एंड्रॉइड: दृश्य शैली को प्रोग्रामेटिक रूप से सेट करें


226

यहाँ XML है:

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/LightStyle"
    android:layout_width="fill_parent"
    android:layout_height="55dip"
    android:clickable="true"
    android:orientation="horizontal" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" />

</RelativeLayout>

styleप्रोग्रामेटिकली विशेषता कैसे सेट करें ?


यहाँ देखें ['प्रतिक्रिया'] [१], इसने मेरे लिए काम किया। [1]: stackoverflow.com/a/5488652/2938493
Artificioo

जवाबों:


211

तकनीकी रूप से आप प्रोग्राम को व्यावहारिक रूप से लागू कर सकते हैं, वैसे भी कस्टम दृश्य के साथ:

private MyRelativeLayout extends RelativeLayout {
  public MyRelativeLayout(Context context) {
     super(context, null, R.style.LightStyle);
  }
}

एक तर्क निर्माता वह है जिसका उपयोग आप प्रोग्राम के विचारों को तुरंत करते हैं।

तो इस कंस्ट्रक्टर को उस सुपर को चेन दें जो स्टाइल पैरामीटर लेता है।

RelativeLayout someLayout = new MyRelativeLayout(new ContextThemeWrapper(this,R.style.RadioButton));

या @ डोरी ने बस इशारा किया:

RelativeLayout someLayout = new RelativeLayout(new ContextThemeWrapper(activity,R.style.LightStyle));

34
आप इस प्रोग्राम को बिना किसी विस्तार के कर सकते हैं क्योंकि 3 arg कंस्ट्रक्टर किसी भी तरह से डेवलपर है
Dori

1
@ टर्बो, डॉक्स और एक्लिप्स दोनों आपको बताएंगे कि http://developer.android.com/reference/android/widget/LinearLayout.html#LinearLayout(android.content.Context, android.util.AttributeSet, int):। LinearLayout स्तर 11+ के साथ आवश्यक है।
एक

2
@ डोरी आप किस लिए पास होंगे AttributeSet?
ब्लंडेल

9
यदि यह एक TextView है, तो आपको उन विशेषताओं के लिए सेटटेक्स्टएपैरेंस (R.style.small_text) का उपयोग करने की आवश्यकता है जो पाठ (आकार, रंग, आदि) को प्रभावित करते हैं
Maragues

2
मुझे नहीं पता कि 3-तर्क दृष्टिकोण काम क्यों नहीं करता है। मैंने आवेदन किया Button। @ बैंजामिन पिट्टे दृष्टिकोण ठीक काम करता है।
यंगजै

124

मेरे लिए क्या काम किया:

Button b = new Button(new ContextThemeWrapper(this, R.style.ButtonText), null, 0);
  • एक ContextThemeWrapper का उपयोग करें

तथा

  • 3-तर्क निर्माण निर्माता का उपयोग करें (इसके बिना काम नहीं होगा)

आपकी विधि का उपयोग करना, लेकिन मुझे W / रिसोर्सटाइप मिलता है, बहुत सारे विशेषता संदर्भ, 0x01010034 पर रुके। कोई वर्कअराउंड?
हेलोमीडियािया

मैंने उस मुद्दे को कभी नहीं देखा। यह एक डिवाइस-विशिष्ट समस्या या हाल ही में Android संस्करण से संबंधित कुछ हो सकता है?
बेंजामिन पाइते

11
जरूरी! यह विधि काम करती है, लेकिन हर बच्चे के देखने के लिए स्टाइल सेट कर देगी और यदि ContextThemeWebpper के साथ एक नया लेआउट बना रही है।
aProperFox

क्या आप बेहतर समझा सकते हैं? मेरे साथ सिर्फ एक बटन जोड़कर काम करता है। आप एक लेआउट को देखें?
गिलियन

1
@ गिलियन बिल्कुल, यदि आप एक यौगिक दृश्य पर इसका उपयोग करते हैं जिसमें एक या एक से अधिक बच्चे हैं, तो उन्हें वैसी ही स्टाइल मिलेगी जैसा कि आप के लिए शैली सेट करने वाले मूल दृश्य के रूप में होती है। यह आंतरिक विचारों के भीतर बहुत अधिक पैडिंग या मार्जिन पैदा कर सकता है और यदि आप इसके बारे में नहीं जानते हैं तो आपको पागल बना सकते हैं :)
aProperFox

88

अद्यतन : इस सवाल का जवाब देते समय (मध्य 2012, एपीआई स्तर 14-15), दृश्य को प्रोग्रामेटिक रूप से सेट करना एक विकल्प नहीं था (भले ही कुछ गैर-तुच्छ वर्कअराउंड थे) जबकि अधिक हालिया एपीआई के बाद यह संभव हुआ है विज्ञप्ति। विवरण के लिए @ Blundell का उत्तर देखें।

