Material Components Chip colour styling - android

In my XML I'm just declaring a ChipGroup as follows:
<com.google.android.material.chip.ChipGroup
android:id="#+id/chipGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
And then adding each Chip dynamically:
ChipGroup chipGroup = findViewById(R.id.chipGroup);
for (String name : names) {
Chip chip = new Chip(activity);
chip.setText(name);
chipGroup.addView(chip);
}
The colour of a selected Chip (light green below) seems to be coming from the colorSecondaryContainer attribute (I know that, because when I change that in my theme, the Chip colour changes). I'd rather it came from colorPrimaryContainer, but it would be OK as-is except that the text colour does not suit colorSecondaryContainer... in particular, the text colour does not seem to be coming from colorOnSecondaryContainer as I would expect, because colorOnSecondaryContainer is dark in my theme, but what I'm seeing is a light text colour on a light chip colour (and the text colour is light regardless of checked status):
How do I make my Chip style comply with my material theme in general, without having to resort to setting this stuff via setters like chip.setTextColor() etc? I don't declare any Chip via XML so I can't override the style in the individual declaration either.

Add Chip Style in theme.xml file
ChipCustomStyle in theme.xml
<style name="ChipCustomStyle" parent="#style/Widget.MaterialComponents.Chip.Choice">
<item name="chipBackgroundColor">#color/chip_background_color</item>
<item name="android:textColor">#color/chip_text_color</item>
<item name="chipCornerRadius">5dp</item>
</style>
Create color resource folder under res and Add chip_background_color.xml for chip background color and chip_text_color.xml for chip text color
chip_background_color.xml in color folder
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/green" android:state_checked="true" />
<item android:color="#color/white" />
</selector>
chip_text_color.xml in color folder
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/white" android:state_checked="true" />
<item android:color="#color/black" />
</selector>
Create attr.xml in values folder and then add CustomChipChoiceStyle attribute in attr.xml
<resources>
<attr name="CustomChipChoiceStyle" format="reference"/>
</resources>
Add CustomChipChoiceStyle in your current activity theme in theme.xml file
<item name="CustomChipChoiceStyle">#style/ChipCustomStyle</item>
Now add CustomChipChoiceStyle style to your Chip in Kotlin file, Example code:
val chipGroup = findViewById<ChipGroup>(R.id.chipGroup)
for (name in names) {
val chip = Chip(this, null, R.attr.CustomChipChoiceStyle)
//val chip = Chip(this)
chip.text = name
chipGroup.addView(chip)
}

Related

Why does the Material FAB not change colors when disabled?

I am disabling the Material Floating Action button but the color does not change when disabled is set to true. I thought Material has a theme for FAB's and when disabled it should turn light grey. I do not want to add code to change the background every time it is enabled/disabled.
I am currently on material version: 1.1.0
In the code I just set the fab to disabled by fab.isEnabled = false
Here is the xml
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/save_reservation_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/keyline_2"
app:backgroundTint="#color/color_primary"
android:src="#drawable/ic_save_black_72dp"
app:tint="#color/color_on_primary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
This is what the disabled/enabled fab looks like:
It should look something like this:
I suspect that this is the culprit:
app:backgroundTint="#color/color_primary"
This is going to tint the color of your FAB regardless of its state.
You could solve this by setting the tint to a ColorStateList instead of a raw color value. That is, create a file named fab_color.xml in your res/color/ directory, and include this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="your gray here"/>
<item android:color="#color/color_primary"/>
</selector>
And change your tint to this instead:
app:backgroundTint="#color/fab_color"
Alternatively, you could adjust your Activity's theme such that the default color of the FAB is the color you want (#color/color_primary) and then remove the app:backgroundTint attr altogether.
The version 1.2.0 introduced the support for enabled/disabled states in the FloatingActionButton.
Now the default style support the disabled state and the background color is based on the colorOnSurface when disabled:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorSecondary" android:state_enabled="true"/>
<item android:alpha="0.12" android:color="?attr/colorOnSurface"/>
</selector>
You can change it using the app:backgroundTint attribute with a custom selector or using:
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:theme="#style/ThemeOverlay.Custom.FloatingActionButton"
../>
with:
<style name="ThemeOverlay.Custom.FloatingActionButton" parent="">
<item name="colorOnSurface">#color/....</item>
</style>

Selector drawable on MaterialButton android

