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


86

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

답변:


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.