Unable to use ?customColor in drawable - android

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.

Related

How to create an Button with an image, text, and two colours?

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

Using attributes for bitmap src inside a drawable selector

I'm trying to create custom themes for my app and therefore, would like the selector to pick up the right drawable based on the current theme. Unfortunately, doesn't look like any image gets picked up at all.
This is my selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<bitmap android:src="?attr/test_a"
android:gravity="center" />
</item>
<item android:state_focused="true">
<bitmap android:src="?attr/test_a"
android:gravity="center" />
</item>
<item android:state_activated="true">
<bitmap android:src="?attr/test_a"
android:gravity="center" />
</item>
<item>
<bitmap android:src="?attr/test_b"
android:gravity="center" />
</item>
</selector>
My attributes are defined in attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="test_a" format="reference"/>
<attr name="test_b" format="reference"/>
</resources>
And my theme has the following:
<style name="MyTheme" parent="Theme.AppCompat.NoActionBar">
<item name="test_a">#drawable/test_a_dark</item>
<item name="test_b">#drawable/test_b_dark</item>
</style>
<style name="MyTheme.Light">
<item name="test_a">#drawable/test_a_light</item>
<item name="test_b">#drawable/test_b_light</item>
</style>
The theme is applied in the manifest as required. I have seen some questions on SO around this saying that there's a problem Pre-Lolipop, however, I'm testing on Marshmellow.
Still not sure why this happens but in case this is useful for someone, as a workaround I did the following:
1) Created two selectors - one for the dark theme, pointing directly at the dark drawables, and one for the light theme
2) Created one attribute with type reference
3) Modified the theme to use that attribute point at the selector instead of the drawable

Android: Change menu divider left right margin

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.

android pass color variable to a complex button style in XML

I have a style for button like : http://ace-subido.github.io/css3-microsoft-metro-buttons/buttons.html (See Stripped button).
But I want to be able to use this style for different colors without recreating 4 xml files (a selector drawable + 3 button states drawables with layer list).
In a btn_stripped_orange.xml (and 2 other xml for different button states) I have a color
With this syntax, evrything is ok :-)
But instead of creating 4 new xml files for every different colors, I want to "pass a color" to btn_stripped_orange.xml (so I should rename it to btn_stripped.xml).
In style.xml I have to call #drawable/btn_stripped_orange_selector
after this btn_stripped_orange_selector call
I think I have to pass the border_color variable to the style in styles.xml with call #drawable/btn_stripped_orange_selector
I want to just create new style with the #drawable/btn_stripped_orange_selector as android:background (and rename it) and the color varaible
This is the code that I'm trying to do (no error in eclipse, but app crash on run), If I replace ?attr/border_color with a color #color/orange for exemple, it works perfectly. I think it's just a syntax problem.
My themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="btn_orange" parent="#style/btStripped1">
<item name="border_color">#attr/border_color</item>
</style>
<attr name="border_color" format="color" />
</resources>
My btn_stripped_orange_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/btn_stripped_orange_press" />
<item android:state_focused="true" android:drawable="#drawable/btn_stripped_orange_focus" />
<item android:drawable="#drawable/btn_stripped_orange" />
</selector>
My btn_stripped_orange.xml (nearly the same than _focus and _press) :
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="?attr/border_color" />
</shape>
</item>
<item android:left="5dp">
<shape android:shape="rectangle">
<solid android:color="#EEEEEE" />
</shape>
</item>
<item android:left="5dp">
<shape android:shape="rectangle">
<solid android:color="#EEEEEE" />
</shape>
</item>
</layer-list>
Finally in my styles.xml
<resources>
.....
<style name="btStripped1">
<!-- I want to pass a color variable here -->
<item name="android:background">#drawable/btn_stripped_orange_selector</item>
<item name="android:padding">6dp</item>
<item name="android:textColor">#android:color/black</item>
<item name="android:shadowColor">#android:color/white</item>
<item name="android:shadowDx">1</item>
<item name="android:shadowDy">1</item>
<item name="android:shadowRadius">1</item>
</style>
....
</resources>
I want a pure xml solution but if it's impossible and you have a solution with a bit of java code, your're welcome !
Thank you very very much for your help and sorry for average english !

Android : change button text and background color

