कैसे करें: कस्टम विजेट के लिए विषय (शैली) को परिभाषित करें


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इस उत्तर में)। इस तरह से ऐक्शन बार को एंड्रॉइड पर कस्टमाइज़ किया जाता है। और अगर आपका मतलब रनटाइम में किसी थीम को बदलना है, तो यह इस दृष्टिकोण के साथ संभव नहीं है।
माइकल

@ मिसेल, हां मेरा मतलब एक ऐसी लाइब्रेरी है जिसे डेवलपर्स इस्तेमाल कर सकते हैं। आपकी टिप्पणी से मेरी समस्या हल हो गई। धन्यवाद!
द डजलर

30
इस सब के बारे में सबसे आश्चर्यजनक बात यह है कि Google में किसी को लगता है कि यह ठीक है।
ग्लेन मेनार्ड

1
क्या विशेषता आवरण किसी उद्देश्य को पूरा करता name="CustomTheme"है declare-styleable? क्या यह सिर्फ संगठन के लिए है, क्योंकि मैं इसे कहीं भी इस्तेमाल नहीं करता। क्या मैं अपनी सभी शैली विशेषताओं को एक आवरण में विभिन्न विगेट्स के लिए रख सकता हूं?
तेनफौर ०४

4

माइकल के उत्कृष्ट जवाब के अलावा एक और पहलू विषयों में कस्टम विशेषताओं को पछाड़ रहा है। मान लें कि आपके पास कई कस्टम विचार हैं जो सभी कस्टम विशेषता "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

जैसा कि आप में से अधिकांश ने देखा है, आप शायद-और हार्ड कोडित रंगों के बजाय @ रंग संदर्भ का उपयोग करना चाहिए।

तो सिर्फ क्यों नहीं

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

आप "my_background_color" की परिभाषा को रनटाइम पर नहीं बदल सकते, जबकि आप आसानी से थीम बदल सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.