OLD उत्तर:

आप प्रोग्राम की शैली को अभी तक प्रोग्रामेटिक रूप से सेट नहीं कर सकते , लेकिन आपको यह धागा उपयोगी लग सकता है।


16
सच नहीं। @ Blundell का उत्तर देखें।
अम्बर्टुकी

31
कुछ स्थितियों के लिए (उदाहरण के लिए TextView का उपयोग करके) आप उपयोग कर सकते हैं textView.setTextAppearance(context, R.style.mystyle);। डॉक्टर के अनुसार "पाठ का रंग, आकार, शैली, संकेत रंग निर्धारित करता है, और निर्दिष्ट TextAppearance संसाधन से रंग हाइलाइट करता है।" डेवलपर
.android.com

4
एपीआई> 23; textView.setTextAppearance (R.style.mystyle);
एलिकन आइकॉल

1
मैंने यह उत्तर 4 साल पहले @HaydenKai पर पोस्ट किया था। और तब से एपीआई ने बहुत कुछ बदल दिया है, ताकि प्रोग्राम को व्यावहारिक रूप से लागू किया जा सके।
कोरहान ओज़टर्क

3
@KorhanOzturk ने सहमति व्यक्त की, लेकिन SO पर इस तरह के सवालों के साथ कि गतिविधि फिर से शुरू हो और एक नया उत्तर स्वीकार किया जाए
हेडनकै

16

एक नए बटन / टेक्स्ट दृश्य के लिए:

Button mMyButton = new Button(new ContextThemeWrapper(this, R.style.button_disabled), null, 0);

मौजूदा उदाहरण के लिए:

mMyButton.setTextAppearance(this, R.style.button_enabled);

छवि या लेआउट के लिए:

Image mMyImage = new ImageView(new ContextThemeWrapper(context, R.style.article_image), null, 0);

8

यदि आप XML का उपयोग जारी रखना चाहते हैं (जो स्वीकृत उत्तर आपको ऐसा नहीं करने देता है) और शैली सेट करने के बाद दृश्य बनाया गया है तो आप पेरिस लाइब्रेरी का उपयोग करने में सक्षम हो सकते हैं जो सभी उपलब्ध विशेषताओं के सबसेट का समर्थन करता है।

चूंकि आप XML से अपना विचार फुला रहे हैं, इसलिए आपको लेआउट में एक आईडी निर्दिष्ट करनी होगी:

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/my_styleable_relative_layout"
    style="@style/LightStyle"
    ...

फिर जब लेआउट बदलने के बाद आपको प्रोग्राम को प्रोग्रामेटिक रूप से बदलना होगा, तो:

// Any way to get the view instance will do
RelativeLayout myView = findViewById(R.id.my_styleable_relative_layout);

// This will apply all the supported attribute values of the style
Paris.style(myView).apply(R.style.LightStyle);

अधिक के लिए: समर्थित दृश्य प्रकारों और विशेषताओं की सूची (पृष्ठभूमि, गद्दी, मार्जिन इत्यादि शामिल हैं और इन्हें आसानी से बढ़ाया जा सकता है) और अतिरिक्त निर्देशों के लिए स्थापना निर्देश

अस्वीकरण: मैं उक्त पुस्तकालय का मूल लेखक हूं।


क्या यह 2019 में उपयोग करने के लिए एक अनुशंसित दृष्टिकोण है?
इगोरगानापोलस्की

1
@IgorGanapolsky afaik हाँ! मैं किसी भी बेहतर एक का पता नहीं है।
नेथनेल

इस समाधान को उपलब्ध कराने के लिए @Nathanel को धन्यवाद। इसके अलावा नवीनतम line_height विशेषता के साथ इसे बनाए रखने के लिए। अच्छा काम करते रहें! वास्तव में उपयोगी।
गुइलम रोका

7

आप अपनी गतिविधि पर एक शैली लागू कर सकते हैं:

super.setTheme( R.style.MyAppTheme );

या Android डिफ़ॉल्ट:

super.setTheme( android.R.style.Theme );

अपनी गतिविधि में, पहले setContentView()


4
@ फेमियन क्या आप कृपया FOM को खुद को स्वतंत्र रूप से व्यक्त कर सकते हैं? उसे कोई संपादन नहीं चाहिए!
मिका

6

प्रदान किए गए उत्तरों में से कोई भी सही नहीं है।

आप प्रोग्राम को स्टाइल सेट कर सकते हैं।

संक्षिप्त उत्तर http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/content/Context.java#435 पर एक नज़र डालें

