Applying style dynamically to views in Java code

I have a custom button view.

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); } } } 

and I have the following style defined in my .xml style

  <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> 

The extended button does not receive this style. Can someone point out what I'm doing wrong? I was looking for a solution and found this one . Can anyone suggest something?

Note. I cannot use XML to apply styles. He must be a constructor.

Edit:

The following is the class in which this custom button is created and used. I removed many irrelevant lines of code

 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); } } 
+6
source share
5 answers

This is the old answer: I got -1 a couple of minutes ago, and here

NEW SOLUTION :

The main idea is to pass the attribute to the constructor. Check out this link for a complete solution: Applying style to views dynamically in Java code

OLD SOLUTION (DOES NOT WORK) :

Add these constructors to your class:

 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 } 
+3
source

Why not use setTextAppearance(Context context, int resid); . It allows you to set the text color, size, style, tooltip color and highlight color.

In the PrayerTimeLabel class,

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

See this post for more details: setTextAppearance via code referencing a user attribute

+3
source

Here is the old answer (and simpler) for this topic: fooobar.com/questions/21165 / ...

In summary:

ContextThemeWrapper newContext = new ContextThemeWrapper (baseContext, R.style.MyStyle); button = new button (newContext);

+1
source

You must make a constructor call to the super(context,attrs,defStyle) constructor super(context,attrs,defStyle) , which will apply defStyle to your View .

However, you cannot change the dynamic style .

0
source

The error message you are referring to is:

In addition, when dynamically creating elements at run time, this means that you cannot just apply style in your code. You need to create a separate XML layout for the view you are creating and inflate it [...]

With this in mind, the solution might look like this:

Create an xml layout for your button - call: prayertimebutton.xml:

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

Then, in the initializePrayerTimeButton method in your PrayerControl class PrayerControl inflate and add the PrayerTimeLabel button to the PrayerTimeLabel layout:

 //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); 

Note that the second parameter, LayoutInflater.inflate() is a reference to the parent view (group).

Below is an answer from adamp, an Android infrastructure developer at Google, discussing this approach in more detail.

Why is it so difficult to set style from code in Android

0
source

Source: https://habr.com/ru/post/918738/


All Articles