How can I change both text and background colors when my button is pressed, with xml ?
To change text color I can do :
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="mycolor"/>
<item android:color="mycolor2"/>
</selector>
To change the background I can do (using it in a selector/item with drawable reference) :
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FF0079FF" />
</shape>
But how can I do both ? Let's say I want to have :
Default : black text / white background
Pressed : white text / blue background
EDIT : answer
I totaly forgot that the background and text color are managed separately, so this is how I did it :
<Button
android:textColor="#color/filtersbuttoncolors"
android:background="#drawable/mybackgroundcolors" />
In mybackgroundcolors.xml I manage the background and in filtersbuttoncolors.xml I manage the text color. In both xml files I manage the status (pressed, selected, default)
Since API level 21 you can use :
android:backgroundTint="#android:color/white"
you only have to add this in your xml
Here is an example of a drawable that will be white by default, black when pressed:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape>
<solid
android:color="#1E669B"/>
<stroke
android:width="2dp"
android:color="#1B5E91"/>
<corners
android:radius="6dp"/>
<padding
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp"/>
</shape>
</item>
<item>
<shape>
<gradient
android:angle="270"
android:endColor="#1E669B"
android:startColor="#1E669B"/>
<stroke
android:width="4dp"
android:color="#1B5E91"/>
<corners
android:radius="7dp"/>
<padding
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp"/>
</shape>
</item>
</selector>
I think doing this way is much simpler:
button.setBackgroundColor(Color.BLACK);
And you need to import android.graphics.Color; not: import android.R.color;
Or you can just write the 4-byte hex code (not 3-byte) 0xFF000000 where the first byte is setting the alpha.
Just complementing #Jonsmoke's answer.
For API level 21 and above you can use :
android:backgroundTint="#android:color/white"
in XML for the button layout.
For API level below 21 use an AppCompatButton using app namespace instead of android for backgroundTint.
For example:
<android.support.v7.widget.AppCompatButton
android:id="#+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="My Button"
app:backgroundTint="#android:color/white" />
add below line in styles.xml
<style name="AppTheme.Gray" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorButtonNormal">#color/colorGray</item>
</style>
in button, add android:theme="#style/AppTheme.Gray", example:
<Button
android:theme="#style/AppTheme.Gray"
android:textColor="#color/colorWhite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#android:string/cancel"/>
When you create an App, a file called styles.xml will be created in your res/values folder. If you change the styles, you can change the background, text color, etc for all your layouts. That way you don’t have to go into each individual layout and change the it manually.
styles.xml:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Theme.AppBaseTheme" parent="#android:style/Theme.Light">
<item name="android:editTextColor">#295055</item>
<item name="android:textColorPrimary">#295055</item>
<item name="android:textColorSecondary">#295055</item>
<item name="android:textColorTertiary">#295055</item>
<item name="android:textColorPrimaryInverse">#295055</item>
<item name="android:textColorSecondaryInverse">#295055</item>
<item name="android:textColorTertiaryInverse">#295055</item>
<item name="android:windowBackground">#drawable/custom_background</item>
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
parent="#android:style/Theme.Light" is Google’s native colors. Here is a reference of what the native styles are:
https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/res/res/values/themes.xml
name="Theme.AppBaseTheme" means that you are creating a style that inherits all the styles from parent="#android:style/Theme.Light".
This part you can ignore unless you want to inherit from AppBaseTheme again. = <style name="AppTheme" parent="AppBaseTheme">
#drawable/custom_background is a custom image I put in the drawable’s folder. It is a 300x300 png image.
#295055 is a dark blue color.
My code changes the background and text color. For Button text, please look through Google’s native stlyes (the link I gave u above).
Then in Android Manifest, remember to include the code:
<application
android:theme="#style/Theme.AppBaseTheme">
Just use a MaterialButton and the app:backgroundTint and android:textColor attributes:
<MaterialButton
app:backgroundTint="#color/my_color"
android:textColor="#android:color/white"/>
add below lines in the styles.xml
<style name="AppTheme.Gray" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorGray</item>
</style>
and in button, add android:theme="#style/AppTheme.Gray", example:
<Button
android:theme="#style/AppTheme.Gray"
android:textColor="#color/colorWhite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#android:string/cancel"/>

Categories

Resources