Динамическое применение стиля к представлениям в Java-коде

У меня есть пользовательский вид кнопки.

public class PrayerTimeLabel extends Button { int hours; int minutes; String dayHalf; //am or pm Context parentActivity; PrayerControl parentControl; public PrayerTimeLabel(Context context,PrayerControl parent) { super(context); init(context,parent,0); } public PrayerTimeLabel(Context context, int defStyle, PrayerControl parent) { //super(context, null, R.style.Button_PrayerTimeButton); super(context, null, defStyle); init(context,parent,defStyle); } private void init(final Context context, PrayerControl parent, int defStyle) { parentActivity = context; parentControl = parent; Typeface tf = Typeface.createFromAsset(context.getAssets(),"fonts/digital.ttf"); this.setTypeface(tf); this.setText(false); this.setOnClickListener(new OnClickListener() { public void onClick(View v) { TimeDialog dialogBox = parentControl.getDialogBox(); dialogBox.setTime(hours, minutes, dayHalf); dialogBox.show(); } }); } public void setTime(int hrs, int min, String half,boolean signalParent) { hours = hrs; minutes = min; dayHalf = half; this.setText(signalParent); } public void setText(boolean signalParent) { super.setText(String.format("%02d", hours)+":"+String.format("%02d", minutes)+" "+dayHalf); if(signalParent){ parentControl.setPrayerTime(hours, minutes, dayHalf); } } } 

И у меня есть следующий стиль, определенный в моем стиле.xml

  <style name="Button.PrayerTimeButton" parent="@android:style/TextAppearance.Widget.Button"> <item name="android:background">#000</item> <item name="android:textSize">18dp</item> <item name="android:textColor">#FFFF00</item> </style> 

Расширенная кнопка не получает этот стиль. Может ли кто-нибудь указать, что я делаю неправильно? Я искал решение и нашел это . Может кто-нибудь предложить что-то

Примечание. Я не могу использовать XML для применения стилей. Он должен быть конструктором.

Редактировать:

Ниже приведен класс, в котором эта пользовательская кнопка создана и используется. Я удалил многие нерелевантные строки кода

 public class PrayerControl extends LinearLayout { protected PrayerTimeLabel prayerTimeButton; protected String prayerName; protected static int counter=0; public PrayerControl(Context context) { super(context); init(context); } public PrayerControl(Context context, AttributeSet attrs) { super(context, attrs); getXMLAttributes(context, attrs); init(context); } protected void getXMLAttributes(Context context, AttributeSet attrs) { TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.PrayerControl); prayerName = a.getString(R.styleable.PrayerControl_name); dayHalf = a.getString(R.styleable.PrayerControl_dayHalf); hours = a.getInteger(R.styleable.PrayerControl_hours, 4); minutes = a.getInteger(R.styleable.PrayerControl_minutes, 30); ltrProgress = a.getInteger(R.styleable.PrayerControl_postNamazInterval, 0); rtlProgress = a.getInteger(R.styleable.PrayerControl_preNamazInterval, 0); intervalMax = a.getInteger(R.styleable.PrayerControl_intervalMax, 30); a.recycle(); } protected void init(Context context) { counter++; parentActivity = context; this.setOrientation(LinearLayout.HORIZONTAL); this.setId(counter); prayerTimeButtonStyle = R.style.Button_PrayerTimeButton; initializePrayerTimeButton(); } protected void initializePrayerTimeButton() { LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, 40); params.gravity = Gravity.CENTER; //params.weight = 1.0f; prayerTimeButton = new PrayerTimeLabel(parentActivity,prayerTimeButtonStyle,this); prayerTimeButton.setTime(hours, minutes, dayHalf,false); prayerTimeButton.setLayoutParams(params); this.addView(prayerTimeButton); } } 

    Почему бы не использовать setTextAppearance(Context context, int resid); , Он позволяет вам установить цвет текста, размер, стиль, цвет подсказки и выделить цвет.

    В классе PrayerTimeLabel ,

     private void init(final Context context, PrayerControl parent, int defStyle) { setTextAppearance(context, R.style.Button_PrayerTimeButton); ... } 

    Для получения дополнительной информации см. Этот пост: setTextAppearance через код, ссылающийся на пользовательский атрибут

    Это старый ответ: я получил пару минут назад, и вот

    НОВОЕ РЕШЕНИЕ :

    Основная идея – передать атрибут конструктору. Проверьте эту ссылку для полного решения: применение стиля к представлениям динамически в Java-коде

    СТАРЫЙ РЕШЕНИЕ (НЕ РАБОТАЕТ) :

    Добавьте эти конструкторы в свой класс:

     public StyledButton(Context context) { super(context, null, R.style.Button_PrayerTimeButton); //... whatever } public StyledButton(Context context, AttributeSet attrs) { super(context, attrs, R.style.Button_PrayerTimeButton); //... whatever } public StyledButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, R.style.Button_PrayerTimeButton); //... whatever } 

    Вот старый ответ (и более простой) для этой темы: https://stackoverflow.com/a/21455192/4360308

    Подводя итог:

    ContextThemeWrapper newContext = new ContextThemeWrapper (baseContext, R.style.MyStyle); Button = новая кнопка (newContext);

    Вы должны сделать в своем конструкторе вызов конструктора super(context,attrs,defStyle) , который применит defStyle к вашему View .

    Однако вы не можете изменить style динамически.

    В сообщении об ошибке вы указываете:

    Кроме того, при динамическом создании элементов во время выполнения это означает, что вы не можете просто применять стиль в коде. Вам нужно создать отдельный XML-макет для создаваемого вами вида и раздуть его […]

    Имея это в виду, решение может выглядеть так:

    Создайте xml-макет для вашей кнопки – назовем его молитвой. Bmt:

     <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FFFF00" //...etc /> 

    Затем в методе initializePrayerTimeButton в вашем классе PrayerControl и добавьте кнопку PrayerControl макет PrayerControl :

     //Retrieve a LayoutInflater instance that is hooked up to the current context LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); //The LayoutInflater instantiates the layout file into a PrayerTimeLabel object PrayerTimeLabel button = (PrayerTimeLabel)inflater.inflate(R.layout.prayertimebutton, this, false); //add the PrayerTimeLabel to the PrayerControl this.addView(button); 

    Обратите внимание, что второй параметр LayoutInflater.inflate() является ссылкой на родительский вид (группа).

    Ниже представлен ответ adamp, разработчик инфраструктуры Android в Google, более подробно обсуждает этот подход.

    Почему так сложно установить стиль из кода в Android?