Reputation: 9234
Here's 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>
How to set style
attribute programmatically?
Upvotes: 288
Views: 375292
Reputation: 1505
int buttonStyle = R.style.your_button_style;
Button button = new Button(new ContextThemeWrapper(context, buttonStyle), null, buttonStyle);
Only this answer works for me. See https://stackoverflow.com/a/24438579/5093308
Upvotes: 3
Reputation: 1002
best simple solution i found, using alertDialog with a custom layout, is :
val mView = LayoutInflater.from(context).inflate(layoutResId, null)
val dialog = AlertDialog.Builder(context, R.style.CustomAlertDialog)
.setView(mView)
.setCancelable(false)
.create()
where style is
<style name="CustomAlertDialog" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:background">@drawable/bg_dialog_white_rounded</item>
</style>
and bg_dialog_white_rounded.xml is
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="16dp" />
<solid android:color="@Color/white" />
</shape>
layoutResId is a resource id of any layout that has to have the theme set to "@style/CustomAlertDialog", for example:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="@dimen/wdd_margin_medium"
android:theme="@style/CustomAlertDialog"
android:layout_marginEnd="@dimen/wdd_margin_medium">
..... etc...
</androidx.constraintlayout.widget.ConstraintLayout>
Upvotes: 0
Reputation: 445
if inside own custom view : val editText = TextInputEditText(context, attrs, defStyleAttr)
Upvotes: -1
Reputation: 76458
Technically you can apply styles programmatically, with custom views anyway:
private MyRelativeLayout extends RelativeLayout {
public MyRelativeLayout(Context context) {
super(context, null, R.style.LightStyle);
}
}
The one argument constructor is the one used when you instantiate views programmatically.
So chain this constructor to the super that takes a style parameter.
RelativeLayout someLayout = new MyRelativeLayout(new ContextThemeWrapper(this,R.style.RadioButton));
Or as @Dori pointed out simply:
RelativeLayout someLayout = new RelativeLayout(new ContextThemeWrapper(activity,R.style.LightStyle));
Now in Kotlin:
class MyRelativeLayout @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
defStyleAttr: Int = R.style.LightStyle,
) : RelativeLayout(context, attributeSet, defStyleAttr)
or
val rl = RelativeLayout(ContextThemeWrapper(activity, R.style.LightStyle))
Upvotes: 275
Reputation: 11308
Update: At the time of answering this question (mid 2012, API level 14-15), setting the view programmatically was not an option (even though there were some non-trivial workarounds) whereas this has been made possible after the more recent API releases. See @Blundell's answer for details.
OLD Answer:
You cannot set a view's style programmatically yet, but you may find this thread useful.
Upvotes: 93
Reputation: 1881
This is quite old question but solution that worked for me now is to use 4th parameter of constructor defStyleRes
- if available.. on view... to set style
Following works for my purposes (kotlin):
val textView = TextView(context, null, 0, R.style.Headline1)
Upvotes: 17
Reputation: 6373
I don't propose to use ContextThemeWrapper as it do this:
The specified theme will be applied on top of the base context's theme.
What can make unwanted results in your application. Instead I propose new library "paris" for this from engineers at Airbnb:
https://github.com/airbnb/paris
Define and apply styles to Android views programmatically.
But after some time of using it I found out it's actually quite limited and I stopped using it because it does not support a lot of properties i need out off the box, so one have to check out and decide as always.
Upvotes: 3
Reputation: 14908
the simple way is passing through constructor
RadioButton radioButton = new RadioButton(this,null,R.style.radiobutton_material_quiz);
Upvotes: 3
Reputation: 3418
For a new Button/TextView:
Button mMyButton = new Button(new ContextThemeWrapper(this, R.style.button_disabled), null, 0);
For an existing instance:
mMyButton.setTextAppearance(this, R.style.button_enabled);
For Image or layouts:
Image mMyImage = new ImageView(new ContextThemeWrapper(context, R.style.article_image), null, 0);
Upvotes: 24
Reputation: 2425
This is my simple example, the key is the ContextThemeWrapper
wrapper, without it, my style does not work, and using the three parameters constructor of the View.
ContextThemeWrapper themeContext = new ContextThemeWrapper(this, R.style.DefaultLabelStyle);
TextView tv = new TextView(themeContext, null, 0);
tv.setText("blah blah ...");
layout.addView(tv);
Upvotes: 6
Reputation: 711
If you'd like to continue using XML (which the accepted answer doesn't let you do) and set the style after the view has been created you may be able to use the Paris library which supports a subset of all available attributes.
Since you're inflating your view from XML you'd need to specify an id in the layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/my_styleable_relative_layout"
style="@style/LightStyle"
...
Then when you need to change the style programmatically, after the layout has been inflated:
// 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);
For more: the list of supported view types and attributes (includes background, padding, margin, etc. and can easily be extended) and installation instructions with additional documentation.
Disclaimer: I'm the original author of said library.
Upvotes: 12
Reputation: 5506
Non of the provided answers are correct.
You CAN set style programatically.
Short answer is take a look at http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/content/Context.java#435
Long answer. Here's my snippet to set custom defined style programatically to your view:
1) Create a style in your styles.xml file
<style name="MyStyle">
<item name="customTextColor">#39445B</item>
<item name="customDividerColor">#8D5AA8</item>
</style>
Do not forget to define your custom attributes in attrs.xml file
My attrsl.xml file:
<declare-styleable name="CustomWidget">
<attr name="customTextColor" format="color" />
<attr name="customDividerColor" format="color" />
</declare-styleable>
Notice you can use any name for your styleable (my CustomWidget)
Now lets set the style to the widget Programatically Here's My simple widget:
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));
}
}
layout:
<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>
And finally StyleLoader class implementation
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;
}
}
You can find fully working example at https://github.com/Defuera/SetStylableProgramatically
Upvotes: 6
Reputation: 3783
What worked for me:
Button b = new Button(new ContextThemeWrapper(this, R.style.ButtonText), null, 0);
AND
Upvotes: 156
Reputation: 4460
You can apply a style to your activity by doing:
super.setTheme( R.style.MyAppTheme );
or Android default:
super.setTheme( android.R.style.Theme );
in your activity, before setContentView()
.
Upvotes: 6
Reputation: 1
I used views defined in XML in my composite ViewGroup, inflated them added to Viewgroup. This way I cannot dynamically change style but I can make some style customizations. My composite:
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);
}
}
and my view in xml where i can assign styles:
<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"
/>
Upvotes: -1