I have the following button:
<Button
android:id="#+id/addexperience_button"
style="#style/MyButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/emptystate_image"
android:layout_alignRight="#id/emptystate_image"
android:layout_below="#id/emptystate_image"
android:text="#string/pickdetail_addexperience" />
with this styling:
<style name="MyButton" parent="AppTheme">
<item name="android:textColor">#color/white</item>
<item name="android:paddingLeft">#dimen/single_spacing</item>
<item name="android:paddingRight">#dimen/single_spacing</item>
<item name="android:background">#drawable/bg_primarybutton</item>
</style>
bg_primarybutton:
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetBottom="6dp"
android:insetLeft="4dp"
android:insetRight="4dp"
android:insetTop="6dp">
<ripple android:color="?android:attr/colorControlHighlight">
<item>
<shape
android:shape="rectangle"
android:tint="#color/colorPrimary">
<corners android:radius="18dp" />
</shape>
</item>
</ripple>
</inset>
Now this button looks like this with 28.0.0-alpha1:
But looks like this with alpha2, alpha3 and rc01:
How come its ignoring my styling on a later version (esp. a RC?) Maybe there is something fundamentally wrong on my Button definition?
The reason for that is because of your AppTheme being Theme.MaterialComponents.Light.NoActionBar, the inflater of your activity is inflating a MaterialButton instead of a Button and you can't change the background of a MaterialButton the same way of an old Button (see doc) .
If you want to have the same style as before, replace your MyButton style with
<style name="MyButton">
<item name="android:textColor">#color/white</item>
<item name="android:paddingLeft">#dimen/single_spacing</item>
<item name="android:paddingRight">#dimen/single_spacing</item>
<item name="backgroundTint">#color/colorPrimary</item>
<item name="cornerRadius">18dp</item>
<item name="rippleColor">?android:attr/colorControlHighlight</item>
</style>
Note that you should not extend your AppTheme when writing a style (that will be used in the style="#style/MyStyle attribute) for a View.
They introduced the auto inflation of MaterialButton with the alpha2.
Open the class android.support.design.theme.MaterialComponentsViewInflater on alpha1 and alpha2 to see the difference.
If you DO NOT want this behavior of auto inflating MaterialButton change your AppThemeto be
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar.Bridge">
Related
I'm trying to define a custom color for my app's theme.
Here is how I do:
define custom attribute:
<declare-styleable name="ApplicationStyle">
<attr name="colorWeekdaysBg" format="color"/>
</declare-styleable>
Define an application style:
<style name="ApplicationStyle" parent="Theme.AppCompat.NoActionBar">
<item name="android:editTextStyle">#style/EditTextStyle</item>
<item name="colorPrimaryDark">#color/dark_blue</item>
<item name="colorPrimary">#color/dark_blue</item>
<item name="colorAccent">#color/dark_blue</item>
<item name="colorWeekdaysBg">#color/access_weekdays</item>
</style>
Set style in the manifest:
<application
android:name=".App"
android:icon="#drawable/icon_launcher"
android:label="#string/app_name"
android:theme="#style/ApplicationStyle">
Use this attribute in the drawable xml:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:right="-1dp">
<shape android:shape="rectangle">
<stroke
android:width="1dp"
android:color="?colorWeekdaysBg" />
<corners
android:bottomLeftRadius="100dp"
android:topLeftRadius="100dp" />
</shape>
</item>
</layer-list>
But for some reason it does not apply my color to the drawable. It applies a transparent color instead.
One more strange thing is if I replace my ?colorWeekdaysBg with ?colorAccent, which is defined in the Theme.AppCompat, then it applies correct color.
So finally the question: Do you have any idea why it doesn't work, and how to fix it?
As per answer give by mudit here it is a bug in the pre-lollipop OS.
It is reported in Google's Issue Tracker.
In the devices which have Android Lollipop and above OS version it will work fine.
Check below code:
attr.xml
<declare-styleable name="AppTheme">
<attr name="colorWeekdaysBg" format="color|reference" /> <!-- Or you can keep color only. It will be ok -->
</declare-styleable>
You have to set the attribute in the v21 style file. Might be you missed this one.
v21\styles.xml
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:splitMotionEvents">false</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:navigationBarColor">#color/black</item>
<item name="colorWeekdaysBg">#color/access_weekdays</item>
</style>
Create two drawable files to get it work on all devices. One for normal i.e. pre-lollipop version and another for Lollipop and above i.e. v21 drawable.
your_drawable.xml In this you have to set color from the color file.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:right="-1dp">
<shape android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#color/access_weekdays" />
<corners
android:bottomLeftRadius="100dp"
android:topLeftRadius="100dp" />
</shape>
</item>
</layer-list>
v21\your_drawable.xml In this file you can set custom attribute like you did.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:right="-1dp">
<shape android:shape="rectangle">
<stroke
android:width="1dp"
android:color="?colorWeekdaysBg" />
<corners
android:bottomLeftRadius="100dp"
android:topLeftRadius="100dp" />
</shape>
</item>
</layer-list>
your_layout.xml In your layout you can give that drawable as below
<Button
android:id="#+id/btnTest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/your_drawable"
android:text="Test Text" />
Now check the answers of your questions.
But for some reason it does not apply my color to the drawable. It applies a transparent color instead.
Because you may not have defined your attribute in v21 style.xml file
One more strange thing is if I replace my ?colorWeekdaysBg with ?colorAccent, which is defined in the Theme.AppCompat, then it applies the correct color.
Android Studio displays color in preview but when you will run the application and reached on that screen your application will be crash with the Error inflating class error
android.view.InflateException: Binary XML file line #68: Error inflating class Button
So finally the question: Do you have any idea why it doesn't work, and how to fix it?
I think now you have got the idea that why it doesn't work and how to fix it.
Here is the link to what I have in mind.
https://dribbble.com/shots/1407665-Categories/attachments/204971
Is there a popular library anyone knows that can manage this, otherwise I am alright with going the customizing route.
I have my 9 buttons defined in my XML no problem.
Next I know I have to create a xml file in the drawable folder like "button_shape.xml". Then I add this to my code:
android:background="#drawable/button_shape"
I make my button have an image, I assume with:
android:drawableTop="#drawable/buttonImage"
I guess lastly is how do I create a shape that keeps the bottom colour a consistent size with the text. While allowing different button sizes. Also can I easily alternate the colours by setting the style on each button and defining them as so:
<style name ="ButtonTheme.Custom1" parent="Base.Widget.AppCompat.Button.Colored">
<item name="colorPrimary">#android:color/holo_blue_light</item>
<item name="colorPrimaryDark">#android:color/holo_blue_dark</item>
</style>
<style name ="ButtonTheme.Custom2" parent="Base.Widget.AppCompat.Button.Colored">
<item name="colorPrimary">#android:color/holo_green_light</item>
<item name="colorPrimaryDark">#android:color/holo_green_dark</item>
</style>
<style name ="ButtonTheme.Custom3" parent="Base.Widget.AppCompat.Button.Colored">
<item name="colorPrimary">#android:color/holo_red_light</item>
<item name="colorPrimaryDark">#android:color/holo_red_dark</item>
</style>
<style name ="ButtonTheme.Custom4" parent="Base.Widget.AppCompat.Button.Colored">
<item name="colorPrimary">#android:color/holo_orange_light</item>
<item name="colorPrimaryDark">#android:color/holo_orange_dark</item>
</style>
<style name ="ButtonTheme.Custom5" parent="Base.Widget.AppCompat.Button.Colored">
<item name="colorPrimary">#android:color/holo_blue_bright</item>
<item name="colorPrimaryDark">#android:color/holo_blue_light</item>
</style>
My custom shape so far is this, which is close; but how can I make the darker color keep a consistent size while the other moves according to size of button?
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:bottom="10dp">
<shape android:shape="rectangle" >
<size android:height="10dp" />
<solid android:color="#color/colorPrimaryDark" />
</shape>
</item>
<item android:top="120dp">
<shape android:shape="rectangle" >
<size android:height="120dp" />
<solid android:color="#color/colorPrimary" />
</shape>
</item>
</layer-list>
You can use RecyclerView and StaggeredGrid
https://developer.android.com/reference/android/support/v7/widget/StaggeredGridLayoutManager.html
I'd like to change the menu divider left right margin
The original screenshot is like this
But I want to change to this
Currently, my style.xml is
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="android:dropDownListViewStyle">#style/PopupMenuListView</item>
</style>
<!-- Change Overflow Menu ListView Divider Property -->
<style name="PopupMenuListView" parent="#android:style/Widget.Holo.ListView.DropDown">
<item name="android:divider">#color/black</item>
<item name="android:dividerHeight">1px</item>
<!-- I put this line dividerPadding, but it doesn't work-->
<item name="android:dividerPadding">10px</item>
</style>
Any suggestion?
Thanks.
Eric
I found Sukhwant Singh Grewal's answer useful (hence upvoted) but a bit concise. Here's a more fully spelled-out solution.
In styles.xml I added the line:
<item name="android:listDivider">#drawable/divider</item>
Then I added the following divider.xml file under res/drawable:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="#drawable/divider_line"
android:left="16dp"
android:right="16dp"/>
</layer-list>
Lastly, I added the following divider_line.xml file under res/drawable:
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="#color/pink_dark"/>
<corners
android:radius="3dp"/>
</shape>
This seemed to work for me.
under res/drawable
add divider.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:left="60dp"
android:right="10dp" android:drawable="#drawable/divider">
</item>
</layer-list>
in android:drawable="#drawable/divider_image"you can use any color like android:drawable="#color/black". Then take it as background of your divider and give height.
I have a button defined as shown below. When I want to disable it I use my_btn.setEnabled(false), but I would also like to grey it out. How can I do that?
Thanks
<Button android:id="#+id/buy_btn" style="#style/srp_button" />
style/srp_button
<style name="srp_button" parent="#android:style/Widget.Button">
<item name="android:background">#drawable/btn_default</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#ffffff</item>
<item name="android:textSize">14sp</item>
<item name="android:typeface">serif</item>
<item name="android:paddingLeft">30dp</item>
<item name="android:paddingRight">30dp</item>
<item name="android:paddingTop">5dp</item>
<item name="android:paddingBottom">5dp</item>
</style>
drawable/btn_default.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/pink" />
<corners android:radius="6dp" />
</shape>
You could Also make it appear as disabled by setting the alpha (making it semi-transparent). This is especially useful if your button background is an image, and you don't want to create states for it.
button.setAlpha(.5f);
button.setClickable(false);
update: I wrote the above solution pre Kotlin and when I was a rookie. It's more of a "quick'n'dirty" solution, but I don't recommend it in a professional environment.
Today, if I wanted a generic solution that works on any button/view without having to create a state list, I would create a Kotlin extension.
fun View.disable() {
getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY)
setClickable(false)
}
In Java you can do something is similar with a static util function and you would just have to pass in the view as variable. It's not as clean but it works.
You have to provide 3 or 4 states in your btn_defaut.xml as a selector.
Pressed state
Default state
Focus state
Enabled state (Disable state with false indication; see comments)
You will provide effect and background for the states accordingly.
Here is a detailed discussion: Standard Android Button with a different color
The most easy solution is to set color filter to the background image of a button as I saw here
You can do as follow:
if ('need to set button disable')
button.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
else
button.getBackground().setColorFilter(null);
Hope I helped someone...
All given answers work fine, but I remember learning that using setAlpha can be a bad idea performance wise (more info here). So creating a StateListDrawable is a better idea to manage disabled state of buttons. Here's how:
Create a XML btn_blue.xml in res/drawable folder:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Disable background -->
<item android:state_enabled="false"
android:color="#color/md_blue_200"/>
<!-- Enabled background -->
<item android:color="#color/md_blue_500"/>
</selector>
Create a button style in res/values/styles.xml
<style name="BlueButton" parent="ThemeOverlay.AppCompat">
<item name="colorButtonNormal">#drawable/btn_blue</item>
<item name="android:textColor">#color/md_white_1000</item>
</style>
Then apply this style to your button:
<Button
android:id="#+id/my_disabled_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/BlueButton"/>
Now when you call btnBlue.setEnabled(true) OR btnBlue.setEnabled(false) the state colors will automatically switch.
You should create a XML file for the disabled button (drawable/btn_disable.xml)
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/grey" />
<corners android:radius="6dp" />
</shape>
And create a selector for the button (drawable/btn_selector.xml)
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/btn_disable" android:state_enabled="false"/>
<item android:drawable="#drawable/btn_default" android:state_enabled="true"/>
<item android:drawable="#drawable/btn_default" android:state_pressed="false" />
</selector>
Add the selector to your button
<style name="srp_button" parent="#android:style/Widget.Button">
<item name="android:background">#drawable/btn_selector</item>
</style>
Set Clickable as false and change the backgroung color as:
callButton.setClickable(false);
callButton.setBackgroundColor(Color.parseColor("#808080"));
I tried the above solutions but none of them seemed to work for me. I went with the following option:
<!-- button_color_selector.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/colorAccent" android:state_enabled="true"/>
<item android:color="#color/colorAccentLight" android:state_enabled="false"/>
</selector>
<com.google.android.material.button.MaterialButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#color/button_color_selector"
.../>
I used this code for that:
ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
profilePicture.setColorFilter(filter);
Button button = (Button)findViewById(R.id.buy_btn);
button.setEnabled(false);
I've created custom ToggleButtons in Android and since all buttons inherit from the same xml I want to change how they act depending on state, so when the state is checked I want to change the shadow color but this does not seem to possible with the current SDK.
I've created an xml file which holds button_colors:
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_checked="true"
android:color="#FFFFFF" />
<item
android:color="#000000" />
</selector>
But this only seems to work with text-color and not shadow color on the text.
Is there something I'm missing?
And rather not do this for every button manually in code since I want this to apply to every button in the app.
UPDATE EDIT:
My selector currently looks like this
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_checked="true"
android:drawable="#drawable/button_gradient_selected" />
<item
android:drawable="#drawable/button_gradient" />
</selector>
But as I mentioned to the commentator below I can't seem to change the style/text-color-shadow from here since it only can take in a drawable it seems.
When I try to put in a different style on the button in here it force closes or either does not change the style depending on state. When I only try to put in the style here and have the drawable be set in the style it force closes. Either way it does not work it seems.
Seems that the Android framework does not support this.
From TextView.java:
case com.android.internal.R.styleable.TextView_textColor:
textColor = a.getColorStateList(attr);
break;
case com.android.internal.R.styleable.TextView_shadowColor:
shadowcolor = a.getInt(attr, 0);
break;
They treat textColor and shadowColor differently.
Please refer to my solution on a different StackOverFlow question. I extended TextView to give a working solution here. (Replace TextView with Button)
This is the Selector file you have to implement:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false" android:drawable="#drawable/btn_toggle_off" />
<item android:state_checked="true" android:drawable="#drawable/btn_toggle_on" />
</selector>
These are the picture tey used for the default ToggleButton:
btn_toggle_on and btn_toogle_off
You can have a selector for the shadow color like this: color_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:dither="true">
<item
android:state_pressed="true"
android:color="#color/btn_text_on" />
<item
android:state_focused="true"
android:color="#color/btn_text_on" />
<item
android:color="#color/btn_text_off" />
</selector>
and then use this selector while styling your button in styles.xml like this:
<style name="ButtonStyle">
<item name="android:textColor">#FF383C48</item>
<item name="android:textSize">12sp</item>
<item name="android:shadowColor">#drawable/color_selector</item>
<item name="android:shadowDx">0</item>
<item name="android:shadowDy">1</item>
<item name="android:shadowRadius">1</item>
<item name="android:typeface">sans</item>
<item name="android:textStyle">bold</item>
</style>