Why doesn't the margin apply on this Button? - android

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.

Related

Styles for Children of ConstraintLayout

I wanna set general style for my inner elements of my ConstraintLayout. For example, I have multiple TextViews with following attributes:
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
I created this style for it:
<style name="PageTitleStyle">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginRight">8dp</item>
<item name="android:layout_marginLeft">8dp</item>
</style>
but how can I set these attributes to the defined style?
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
You can define your attributes in styles as follows:
<style name="MyStyle">
<item name="layout_constraintLeft_toLeftOf">parent</item>
<item name="layout_constraintRight_toRightOf">parent</item>
</style>
You can then specify style="#style/MyStyle" on each TextView.
Setting the style on the ConstraintLayout will not set the style on the children of the ConstraintLayout unless you set the style as a theme. See "Apply a style as a theme". (Emphasis is mine.)
Beginning with Android 5.0 (API level 21) and Android Support Library v22.1, you can also specify the android:theme attribute to a view in your layout file. This modifies the theme for that view and any child views, which is useful for altering theme color palettes in a specific portion of your interface.
So you would add android:theme="#style/MyStyle" to the ConstraintLayout. This will replace the existing theme, so you may want to set your AppTheme as the parent of MyStyle.
There is one odd-looking side effect that I have noticed in doing this: The constraints named in the style effect the display of the layout in the studio designer (correctly) but the constraints themselves do not display. The layout editor will also not pick up that the constraints are defined in the style and will give "constraint missing" errors. (Android Studio 3.3 RC3)
Relation constraints can not be used in "style". Try to use it in layout

Style not working entirely when applied on Button programmatically [duplicate]

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.

Android change button colors only

For my android project I have some default buttons.
To make the app look nicer I try to change the colors with the following code :
<style name="CustomStyle"parent="#android:style/Theme.Holo.Light.DarkActionBar">
<item name="android:buttonStyle">#style/CustomButton</item>
</style>
<style name="CustomButton" parent="android:style/Widget.Button">
<item name="android:background">#color/buttonBackgroundColor</item>
<item name="android:textColor">#color/buttonTextColor</item>
</style>
The color of the buttons are adjusted like I want but all the exisiting default heights and paddings are gone.
How should I adjust the colors of my button without losing the existing padding and height and other default values?
I want to change the style for all buttons in my app in multiple fragments/activitys so doing it programmaticly is not prefered.
Minimum api level that I use is 14, if I used api level 21 or higher I could use backgroundTint instead of background and get the right result but this is not an option now.
Android default button uses a 9 patch drawable as background.
which has some default padding, look at the content area defined by the right and bottom lines.
You can define padding as well in the custom style you have.
<style name="CustomButton" parent="android:style/Widget.Button">
<item name="android:background">#color/buttonBackgroundColor</item>
<item name="android:textColor">#color/buttonTextColor</item>
<item name="android:padding">#dimen/custom_button_padding</item>
</style>
You can do it programatically with :
yourButton.setBackgroundColor(getResources().getColor(Color.parseColor("#FFFFFF")));
or if you want to do it using styles:
1) You should insert a dimension value within the style xml:
<dimen name="buttonHeight">40px</dimen>
2) Reference the dimension value. So in your layout file you'll write:
android:layout_height="#dimen/buttonHeight"

FrameLayout not use the styles correctly

I am very happy with this website. I'm learning a lot.
Today I doubt has arisen. And I want to put a style to a FrameLayout. and do not use.
The style is as follows:
<style name="textAsk">
<item name="android:textColor">#000000</item>
<item name="android:padding">2dp</item>
<item name="android:minWidth">88dp</item>
<item name="android:minHeight">36dp</item>
<item name="android:textSize" >18dp</item>
<item name="android:layout_marginRight">12dp</item>
<item name="android:layout_marginLeft">12dp</item>
<item name="android:layout_marginTop">5dp</item>
</style>
I show fragments that are changing in a FrameLayout. Each Fragment contains a TextView with a text in it.
There are a lot of fragments, and I would like to set a style, a common one, for all the TextViews, in order to save time and not setup the style in each TextView.
I had tried this code:
<FrameLayout
android:id="#+id/fragmentaskGRP1"
android:layout_width="match_parent"
android:layout_height="450dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
style="#style/textAsk"/>
But the only thing that works for me is:
<item name="android:layout_marginRight">12dp</item>
<item name="android:layout_marginLeft">12dp</item>
<item name="android:layout_marginTop">10dp</item>
Thank you very much for everything
The FrameLayout doesn't support the textColor or textSize attribute (API). So it's never set for the FrameLayout and ignored. See the style properties section from the guide Styles and Themes for more information.
Quote from the Guide:
However, if you apply a style to a View that does not support all of the style properties, the View will apply only those properties that are supported and simply ignore the others.
Define the text-related styles in a separate style definition and use it for this one for the matching views like TextView
The thing is that child views don't inherit styles from their enclosing ViewGroup. Styles can have parents, but in your case TextViews are not going to get these attributes from the FrameLayout.
The other styles will not be applied to fragments. You have to create another logic to apply styles to all fragments (Most probably you will have to apply styles individually to each fragment)
FrameLayout have nothing to do with text so textColor, textSize will have no effect.
Where as minWidth, minHeight are properties of View it think they should work.

Put View styles in resource files

I have some customized Views like:
public class CustomizedTextView extends TextView {
...
public CustomizedTextView(Context context) {
this.setText(TEXT_COLOR);
this.setTextSize(TEXT_SIZE);
this.setTypeFace(TYPE_FACE);
this.setPadding(LEFT, TOP, RIGHT, BOTTOM);
...
}
}
As you can see, these style settings and corresponding constants takes many lines of code. So I want to separate it out in resource files.
I have gone through the Android documentation, it says you could defined a style file like:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CodeFont" parent="#android:style/TextAppearance.Medium">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
</style>
</resources>
But I didn't find an API like setStyle(R.style.style001) to set the style in code. I also found a post here: android set style in code
Basically it says you can't do it in code. However this post is three years ago I am not sure what's the situation in API 19. Because defining a customized View is so common in Android that I don't understand why this is not possible.
You can set the textview style using setTextAppearance like this
textView.setTextAppearance(context, R.style.CodeFont);

Categories

Resources