लंबा जवाब। यहाँ मेरे स्निपेट को आपके दृष्टिकोण के अनुसार कस्टम परिभाषित शैली सेट करने के लिए दिया गया है:

1) अपनी style.xml फ़ाइल में एक शैली बनाएँ

 <style name="MyStyle">
    <item name="customTextColor">#39445B</item>
    <item name="customDividerColor">#8D5AA8</item>
</style>

Attrs.xml फ़ाइल में अपनी कस्टम विशेषताओं को परिभाषित करना न भूलें

मेरी attrsl.xml फ़ाइल:

<declare-styleable name="CustomWidget">
    <attr name="customTextColor" format="color" />
    <attr name="customDividerColor" format="color" />
</declare-styleable>

ध्यान दें कि आप अपनी शैली के लिए किसी भी नाम का उपयोग कर सकते हैं (मेरा CustomWidget)

अब शैली को विजेट पर सेट करने देता है

public class StyleableWidget extends LinearLayout {

private final StyleLoader styleLoader = new StyleLoader();

private TextView textView;
private View divider;

public StyleableWidget(Context context) {
    super(context);
    init();
}

private void init() {
    inflate(getContext(), R.layout.widget_styleable, this);
    textView = (TextView) findViewById(R.id.text_view);
    divider = findViewById(R.id.divider);
    setOrientation(VERTICAL);
}

protected void apply(StyleLoader.StyleAttrs styleAttrs) {
    textView.setTextColor(styleAttrs.textColor);
    divider.setBackgroundColor(styleAttrs.dividerColor);
}

public void setStyle(@StyleRes int style) {
    apply(styleLoader.load(getContext(), style));
}
}

लेआउट:

<TextView
    android:id="@+id/text_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="22sp"
    android:layout_gravity="center"
    android:text="@string/styleble_title" />

<View
    android:id="@+id/divider"
    android:layout_width="match_parent"
    android:layout_height="1dp"/>

</merge>

और अंत में स्टाइललॉडर वर्ग कार्यान्वयन

public class StyleLoader {

public StyleLoader() {

}

public static class StyleAttrs {
    public int textColor;
    public int dividerColor;
}

public StyleAttrs load(Context context, @StyleRes int styleResId) {
    final TypedArray styledAttributes = context.obtainStyledAttributes(styleResId, R.styleable.CustomWidget);
    return load(styledAttributes);
}

@NonNull
private StyleAttrs load(TypedArray styledAttributes) {
    StyleAttrs styleAttrs = new StyleAttrs();
    try {
        styleAttrs.textColor = styledAttributes.getColor(R.styleable.CustomWidget_customTextColor, 0);
        styleAttrs.dividerColor = styledAttributes.getColor(R.styleable.CustomWidget_customDividerColor, 0);
    } finally {
        styledAttributes.recycle();
    }
    return styleAttrs;
}
}

आप पूरी तरह से काम करने के उदाहरण https://github.com/Defuera/SetStylableProgramatically पर देख सकते हैं


13
यह सही शैली नहीं है, यह सहेजे गए सेटिंग्स को लागू करने / स्थापित करने के द्वारा सिर्फ एक नकली है (हाँ यह वास्तव में आपकी XML फ़ाइल में सहेजी गई सेटिंग्स का कुछ प्रकार है) आपके दृश्यों पर (यहां आपके पास बस 2 निश्चित दृश्य हैं - और आपको निश्चित रूप से उन्हें जानने की आवश्यकता है पहले से)। सभी जादू applyविधि में है जो कुछ भी दिलचस्प नहीं करता है। शैली का सही अर्थ यह है कि यह भविष्य के सभी गतिशील रूप से जोड़े गए दृश्यों पर स्वचालित रूप से कुछ दृश्य शैली लागू कर रहा है। यहाँ यह कोड निश्चित रूप से ऐसा नहीं कर सकता है और यहाँ कुछ भी गतिशील नहीं है, हमें यह जानने की आवश्यकता है कि क्या दृश्य और कौन से गुण / फ़ील्ड सेट करने हैं।
राजा किंग

1
मुझे यह निर्दिष्ट करने में कोई आपत्ति नहीं है कि शैलियों को लागू करने के लिए क्या विचार हैं, लेकिन इस समाधान में शैली के तत्व हार्ड-कोडित हैं (जैसे टेक्स्टकॉलर और डिवाइडरक्लोर)। यह गतिशील रूप से शैली में परिभाषित सभी तत्वों को नहीं ढूंढेगा और उन्हें दृश्य पर लागू करेगा।
nasch

आपके द्वारा पोस्ट किया गया लिंक नहीं खुलता है। क्या आप पुनः पोस्ट कर सकते हैं?
इगोरगानापोलस्की

4

