Program Tip

Android에서 스타일 가능 속성 선언

programtip 2020. 10. 14. 20:53
반응형

Android에서 스타일 가능 속성 선언


declare-styleable컴포넌트에 대한 사용자 정의 스타일을 선언 할 수 있는 태그에 대한 귀중한 문서가 거의 없습니다 . 태그 속성에 대해 유효한 값 목록찾았습니다 . 그것이 진행되는 한 좋지만 이러한 값 중 일부를 사용하는 방법을 설명하지 않습니다. attr.xml (표준 속성에 대한 Android 소스)을 찾아 보면서 다음과 같은 작업을 수행 할 수 있음을 발견했습니다.formatattr

<!-- The most prominent text color.  -->
<attr name="textColorPrimary" format="reference|color" />

format속성 분명히 값의 조합으로 설정할 수있다. 아마도 format속성은 파서가 실제 스타일 값을 해석하는 데 도움이 될 것입니다. 그런 다음 attr.xml에서 이것을 발견했습니다.

<!-- Default text typeface. -->
<attr name="typeface">
    <enum name="normal" value="0" />
    <enum name="sans" value="1" />
    <enum name="serif" value="2" />
    <enum name="monospace" value="3" />
</attr>

<!-- Default text typeface style. -->
<attr name="textStyle">
    <flag name="normal" value="0" />
    <flag name="bold" value="1" />
    <flag name="italic" value="2" />
</attr>

이 두 가지 모두 표시된 스타일에 대해 허용되는 값 집합을 선언하는 것 같습니다.

그래서 두 가지 질문이 있습니다.

  1. enum세트 중 하나를 취할 수있는 스타일 속성과 세트를 취할 수있는 스타일 속성의 차이점은 무엇입니까 flag?
  2. 누구든지 declare-styleable작동 방식 에 대한 더 나은 문서를 알고 있습니까 (Android 소스 코드를 리버스 엔지니어링하는 것 제외)?

여기에이 질문이 있습니다. 약간의 정보로 사용자 지정 속성정의 하지만 많지는 않습니다.

그리고이 포스트 . 플래그 및 열거 형에 대한 좋은 정보가 있습니다.

사용자 지정 XML 속성 플래그

플래그는 속성 태그 아래에 정의 된 값의 아주 작은 하위 집합 만 허용된다는 점에서 특수 속성 유형입니다. 플래그는 "이름"속성과 "값"속성으로 지정됩니다. 이름은 해당 속성 유형 내에서 고유해야하지만 값은 그럴 필요가 없습니다. 이것이 Android 플랫폼이 진화하는 동안 "fill_parent"와 "match_parent"가 모두 동일한 동작에 매핑되는 이유입니다. 그들의 가치는 동일했습니다.

name 속성은 레이아웃 XML 내의 값 위치에 사용 된 이름에 매핑되며 네임 스페이스 접두사가 필요하지 않습니다. 따라서 위의 "tilingMode"에 대해 속성 값으로 "center"를 선택했습니다. 나는 "늘어난"또는 "반복"을 쉽게 선택할 수 있지만 다른 것은 없습니다. 실제 값으로 대체하는 것도 허용되지 않았습니다.

값 속성은 정수 여야합니다. 16 진수 또는 표준 숫자 표현의 선택은 귀하에게 달려 있습니다. 둘 다 사용되는 Android 코드 내에 몇 군데가 있으며 Android 컴파일러는 둘 중 하나를 기꺼이 받아들입니다.

사용자 지정 XML 속성 열거 형

열거 형은 하나의 프로 비전이있는 플래그와 거의 동일한 방식으로 사용되며 정수와 상호 교환하여 사용할 수 있습니다. 내부적으로 Enum과 Integer는 동일한 데이터 유형, 즉 Integer에 매핑됩니다. Integers와 함께 속성 정의에 나타날 때 Enum은 항상 나쁜 "매직 넘버"를 방지하는 역할을합니다. 이것이 차원, 정수 또는 명명 된 문자열 'fill_parent'가있는 'android : layout_width'를 가질 수있는 이유입니다.