I have been using the new MaterialButton class. I want different colors on the button when the user clicks the button.
I have been using selector drawables for this purpose since the very beginning, however it doesn't appear to be working on MaterialButton.
<com.google.android.material.button.MaterialButton
android:layout_width="0dp"
android:text="#string/login"
style="#style/Widget.Mohre.Button"
android:layout_height="wrap_content"
app:cornerRadius="#dimen/card_corner_radius"
android:padding="#dimen/unit_large"
android:id="#+id/loginBtn"/>
My Widget.Mohre.Button style
#color/textColorWhite
#drawable/mohre_button_selector
#style/TextAppearance.Button
#animator/button_state_list_anim
My selector drawable
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/mohre_button_pressed" android:state_pressed="true" />
<item android:drawable="#drawable/mohre_button_selected" android:state_enabled="false" android:state_pressed="false" />
<item android:drawable="#drawable/mohre_button_normal" />
My individual drawables are just rectangle shapes with different colors like these
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="30dp"></corners>
<solid android:color="#3a516a"></solid>
</shape>
The button doesn't take on the colors at all from the selector drawable. It just shows the default accent color of the application
With the normal way (setting the selector drawable as background of the button), it won't work as expected if you are using Theme.MaterialComponents.
You can use Theme.AppCompat.DayNight.NoActionBar as an alternative, but if you don't want to use that theme, then simply use:
<androidx.appcompat.widget.AppCompatButton
................/>
You will get the same result as it was working with the Appcompat theme even if you are using latest Material themes!
as explained in this medium post https://medium.com/over-engineering/hands-on-with-material-components-for-android-buttons-76fa1a92ec0a we can use ColorStateList to change color or background of Button.
For me working solution for now was to set backgroundTint to null and backgroundTintMode to add like this:
<style name="Button.XYZ" parent="Button">
<item name="shapeAppearance">?attr/shapeAppearanceLargeComponent</item>
<item name="drawableTint">#color/ColorXYZ</item>
<!-- background drawable -->
<item name="backgroundTint">#null</item>
<item name="backgroundTintMode">add</item>
<!-- background drawable -->
<item name="android:background">#drawable/XYZ</item>
<!-- Color drawable -->
<item name="android:textColor">#color/XYZ</item>
</style>
And also using the style in xml not in theme
If you want a button that has a custom background (to apply <selector> e.g), but your theme is set up to use Theme.MaterialComponents (which is nowadays, 2021), you could switch the XML element in the layout to be <android.widget.Button> instead of <Button>. This should cause the Material Components for Android to ignore that element, and you can manipulate this button normally with respect to XML attributes.

Change Chip Widget style programmatically not working - Android

