Android에서 스타일 가능 속성 선언
declare-styleable
컴포넌트에 대한 사용자 정의 스타일을 선언 할 수 있는 태그에 대한 귀중한 문서가 거의 없습니다 . 태그 의 속성에 대해 유효한 값 목록 을 찾았습니다 . 그것이 진행되는 한 좋지만 이러한 값 중 일부를 사용하는 방법을 설명하지 않습니다. attr.xml (표준 속성에 대한 Android 소스)을 찾아 보면서 다음과 같은 작업을 수행 할 수 있음을 발견했습니다.format
attr
<!-- 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>
이 두 가지 모두 표시된 스타일에 대해 허용되는 값 집합을 선언하는 것 같습니다.
그래서 두 가지 질문이 있습니다.
enum
값 세트 중 하나를 취할 수있는 스타일 속성과 값 세트를 취할 수있는 스타일 속성의 차이점은 무엇입니까flag
?- 누구든지
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
'Program Tip' 카테고리의 다른 글
다른 함수 안에 함수를 정의 할 수없는 이유는 무엇입니까? (0) | 2020.10.14 |
---|---|
C enum의 값 대신 텍스트 인쇄 (0) | 2020.10.14 |
iOS 시뮬레이터에서 App Store에 액세스 할 수 있습니까? (0) | 2020.10.14 |
NServiceBus 대 MassTransit (0) | 2020.10.14 |
bash의 함수 내에서 전역 변수를 수정하는 방법은 무엇입니까? (0) | 2020.10.14 |