यह काफी पुराना प्रश्न है, लेकिन समाधान जो मेरे लिए अब काम करता है वह है कंस्ट्रक्टर के चौथे पैरामीटर का उपयोग करना defStyleRes- यदि उपलब्ध हो तो .. देखने के लिए ... स्टाइल सेट करने के लिए

मेरे उद्देश्यों के लिए निम्नलिखित कार्य (कोटलिन):

val textView = TextView(context, null, 0, R.style.Headline1)

3

यह मेरा सरल उदाहरण है, कुंजी ContextThemeWrapperआवरण है, इसके बिना, मेरी शैली काम नहीं करती है, और व्यू के तीन मापदंडों के निर्माण का उपयोग कर रही है।

ContextThemeWrapper themeContext = new ContextThemeWrapper(this, R.style.DefaultLabelStyle);
TextView tv = new TextView(themeContext, null, 0);
tv.setText("blah blah ...");
layout.addView(tv);


1

मैं ContextThemeWrapper का उपयोग करने का प्रस्ताव नहीं करता क्योंकि यह ऐसा करती है:

निर्दिष्ट विषय को आधार संदर्भ के विषय के शीर्ष पर लागू किया जाएगा।

आपके आवेदन में अवांछित परिणाम क्या हो सकते हैं। इसके बजाय मैं Airbnb में इंजीनियरों से इसके लिए नई लाइब्रेरी "पेरिस" प्रस्तावित करता हूं:

https://github.com/airbnb/paris

प्रोग्राम को एंड्रॉइड दृश्यों में शैलियों को परिभाषित और लागू करें।

लेकिन इसका उपयोग करने के कुछ समय बाद मुझे पता चला कि यह वास्तव में काफी सीमित है और मैंने इसका उपयोग करना बंद कर दिया है क्योंकि यह बहुत सारी संपत्तियों का समर्थन नहीं करता है जिनकी मुझे बॉक्स से आवश्यकता होती है, इसलिए किसी को हमेशा की तरह जांच करनी होगी और निर्णय लेना होगा।


अपने डाउनवोट मित्र को समझाएं ... मैं एक दिन और आधा हार गया क्योंकि मैंने ContextThemeWrapper का उपयोग किया है, और यह मेरे संदर्भ विषय सफेद पृष्ठभूमि पर लागू होता है, फिर अचानक Google सामग्री लाइब्रेरी से चिप विजेट क्रैश हो रहा था, अनुमान
लगाएं

क्या पेरिस लाइब्रेरी कॉनटेक्स्टटेमवेयर का उपयोग नहीं करती है?
इगोरगानापोलस्की

@IgorGanapolsky यह नहीं करता है। यह एक्सएमएल शैली को पढ़ता है और इसे व्यू पर संबंधित विधि कॉल में परिवर्तित करता है।
नेथनेल

यह वास्तव में काफी सीमित है मैंने इसका उपयोग करना बंद कर दिया है क्योंकि यह बहुत सारे गुणों का समर्थन नहीं करता है जो मुझे चाहिए ...
रेनेटिक

-1

मैंने अपने समग्र ViewGroup में XML में परिभाषित विचारों का उपयोग किया, उन्हें Viewgroup में जोड़ा गया। इस तरह मैं गतिशील रूप से शैली नहीं बदल सकता लेकिन मैं कुछ शैली अनुकूलन बना सकता हूं। मेरा समग्र:

public class CalendarView extends LinearLayout {

private GridView mCalendarGrid;
private LinearLayout mActiveCalendars;

private CalendarAdapter calendarAdapter;

public CalendarView(Context context) {
    super(context);

}

public CalendarView(Context context, AttributeSet attrs) {
    super(context, attrs);

}

@Override
protected void onFinishInflate() {
    super.onFinishInflate();
    init();
}

private void init() {
    mCalendarGrid = (GridView) findViewById(R.id.calendarContents);
    mCalendarGrid.setNumColumns(CalendarAdapter.NUM_COLS);

    calendarAdapter = new CalendarAdapter(getContext());
    mCalendarGrid.setAdapter(calendarAdapter);
    mActiveCalendars = (LinearLayout) findViewById(R.id.calendarFooter);
}

}

और xml में मेरा विचार जहां मैं शैलियों को असाइन कर सकता हूं:

<com.mfitbs.android.calendar.CalendarView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/calendar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical"
>

<GridView
    android:id="@+id/calendarContents"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<LinearLayout
    android:id="@+id/calendarFooter"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    />


1
आप शैली को गतिशील रूप से कहाँ स्थापित कर रहे हैं?
इगोरगानापोलस्की

-3

आप वांछित शैली के साथ लेआउट युक्त xml बना सकते हैं और फिर इस तरह अपने दृश्य की पृष्ठभूमि संसाधन बदल सकते हैं ।


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