이를 컨텍스트에 적용하기 위해 정수 또는 "scroll_to_top"문자열을 허용하는 "layout_scroll_height"라는 사용자 지정 속성을 생성한다고 가정 해 보겠습니다. 이렇게하려면 "integer"형식 속성을 추가하고 enum을 따릅니다.

<attr name="layout_scroll_height" format="integer">  
    <enum name="scroll_to_top" value="-1"/> 
</attr>

이러한 방식으로 Enum을 사용할 때 한 가지 규정은 사용자 정의보기를 사용하는 개발자가 의도적으로 "-1"값을 레이아웃 매개 변수에 배치 할 수 있다는 것입니다. 이렇게하면 "scroll_to_top"이라는 특수한 경우 논리가 트리거됩니다. 이러한 예상치 못한 (또는 예상되는) 동작은 Enum 값을 잘못 선택하면 라이브러리를 "레거시 코드"더미로 빠르게 이동할 수 있습니다.


내가보기에 속성에 실제로 추가 할 수있는 실제 값은 속성에서 얻을 수있는 것에 의해 제한됩니다. 자세한 힌트는 여기 에서 AttributeSet클래스 참조를 확인하십시오 .

다음을 얻을 수 있습니다.

  • 부울 ( getAttributeBooleanValue),
  • 수레 ( getAttributeFloatValue),
  • 정수 ( getAttributeIntValue),
  • int ( getAttributeUnsignedIntValue),
  • 및 문자열 ( getAttributeValue)

@Aleadam의 대답은 매우 도움이되지만 imho는 enum사이의 주요 차이점을 생략 flag합니다. 전자는 하나를 선택하도록 의도되었으며 일부 뷰에 해당 속성을 할당 할 때 하나의 값만 선택합니다. 그러나 후자의 값은 비트 OR 연산자를 사용하여 결합 할 수 있습니다.

예, res/values/attr.xml

<!-- declare myenum attribute -->
<attr name="myenum">
    <enum name="zero" value="0" />
    <enum name="one" value="1" />
    <enum name="two" value="2" />
    <enum name="three" value="3" />
</attr>

<!-- declare myflags attribute -->
<attr name="myflags">
    <flag name="one" value="1" />
    <flag name="two" value="2" />
    <flag name="four" value="4" />
    <flag name="eight" value="8" />
</attr>

<!-- declare our custom widget to be styleable by these attributes -->
<declare-styleable name="com.example.MyWidget">
    <attr name="myenum" />
    <attr name="myflags" />
</declare-styleable>

에서에게 res/layout/mylayout.xml우리가 지금 할 수있는

<com.example.MyWidget
    myenum="two"
    myflags="one|two"
    ... />

So an enum selects one of its possible values, while flags can be combined. The numerical values should reflect this difference, typically you'll want the sequence to go 0,1,2,3,... for enums (to be used as array indices, say) and flags to go 1,2,4,8,... so they can be independently added or removed, using bitwise OR | to combine flags.

We could explicitly define "meta flags" with values that are not a power of 2, and thus introduce a kind of shorthand for common combinations. For instance, if we had included this in our myflags declaration

<flag name="three" value="3" />

then we could have written myflags="three" in stead of myflags="one|two", for completely identical results as 3 == 1|2.

Personally, I like to always include

<flag name="none" value="0" /> <!-- or "normal, "regular", and so on -->
<flag name="all" value="15" /> <!-- 15 == 1|2|4|8 -->

which will allow me to unset or set all flags at once.

More subtly, it might be the case that one flag is implied by another. So, in our example, suppose that the eight flag being set should force the four flag to be set (if it wasn't already). We could then re-define eight to pre-include, as it were, the four flag,

<flag name="eight" value="12" /> <!-- 12 == 8|4 -->

Finally, if you are declaring the attributes in a library project but want to apply them in layouts of another project (dependent on the lib), you'll need to use a namespace prefix which you must bind in the XML root element. E.g.,

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:auto="http://schemas.android.com/apk/res-auto"
    ... >

    <com.example.MyWidget
        auto:myenum="two"
        auto:myflags="one|two"
        ... />

</RelativeLayout>

참고URL : https://stackoverflow.com/questions/6020379/declaring-styleable-attributes-in-android

반응형