I'm doing a list with Chips. I want this chips can be selected, so, taking a look to https://material.io/develop/android/components/chip/ I see I can have a "Choice Chip".
As I need to create and add dynamically I have to configure with specific colors, color ripplem, ...
So what I have to configure it is:
val chip = Chip(context, null, R.style.CustomChipChoice)
chip.isClickable = true
chip.isCheckable = true
chip.isCheckedIconVisible=false
chip.height = ScreenUtils.dpToPx(40)
chip.chipCornerRadius = (ScreenUtils.dpToPx(20)).toFloat()
chip.chipStrokeWidth = (ScreenUtils.dpToPx(2)).toFloat()
chip.setTextAppearanceResource(R.style.ChipTextStyle)
return chip
What I try with R.style.CustomChipChoice is:
CustomChipChoice style
<style name="CustomChipChoice" parent="#style/Widget.MaterialComponents.Chip.Choice">
<item name="chipBackgroundColor">#color/background_color_chip_state_list</item>
<item name="chipStrokeColor">#color/background_color_chip_state_list</item>
<item name="rippleColor">#color/topic_social_pressed</item>
</style>
background_color_chip_state_list
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/topic_social_selected" android:state_checked="true" />
<item android:color="#color/topic_social_pressed" android:state_pressed="true" />
<item android:color="#color/topic_unselected_background" />
</selector>
stroke_color_chip_state_list
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/topic_social_pressed" android:state_checked="true"/>
<item android:color="#color/grey_material2" android:state_checked="false"/>
</selector>
As you can see, I make the chip, clickable and checkable (hiding the check icon I don't need).
But when I test it, the colors are not set. The chips just look as default colors (grey's scale)
Where can I apply or how, this custom style?
P.S:
I have done a fast test, to see if my CustomStyle was malformed/etc..
I added a view via xml and worked perfectly...
<android.support.design.chip.Chip
android:id="#+id/test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/CustomChipChoice"
android:checkable="true"
android:clickable="true"
app:checkedIconVisible="false"
android:text="Chip Test"/>
You can't use the constructor val chip = Chip(context, null, R.style.CustomChipChoice) because the 3rd parameter isn't the style but the attribute in the theme as R.attr.chipStyle.
The Chip hasn't a constructor with 4 parameters as other components because it extends AppCompatCheckbox which does not support a 4 parameter constructor.
However you can use something different.
1st option:
Just use a xml layout (single_chip_layout.xml) to define the single Chip with your favorite style:
<com.google.android.material.chip.Chip
xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/CustomChipChoice"
...
/>
with
<style name="CustomChipChoice" parent="#style/Widget.MaterialComponents.Chip.Choice">
...
</style>
Then instead of val chip = Chip(context, null, R.style.CustomChipChoice) use:
val chip = layoutInflater.inflate(R.layout.single_chip_layout, chipGroup, false) as Chip
In java:
Chip chip =
(Chip) getLayoutInflater().inflate(R.layout.single_chip_layout, chipGroup, false);
2nd option:
Another option is to use the setChipDrawable method to override the ChipDrawable inside the Chip:
Chip chip = new Chip(this);
ChipDrawable chipDrawable = ChipDrawable.createFromAttributes(this,
null,
0,
R.style.Widget_MaterialComponents_Chip_Choice);
chip.setChipDrawable(chipDrawable);
In order to set the chip style in code you can try the following:
val chip = Chip(context)
val drawable = ChipDrawable.createFromAttributes(context, null, 0, R.style.Widget_MaterialComponents_Chip_Choice)
chip.setChipDrawable(drawable)
the CustomChipChoice is not a style it is just a reference to a style. therefore change R.style.CustomChipChoice to it : R.attr.CustomChipChoice
val newChip = Chip(context, null, R.attr.CustomChipChoice)
but before it you should add this CustomChipChoicein values.xml file in your project.
for this. if your project does not have the values.xml create it in values directory.
then add CustomChipChoice like this.
values.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="CustomChipChoice" format="reference" />
</resources>
now in styles.xml add your style like this.
styles.xml
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
.
.
<item name="CustomChipChoice">#style/CustomChipChoiceStyle</item>
.
.
</style>
now that CustomChipChoice attr references to this style
and now you can create your custom style in styles.xml file.
styles.xml
<style name="CustomChipChoiceStyle" parent="#style/Widget.MaterialComponents.Chip.Action">
.
<item name="checkedIconVisible">false</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
<item name="chipBackgroundColor">#color/colorWhite</item>
<item name="chipIcon">#drawable/ic_filter</item>
<item name="chipIconVisible">true</item>
<item name="textStartPadding">0dp</item>
<item name="textEndPadding">0dp</item>
.
.
<item name="android:textAppearance">#style/ChipTextStyleAppearance</item>
</style>
if you want to change text appearance of chip. here is ChipTextStyleAppearance. you can add it like this.
styles.xml
<style name="ChipTextStyleAppearance">
<item name="android:fontFamily">#font/main_font</item>
<item name="android:textSize">13dp</item>
<item name="android:textColor">#ffffff</item>
</style>
dont forget to add the AppTheme in androidManifest.xml on application or activity tags.
androidManifest.xml
<application
.
.
android:theme="#style/AppTheme">
<activity
.
.
android:theme="#style/AppTheme" />
There's another very simple approach to this.
styles.xml
<style name="Widget.MyApp.Chip" parent="Widget.MaterialComponents.Chip.Choice">
<item name="android:textAppearance">#style/TextAppearance.MyApp.Chip</item>
<item name="chipIconTint">?attr/colorPrimary</item>
</style>
theme.xml
<style name="Theme.MyApp.MyTheme" parent="Base.Theme.MyApp">
<item name="chipStyle">#style/Widget.MyApp.Chip</item>
</style>
With this, all chips in activities that have the theme Theme.MyApp.MyActivity applied to it will follow this custom style whether the chip has been added through xml or programmatically.
Kotlin
xml
<com.google.android.material.chip.ChipGroup
android:id="#+id/chipGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
</com.google.android.material.chip.ChipGroup>
Class
data class Parametro(
var idParametro: Long,
var nombreParametro: String? )
Main
listParametro.forEach { it->
val chip = Chip(context)
chip.id= it.idParametro.toInt()
chip.text= it.nombreParametro
chip.isClickable = true
chip.isCheckable = true
chip.setOnCheckedChangeListener { buttonView, isChecked ->
Log.i("checkedChipIds","${buttonView.id} $isChecked")
}
mBinding.chipGroup.addView(chip)
}
it works for me :)

Remove pressed color on Spinner

I'd like to remove the blue color (I'm testing my app with Holo) appearing when I click on a Spinner.
My code :
ArrayAdapter<String> array_adapter = new ArrayAdapter<String> (getActivity(),
R.layout.spinner_item, string_array);
array_adapter.setDropDownViewResource(R.layout.spinner_item);
Spinner spinner = (Spinner) getView().findViewById(R.id.spinner);
spinner.setAdapter(array_adapter);
spinner_item.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/spinner_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAllCaps="true"
android:background="#drawable/item"
style="#style/EquidiaTheme.MySpinner" />
and item.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#android:color/transparent" />
<item android:state_selected="true" android:drawable="#android:color/transparent" />
<item android:drawable="#android:color/transparent" />
</selector>
This doesn't work. Any idea?
Customize android:spinnerDropDownItemStyle
Styling ActionBar dropdown menu
I was able to get rid the blue rectangle on item when I select it when I done this:
First I declare color that I want to use in values.xml:
<resources>
<drawable name="red_color">#ff0000</drawable>
<drawable name="blue_color">#0000ff</drawable>
<drawable name="green_color">#00ff00</drawable>
<drawable name="transparent_color">#00000000</drawable>
</resources>
Than I define custom style in Styles.xml
<resources>
<style name="Theme.Spinner" parent="android:Theme.Holo">
<item name="android:attr/listChoiceBackgroundIndicator">#drawable/transparent_color</item>
</style>
</resources>
in the style I was able to use only colors defined in resources ( Setting color like: #android:color/XXX or #XXX directly in style didn't work)
After all I aplly the them on Activity. I use Xamarin so may code is:
[Activity( Label = "TestLayouts", MainLauncher = true, Icon = "#drawable/icon", Theme="#style/Theme.Spinner")]
but for android it should be:
<activity android:theme="#style/Theme.Spinner">
I use this answer for reference:
Default selector background in Clickable Views
also to get rid the blue rectangle on spinner itself use:
<Spinner
android:background="#null"
You need to use both to completly remove blue rectable.
Also maybe this attributes in style may help you:
<item name="android:attr/colorPressedHighlight">#FF0000</item>
<item name="android:attr/colorLongPressedHighlight">#FF0000</item>
<item name="android:attr/listChoiceIndicatorSingle">#drawable/red_color</item>
A solution without theme. Ideal if you only got a few spinner.
create a drawable (xml) with state (https://developer.android.com/guide/topics/resources/drawable-resource.html#StateList)
use the SAME image for the state PRESSED and NORMAL
then use it as background :
mySpinner.setBackgroundResource(R.drawable.my_spinner_state_drawable)
extra tips:
you can use system drawable (image) from the system resource: like "#android: drawable/btn_dropdown_normal". It is easier to maintain and give a more native look and feel.
ref http://androiddrawables.com/Buttons.html

How to get(reference) the current theme default text color in XML

I have a shape (rect_shape.xml) which draws a stroke outline in every item of a listview (listview_style.xml).
This outline should have the same color like the default text color of the current theme.
Is there any way, in XML, to set the android:color value of the stroke to the current text color?
I've seen some similar questions (like How to get my own defined attribute value in my style ) around here which try to set an own attribute, but I don't think that this is what I want.
Anyhow I tried that but I couldn't set the android:color value to my own defined attribute ( android:color="?custom_stroke_color" throws InflateException).
Because the user is able to switch between the Themes dynamically, one single predefined color (or reference to a color resource e.g. #color/white ) in rect_shape.xml is not an option.
Appreciate any help...
rect_shape.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<stroke android:width="3dp"
<!-- should be the current default text color -->
android:color="#FFF" />
<solid/>
...
</shape>
listview_style.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/rect_shape" >
...
</LinearLayout>
themes.xml
<resources>
<style name="DarkTheme" parent="#style/Theme.Sherlock">
<!-- default text color is white -->
...
</style>
<style name="LightTheme" parent="#style/Theme.Sherlock.Light">
<!-- default text color is black-->
...
</style>
</resources>
Accessing themed attributes in drawable XML files is only available in android 5.0 and up.
See This issue

Categories

Resources