방법 : 사용자 지정 위젯에 대한 테마 (스타일) 항목 정의


86

응용 프로그램 전체에서 널리 사용하는 컨트롤에 대한 사용자 지정 위젯을 작성했습니다. 위젯 클래스 ImageButton는 몇 가지 간단한 방법으로 파생 되고 확장됩니다. 사용되는 위젯에 적용 할 수있는 스타일을 정의했지만 테마를 통해 설정하는 것을 선호합니다. 에서 R.styleable내가 좋아하는 위젯 스타일 속성 참조 imageButtonStyletextViewStyle. 내가 작성한 사용자 정의 위젯에 대해 이와 같은 것을 만들 수있는 방법이 있습니까?

답변:


209

예, 한 가지 방법이 있습니다.

위젯에 대한 속성 선언이 있다고 가정합니다 ( attrs.xml).

<declare-styleable name="CustomImageButton">
    <attr name="customAttr" format="string"/>
</declare-styleable>

스타일 참조에 사용할 속성을 선언합니다 (에서 attrs.xml).

<declare-styleable name="CustomTheme">
    <attr name="customImageButtonStyle" format="reference"/>
</declare-styleable>

위젯에 대한 기본 속성 값 세트를 선언하십시오 (에서 styles.xml).

<style name="Widget.ImageButton.Custom" parent="android:style/Widget.ImageButton">
    <item name="customAttr">some value</item>
</style>

사용자 정의 테마 선언 ( themes.xml) :

<style name="Theme.Custom" parent="@android:style/Theme">
    <item name="customImageButtonStyle">@style/Widget.ImageButton.Custom</item>
</style>

이 속성을 위젯 생성자 (에서 CustomImageButton.java) 의 세 번째 인수로 사용합니다 .

public class CustomImageButton extends ImageButton {
    private String customAttr;

    public CustomImageButton( Context context ) {
        this( context, null );
    }

    public CustomImageButton( Context context, AttributeSet attrs ) {
        this( context, attrs, R.attr.customImageButtonStyle );
    }

    public CustomImageButton( Context context, AttributeSet attrs,
            int defStyle ) {
        super( context, attrs, defStyle );

        final TypedArray array = context.obtainStyledAttributes( attrs,
            R.styleable.CustomImageButton, defStyle,
            R.style.Widget_ImageButton_Custom ); // see below
        this.customAttr =
            array.getString( R.styleable.CustomImageButton_customAttr, "" );
        array.recycle();
    }
}

이제 다음 Theme.Custom을 사용하는 모든 활동 에 적용 해야합니다 CustomImageButton(AndroidManifest.xml에서).

<activity android:name=".MyActivity" android:theme="@style/Theme.Custom"/>

그게 다야. 이제 현재 테마의 속성 CustomImageButton에서 기본 속성 값을로드하려고합니다 customImageButtonStyle. 테마 또는 속성 값에서 그러한 속성이 발견되지 않으면 @null마지막 인수 obtainStyledAttributes가 사용됩니다. Widget.ImageButton.Custom이 경우.

모든 인스턴스 및 모든 파일 (제외 AndroidManifest.xml)의 이름을 변경할 수 있지만 Android 명명 규칙을 사용하는 것이 좋습니다.


4
테마를 사용하지 않고 똑같은 일을 할 수있는 방법이 있나요? 사용자 정의 위젯이 있지만 사용자가 원하는 테마로 이러한 위젯을 사용할 수 있기를 바랍니다. 게시 한 방식으로 수행하려면 사용자가 내 테마를 사용해야합니다.
theDazzler

3
@theDazzler : 개발자가 사용할 수있는 라이브러리를 의미하는 경우 자체 테마를 만들고 테마의 스타일 속성을 사용하여 위젯의 스타일을 지정할 수 있습니다 ( customImageButtonStyle이 답변에서). 이것이 Android에서 작업 표시 줄을 사용자 지정하는 방법입니다. 그리고 런타임에 테마를 변경하는 것을 의미한다면이 접근 방식으로는 불가능합니다.
Michael

@Michael, 네 개발자가 사용할 수있는 라이브러리를 의미했습니다. 귀하의 의견이 내 문제를 해결했습니다. 감사!
theDazzler

30
이 모든 것의 가장 놀라운 점은 구글의 누군가가 이것이 괜찮다고 생각한다는 것입니다.
Glenn Maynard

1
합니까 name="CustomTheme"에서 declare-styleable어떤 목적에 봉사 래퍼 속성? 그것은 단지 조직을위한 것입니까? 다양한 위젯에 대한 모든 스타일 속성을 하나의 래퍼에 넣을 수 있습니까?
Tenfour04

4

michael의 탁월한 답변 외에도 또 다른 측면은 테마의 사용자 정의 속성을 재정의하는 것입니다. 모두 사용자 정의 속성 "custom_background"를 참조하는 여러 사용자 정의보기가 있다고 가정하십시오.

<declare-styleable name="MyCustomStylables">
    <attr name="custom_background" format="color"/>
</declare-styleable>

테마에서 가치가 무엇인지 정의합니다.

<style name="MyColorfulTheme" parent="AppTheme">
    <item name="custom_background">#ff0000</item>
</style>

또는

<style name="MyBoringTheme" parent="AppTheme">
    <item name="custom_background">#ffffff</item>
</style>

스타일에서 속성을 참조 할 수 있습니다.

<style name="MyDefaultLabelStyle" parent="AppTheme">
    <item name="android:background">?background_label</item>
</style>

에서와 같이 android 속성을 참조하는데도 사용되는 물음표를 확인하십시오.

?android:attr/colorBackground

대부분의 사람들이 알고 있듯이 하드 코딩 된 색상 대신 @color 참조를 사용할 수 있습니다.

그러니 그냥하지 않는 이유

<item name="android:background">@color/my_background_color</item>

테마를 쉽게 전환 할 수있는 반면 런타임에는 "my_background_color"의 정의를 변경할 수 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.