This question already has answers here:
Set style for TextView programmatically
(13 answers)
Closed 3 years ago.
Here is my style:
<style name="buttonQuestionStyle" parent="#style/Widget.AppCompat.Button.Colored">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#color/white</item>
<item name="android:textSize">16sp</item>
<item name="android:padding">25dp</item>
<item name="android:layout_margin">10dp</item>
<item name="android:background">#color/questionButton</item>
</style>
And here my code:
Button btn = new Button(getActivity());
btn.setText(ojb.getText());
if (Build.VERSION.SDK_INT < 23) {
btn.setTextAppearance(getActivity(), R.style.buttonQuestionStyle);
} else {
btn.setTextAppearance(R.style.buttonQuestionStyle);
}
In the app:
Programmatically button appears like this:
And via layout it worked. Appears like this:
Here is my code in the XML Layout:
<Button
android:text="Question"
style="#style/buttonQuestionStyle" />
So... I dont know why it happens, and how fix it.
You can pass a ContextThemeWrapper in constructor for button and use 3 arguments constructor for Button(context, attributeset, defStyle).
ContextThemeWrapper wrapper = new ContextThemeWrapper(this,R.style.buttonQuestionStyle);
Button btn = new Button(wrapper, null, 0); // note this constructor
btn.setText("some text");
Some info around why you cannot set button's style programmatically, as per the JavaDoc of method setTextAppearance
Sets the text appearance from the specified style resource.
<p>
Use a framework-defined {#code TextAppearance} style like
{#link android.R.style#TextAppearance_Material_Body1 #android:style/TextAppearance.Material.Body1}
or see {#link android.R.styleable#TextAppearance TextAppearance} for the
set of attributes that can be used in a custom style.
#param resId the resource identifier of the style to apply
#attr ref android.R.styleable#TextView_textAppearance
So it deals with only text appearance not other style elements.
Still if you want to apply some style at runtime programmatically you need to
make each and every change separately for example to set background you need to call setBackground and similarly for other cases.
or
Inflate that view programmatically using that particular theme.
Related
I am pro grammatically creating buttons and specifying the height and width of each prior to adding it to a Grid View:
Button discountButton = new Button(this, null, 0, R.style.discount_select_button);
discountButton.setText("blah");
discountButton.setWidth(300);
discountButton.setHeight(300);
discountsGrid.addView(discountButton);
The button utilises this style, all items defined within the style get applied except for "layout_margin", why could this be?
<style name="discount_select_button" parent="#android:style/Widget.Button">
<item name="android:layout_margin">10dp</item>
<item name="android:textAlignment">center</item>
<item name="android:textColor">#color/white_light_background_focusable_color</item>
<item name="android:background">#drawable/discount_selection_button_shape</item>
<item name="android:gravity">fill_horizontal</item>
<item name="android:autoSizeMinTextSize">1sp</item>
<item name="android:autoSizeMaxTextSize">25sp</item>
<item name="android:autoSizeTextType">uniform</item>
<item name="android:autoSizeStepGranularity">1sp</item>
</style>
When I apply all the above properties programmatically, all applies successfully but not when defined within a style.
The minimum API level I am targeting is 26
Attributes beginning with layout_ are not actually part of the view, they are part of that view's LayoutParams object, and they define the behavior of the parent.
If you use that style definition directly in XML, the margins will work, but from Java they will not.
You can create a ViewGroup.MarginLayoutParams object and set the params.topMargin field to get your desired result.
I am looking to create a custom ViewGroup to be used in a library; which contains a few ImageButton objects. I would like to be able to apply a style each ImageButton; but I cannot figure out how to apply a style programmatically other than by applying a attribute resource to the defStyleAttr parameter; like so:
mImageButton = new ImageButton(
getContext(), // context
null, // attrs
R.attr.customImageButtonStyle); // defStyleAttr
The issue with this is that the only way to change the style of each ImageButton would be by applying a style to this attribute in a parent theme. But I would like to be able to set a default style, without having to manually set this attribute for each project that uses this library.
There is a parameter that does exactly what I am looking for; defStyleRes, which can be used like so:
mImageButton = new ImageButton(
getContext(), // context
null, // attrs
R.attr.customImageButtonStyle, // defStyleAttr
R.style.customImageButtonStyle); // defStyleRes
This parameter is only available at API Level 21 and above, but my projects target API Level 16 and above. So how can I set the defStyleRes, or apply a default style, without access to this parameter?
I applied my style using a ContextThemeWrapper, as suggested by #EugenPechanec, which seems to work well, but each ImageButton now has the default ImageButton background, even though my style applies <item name="android:background">#null</item>.
Here is the style I am using:
<style name="Widget.Custom.Icon" parent="android:Widget">
<item name="android:background">#null</item>
<item name="android:minWidth">56dp</item>
<item name="android:minHeight">48dp</item>
<item name="android:tint">#color/selector_light</item>
</style>
And this is how I am applying it:
ContextThemeWrapper wrapper = new ContextThemeWrapper(getContext(), R.style.Widget_Custom_Icon);
mImageButton = new AppCompatImageButton(wrapper);
On the left is what I am getting, and on the right is what I would like it to look like:
defStyleAttr is for resolving default widget style from theme attribute.
Example: AppCompatCheckBox asks for R.attr.checkBoxStyle. Your theme defines <item name="checkBoxStyle">#style/Widget.AppCompat.CheckBox</item>.
If that attribute is not defined in your theme the widget would pickup its defStyleRes e.g. R.style.Widget_AppCompat_CheckBox.
Note that these are not actual values used by the widget.
I have not seen defStyleRes constructor parameter used outside of the framework. All of these parameters (plus defaults) are however used when asking TypedArray for resources.
How to actually solve your problem
So the four parameter constructor is not available on all platforms. You need to find a way to feed in your default style. Consider a style you'd like to apply:
<style name="MyImageButtonStyle" parent=""> ... </style>
You need a way to convert it to a defStyleAttr parameter. Define the default style on a theme overlay:
<style name="MyImageButtonThemeOverlay" parent="">
<!-- AppCompat widgets don't use the android: prefix. -->
<item name="imageButtonStyle">#style/MyImageButtonStyle</item>
</style>
Now you can create your ImageButton using this theme overlay:
// When creating manually you have to include the AppCompat prefix.
mImageButton = new AppCompatImageButton(
new ContextThemeWrapper(getContext(), R.style.MyImageButtonThemeOverlay)
);
You don't need to specify any other parameters as AppCompatImageButton will pickup R.attr.imageButtonStyle by default.
If that looks hacky you can always inflate your custom view hierarchy or individual widgets from XML where you specified the style="#style/MyImageButtonStyle" attribute.
I need to run a custom dialog layout using only theme/style options. Running custom Dialog layout by code is not an option for me. I think this should be possible by mean of attributes "android:layout", "android:dialogLayout", "*android:dialogCustomTitleDecorLayout", "*android:dialogTitleIconsDecorLayout", "*android:dialogTitleDecorLayout".<br/><br/>
My Activity onCreate load layout in a Dialog Style:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.MyDialog);
setContentView(R.layout.mydialog);
this.setTitle("A title");
}
style xml:
<style name="MyDialog" parent="android:Theme.Holo.Light.Dialog">
<item name="android:windowTitleStyle">#style/MyDialog.WindowTitle</item>
<item name="android:layout">#layout/dialog_title</item>
<item name="android:dialogLayout">#layout/dialog_title</item>
<item name="*android:dialogCustomTitleDecorLayout">#layout/dialog_title</item>
<item name="*android:dialogTitleIconsDecorLayout">#layout/dialog_title</item>
<item name="*android:dialogTitleDecorLayout">#layout/dialog_title</item>
</style>
<style name="MyDialog.WindowTitle">
<item name="android:maxLines">1</item>
<item name="android:scrollHorizontally">true</item>
<item name="android:textAppearance">#style/TextAppearance_WindowTitle</item>
</style>
<style name="TextAppearance_WindowTitle">
<item name="android:textSize">32sp</item>
<item name="android:textColor">#+color/verdeTI</item>
</style>
Please, note that Text colour of the title is correctly applied (#+color/verdeTI) so I am confident the cascading styling is right but it seems none of the layout options work at all because I continue to see the standard Dialog Layout. My "dialog_title" use a completely different ImageView for divider so I can be sure when it is loaded.
The custom divider is just the main reason because I need a different layout.
Update 15/4/2014
Android theme Guide stats:
Some style properties, however, are not supported by any View element and can only be applied as a theme. These style properties apply to the entire window and not to any type of View. For example, style properties for a theme can hide the application title, hide the status bar, or change the window's background. These kind of style properties do not belong to any View object. To discover these theme-only style properties, look at the R.attr reference for attributes that begin with window. For instance, windowNoTitle and windowBackground are style properties that are effective only when the style is applied as a theme to an Activity or application. See the next section for information about applying a style as a theme.
OK attributes starting with "window" are applied only in Themes not in Styles. What's about *Layout attributes ? When they are applied ?
You can try by passing ThemeName as argument of constructor like this way.
public class TestDialog extends Dialog{
public TestDialog(Context context) {
super(context, R.style.YourTheme);
// TODO Auto-generated constructor stub
}
}
Add window feature if you require.
Make object of this class in any Activity so you can use Dialog property.
:-
More info https://stackoverflow.com/a/18224754/942224
i was using this way. so it may be help you.
You can try by creating your required layout file and opening it with an activity class just in the manifest add this code to your activity
android:theme="#android:style/Theme. Dialog"
But you will be getting title bar in your dialog with this which is your label name for your activity. To remove it add this code before setContentView
requestWindowFeature(Window. FEATURE_NO_TITLE);
I have a problem figuring out how to do this:
I am currently coding an app that comes with different themes (User can select the complete appereance of the app out of a list of different styles).
Then the list item is selected I want to call setTheme(R.style.Own_App_Style0); to change the complete appearance.
The problem is best explained by an example:
Lets say we have 2 TextView.
Theme1
1. TextView: TextColor should be green and TextSize 15sp.
2. TextView: TextColor should be red and TextSize 10sp.
Theme2
1. TextView: TextColor should be blue and TextSize 10sp.
2. TextView: TextColor should be yellow and TextSize 10sp.
Of course I know that by setting <item name="textViewStyle">#android:style/Widget.TextView</item> I can change the default appearance of TextViews.
But how can it be done to have lets say two (ore more) different types of TextView with different applied styles (and by xml)?
Found a solution (basically in this answer setTextAppearance through code referencing custom attribute). In case anyone else has this problem I shortly explain:
Declare in style.xml a attribute and in the actual style definition asign a value (reference) to this attribute:
<declare-styleable name="CustomTextView">
<attr name="mainTextView" format="reference"/>
</declare-styleable>
<style name="appstyle0" parent="android:style/Theme.Holo.Light">
<item name="#attr/mainTextView">#style/CustomTextViewAppearance1</item>
<item name="android:textViewStyle">#style/CustomTextViewAppearance2</item>
</style>
<style name="appstyle1" parent="android:style/Theme.Holo.Light">
<item name="#attr/mainTextView">#style/CustomTextViewAppearance2</item>
<item name="android:textViewStyle">#style/CustomTextViewAppearance1</item>
</style>
<style name="CustomTextViewAppearance1">
<item name="android:textSize">10dip</item>
</style>
<style name="CustomTextViewAppearance2">
<item name="android:textSize">30dip</item>
</style>
Now in the layout all textViews are like CustomTextViewAppearance2 (because this is set as standard in this style. And the textViews that should use the other style write into the definition:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="blablabla"
style="?mainButtonTextView"/>
When you now call .setTheme (after restart the activity) the appearance of the textviews switch. Like this method you can define as many different types of View styles and switch between them only by calling .setTheme.
Unfortunately, styles are static once they are defined. To have an entire cascade of styles modified programmatically, you would have to change the definition of the style itself. Instead, all you can do is change the style that is assigned to a TextView (or whatever style-able object), as outlined in the question I linked to in my comment above.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
android : set textView style at runtime
i just wanna know how i can implement style in runtime i saw some posts here but i couldnt find anything properly
i create a new Textview , like this
TextView title = TextView(this, null, R.style.TitleSep);
this its my style xml.
<style name="TitleSep">
<item name="android:layout_height">fill_parent</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:lineSpacingMultiplier">1.1</item>
<item name="android:textSize">16sp</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">#ffff0000</item>
<item name="android:padding">2dip</item>
</style>
Nothing change at all, i saw the api and should be change the style instead i got the default style.
Any advice.
Cheers
Ron
You can define the TextView in separated layout file (like Rajath DSouza suggested). And then load the view from layout file (inflate it) dynamically.
For example:
TextView title = (TextView) activity.getViewInflate().inflate(R.layout.styled_textview, null, null);
If you can use the layout file, do the following - it's simpler.
<TextView
style="#style/TitleSep"
android:text="hello" />
UPDATE: (from comment)
Why don't create the textview at compile time, but make it invisible, and set it to visible if and when you need to show it. The reason I suggest this roundabout method is because setting the style at compile time seems simpler.