Android menu item define style for enabled/disabled status - android

Is it possible to define different style for menu item depending on its enabled/disabled status?
For example, I want the text color of menu item to be gray in disabled mode and white in enabled mode.
I didn't have success with changing color dinamycally just as many people didn't on stackoverflow.

It really depends on the item you wish to customize.
Basically you can create a custom color that changes depending on its state:
colors/custom_color.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#FF0000" android:state_enabled="false" />
<item android:color="#CCCCCC"/>
</selector>
Then set it to your menu item like this:
menu.findItem(R.id.action_search).getActionView().
setBackgroundResource(R.colors/custom_color.xml);
Or perhaps in the xml if available:
android:textColor="#color/custom_color"

You can use a drawable as the text colour, and in drawable you can use selector to select the colour according to enabled status. Using following drawable definition as colour will make your disabled menu items grey and the rest black.
In e.g. res/drawable/default_text_colour.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="#android:color/darker_gray"/>
<item android:color="#android:color/white"/>
</selector>
Then, using the drawable:
<item name="android:textColor">#drawable/default_text_colour</item>

For some one else may be needed: use ToolBar instead of ActionBar, add TextView and set style as MenuItem:
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_explorer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="#style/CustomActionBar.Theme"
android:background="#mipmap/bg_naviber">
<TextView
android:id="#+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="#string/title_activity_explorer2"
android:layout_gravity="start"
android:padding="#dimen/dimen_8"
style="#style/CustomActionBar.Tittle"
/>
<TextView
android:id="#+id/toolbar_delete"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:text="#string/action_delete"
android:textColor="#drawable/selector_text_view"
android:padding="#dimen/dimen_16"
style="#style/CustomActionBar.Menu"
/>
<TextView
android:id="#+id/toolbar_do_delete"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:text="#string/action_do_delete"
android:textColor="#drawable/selector_text_view"
android:padding="#dimen/dimen_16"
style="#style/CustomActionBar.Menu"
android:visibility="gone"
/>
</android.support.v7.widget.Toolbar>
set textColor by selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
>
<!-- order is important -->
<item android:state_enabled="false" android:color="#color/white_disabled"/>
<item android:state_pressed="true" android:color="#color/white"/>
<item android:color="#color/white"/>
</selector>

Using:
<style name="Theme.WordsTrainer" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
I've added the line:
<item name="android:textColor">?android:attr/textColorPrimary</item>
to themes.xml and night\themes.xml, and this works fine with day and nigth mode both.
I've spend a day diggin it, and finally found the answer in obvious place:
https://developer.android.com/guide/topics/ui/look-and-feel/darktheme

Related

Set com.google.android.material.chip.Chip selected color

How do I set the selected com.google.android.material.chip.Chip color? I don't want it to be the default gray. This is a single selection chip group.
Original documentation here
<com.google.android.material.chip.ChipGroup
android:id="#+id/chipgroup"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
app:checkedChip="#+id/chip_program"
app:chipSpacingHorizontal="32dp"
app:chipSpacingVertical="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/detailText"
app:singleSelection="true">
<com.google.android.material.chip.Chip
android:id="#+id/chip_program"
style="#style/Widget.MaterialComponents.Chip.Choice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Program"
app:chipEndPadding="16dp"
app:chipStartPadding="16dp" />
<com.google.android.material.chip.Chip
android:id="#+id/chip_normal"
style="#style/Widget.MaterialComponents.Chip.Choice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/program_normal"
app:chipEndPadding="16dp"
app:chipStartPadding="16dp" />
</com.google.android.material.chip.ChipGroup>
Just set an attribute app:chipBackgroundColor and pass a color state list to it:
<android.support.design.chip.Chip
android:id="#+id/test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkable="true"
android:clickable="true"
android:focusable="true"
app:chipBackgroundColor="#color/bg_chip_state_list"
app:chipText="Test" />
bg_chip_state_list looks like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/colorSecondaryLight" android:state_checked="true" />
<item android:color="#color/colorPrimaryDark" />
</selector>
However I also had to set android:clickable to true to make this work
Using a ColorStateList is a proper way.
The only thing I want to add is using custom defined style much more clear to read especially if you want to customise a bunch of properties.
Among other things, one common style applied to all views allows you to make changes in one place that apply immediately to all views
styles.xml
<style name="CustomChipChoice" parent="#style/Widget.MaterialComponents.Chip.Choice">
<item name="chipBackgroundColor">#color/background_color_chip_state_list</item>
<item name="android:textColor">#color/text_color_chip_state_list</item>
</style>
text_color_chip_state_list.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
android:color="#color/color_checked" />
<item android:state_checked="false"
android:color="#color/color_unchecked" />
</selector>
background_color_chip_state_list.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/color1" android:state_checked="true" />
<item android:color="#color/color2" />
</selector>
After that all you need is apply your custom style for all the Chip views like this.
<android.support.design.chip.Chip
android:layout_width="wrap_content"
android:layout_height="match_parent"
style="#style/CustomChipChoice"
android:checkable="true"
android:clickable="true"
android:focusable="true"
android:text="Chip text" />
To change the colors in the Chip you can use a custom style:
<com.google.android.material.chip.Chip
style="#style/My_Widget.MaterialComponents.Chip.Choice"
../>
With this style:
<style name="My_Widget.MaterialComponents.Chip.Choice" parent="Widget.MaterialComponents.Chip.Choice">
<!-- Chip background color selector -->
<item name="chipBackgroundColor">#color/my_choice_chip_background_color</item>
<!-- Border color -->
<item name="chipStrokeColor">#color/primaryDarkColor</item>
<!-- Chip text color selector -->
<item name="android:textColor">#color/mtrl_choice_chip_text_color</item>
<!-- Chip close icon color selector -->
<item name="closeIconTint">#color/mtrl_chip_close_icon_tint</item>
</style>
For the chipBackgroundColor you can use a selector like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 24% opacity -->
<item android:alpha="0.24" android:color="#color/custom" android:state_enabled="true" android:state_selected="true"/>
<item android:alpha="0.24" android:color="#color/secondaryDarkColor" android:state_enabled="true" android:state_checked="true"/>
<!-- 12% of 87% opacity -->
<item android:alpha="0.10" android:color="#color/primaryLightColor" android:state_enabled="true"/>
<item android:alpha="0.12" android:color="#color/colorPrimary"/>
</selector>
For the text color you can use something like:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/colorAccent" android:state_enabled="true" android:state_selected="true"/>
<item android:color="?attr/colorPrimary" android:state_enabled="true" android:state_checked="true"/>
<!-- 87% opacity. -->
<item android:alpha="0.87" android:color="?attr/colorOnSurface" android:state_enabled="true"/>
<!-- 38% of 87% opacity. -->
<item android:alpha="0.33" android:color="?attr/colorOnSurface"/>
</selector>
Result for normal/selected state:
For those using alpha-05, I found that state_checked was being ignored on the filterable (parent="Widget.MaterialComponents.Chip.Filter") Chips. Instead, you need state_selected:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/apricot" android:state_selected="true"/>
<item android:color="#color/apricotSubtle"/>
</selector>
As others mentioned, you need to set the background color property of the chip element to a ColorStateList that you define. But I just wanted to point out an important note on how to do that since I ran into issues getting the different states to work.
When defining your own ColorStateList (xml resource) you need to make sure you set the different state options in the ColorStateList BEFORE the default color! This was tripping me up for a few days before I figured it out, so I hope this helps someone else as well.
Also, your chip needs to be clickable and focusable (checkable didn't work for me) so set these properties to true as well.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"
android:color="#color/chipColorLight" />
<item android:color="#color/chipColorDefault"/>
</selector>
If you want to programmatically set different ColorStateOptions you can do that like so:
binding.myChip.chipBackgroundColor = resources.getColorStateList(R.color.chip_color_state_list)
Somehow changing android:textColor in styles doesn't work for me. I have to change the chip's text color programmatically (as I also create chips programmatically).
val chip = Chip(context)
// Apply custom MyChipChoice style to the chip
val drawable = ChipDrawable.createFromAttributes(context!!, null, 0, R.style.MyChipChoice)
chip.setChipDrawable(drawable)
// Apply text color to the chip
val colorStateList = ContextCompat.getColorStateList(context!!, R.color.my_choice_chip_text_color)
chip.setTextColor(colorStateList)
If you are creating the Chip items in code use a state list like mentioned above and the following methods (in Java of course):
chip.setClickable(true);
chip.setCheckable(true);
chip.setChipBackgroundColor(getColorStateList(R.color.chip_background_color));
chip.setCheckedIconVisible(false);
Note: getColorStateList requires minSdkVersion to be 23 in the build.gradle script.
Check out this...
<com.google.android.material.chip.ChipGroup
android:id="#+id/chipGroupFilter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="#style/Theme.MaterialComponents.Light.DarkActionBar"
app:selectionRequired="true"
app:singleLine="true"
app:singleSelection="true">
<com.google.android.material.chip.Chip
android:id="#+id/chipAll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="All"
android:checkable="true"
android:clickable="true"
android:focusable="true"
app:chipBackgroundColor="#color/bg_chip_state_list"
app:checkedIconEnabled="false"
android:textColor="#color/whiteBlackSwitchColor"
app:chipIcon="#drawable/ic_all"
app:chipIconTint="#4D4F55"
app:chipIconVisible="true" />
</com.google.android.material.chip.ChipGroup>
So you can use the setChipBackgroundColor(ColorStateList cl) method to set the color of your chip and then you can add an setOnClickListener(new ...) to toggle with selection and non-selection like the following code:
yourchip.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (((Chip)v).getChipBackgroundColor().equals(getResources().getColorStateList(R.color.colorPrimaryDark,null))) {
((Chip)v).setChipBackgroundColor(getResources().getColorStateList(R.color.colorPrimary, null));
} else {
((Chip) v).setChipBackgroundColor(getResources().getColorStateList(R.color.colorPrimaryDark, null));
}
}
});
where i have used colorPrimaryDark for selection and colorPrimary for non-selection.

KitKat xml selector applying wrong color based on state

I'm having an issue specific to Kitkat devices and lower, the code works exactly as expected on newer versions of Android. I'm styling a button using a selector, on Kitkat the color of the button is grey (#color/button_disabled_color), but on newer version the color is blue (?attr/colorPrimary). Can't Kitkat use the state correctly or is there something else going wrong here?
The selector looks like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/button_disabled_color" android:state_enabled="false" />
<item android:color="?attr/colorPrimary"/>
</selector>
The button is defined in xml as follows:
<android.support.v7.widget.AppCompatButton
android:id="#+id/buttonStandard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/standard_button"/>
The default button style is specified like below, note this style is set as the default style for buttons in the theme.
<style name="AppTheme.ButtonStyle" parent="Widget.AppCompat.Button.Colored">
<item name="backgroundTint">#color/primary_button_color</item>
<item name="android:textColor">#color/primary_button_text_color</item>
</style>
Note that it works fine for the textColor which is done in the exact same way. changing the ?attr/colorPrimary to an actual color specified in the colors.xml also made no difference.
Add selector like ..
square_blue.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:exitFadeDuration="#android:integer/config_mediumAnimTime">
<item android:state_pressed="true" android:drawable="#drawable/square_blue_pressed"/>
<item android:drawable="#drawable/square_blue_normal"/>
</selector>
square_blue_pressed.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/light_blue" />
</shape>
square_blue_normal.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/dark_blue" />
</shape>
in layout xml
<android.support.v7.widget.AppCompatTextView
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="20dp"
android:background="#drawable/square_blue"
android:text="#string/standard_button"/>

Selected tab's color in Bottom Navigation View

I'm adding a BottomNavigationView to a project, and I would like to have a different text (and icon tint) color for the selected tab (to achieve greying out non-selected tabs effect). Using a different color with android:state_selected="true" in a color selector resource file doesn't seem to work. I also tried having additional item entries with android:state_focused="true" or android:state_enabled="true", no effect unfortunately. Also tried setting the state_selected attribute to false (explicitly) for the default (non-selected) color, with no luck.
Here is how I add the view to my layout:
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemBackground="#color/silver"
app:itemIconTint="#color/bnv_tab_item_foreground"
app:itemTextColor="#color/bnv_tab_item_foreground"
app:menu="#menu/bottom_nav_bar_menu" />
Here is my color selector (bnv_tab_item_foreground.xml):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#android:color/darker_gray" />
<item android:state_selected="true" android:color="#android:color/holo_blue_dark" />
</selector>
And my menu resource (bottom_nav_bar_menu.xml):
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/action_home"
android:icon="#drawable/ic_local_taxi_black_24dp"
android:title="#string/home" />
<item
android:id="#+id/action_rides"
android:icon="#drawable/ic_local_airport_black_24dp"
android:title="#string/rides"/>
<item
android:id="#+id/action_cafes"
android:icon="#drawable/ic_local_cafe_black_24dp"
android:title="#string/cafes"/>
<item
android:id="#+id/action_hotels"
android:icon="#drawable/ic_local_hotel_black_24dp"
android:title="#string/hotels"/>
</menu>
I would appreciate any help.
While making a selector, always keep the default state at the end, otherwise only default state would be used. You need to reorder the items in your selector as:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="#android:color/holo_blue_dark" />
<item android:color="#android:color/darker_gray" />
</selector>
And the state to be used with BottomNavigationBar is state_checked not state_selected.
1. Inside res create folder with name color (like drawable)
2. Right click on color folder. Select
new-> color resource file-> create color.xml file (bnv_tab_item_foreground)
(Figure 1: File Structure)
3. Copy and paste bnv_tab_item_foreground
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
app:itemBackground="#color/appcolor"//diffrent color
app:itemIconTint="#color/bnv_tab_item_foreground" //inside folder 2 diff colors
app:itemTextColor="#color/bnv_tab_item_foreground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/navigation" />
bnv_tab_item_foreground:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="#color/white" />
<item android:color="#android:color/darker_gray" />
</selector>
Figure 1: File Structure:
BottomNavigationView uses colorPrimary from the theme applied for the selected tab and it uses android:textColorSecondary for the inactive tab icon tint.
So you can create a style with the prefered primary color and set it as a theme to your BottomNavigationView in an xml layout file.
styles.xml:
<style name="BottomNavigationTheme" parent="Theme.AppCompat.Light">
<item name="colorPrimary">#color/active_tab_color</item>
<item name="android:textColorSecondary">#color/inactive_tab_color</item>
</style>
your_layout.xml:
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
android:theme="#style/BottomNavigationTheme"
app:menu="#menu/navigation" />
If you want to change icon and text colors programmatically:
ColorStateList iconColorStates = new ColorStateList(
new int[][]{
new int[]{-android.R.attr.state_checked},
new int[]{android.R.attr.state_checked}
},
new int[]{
Color.parseColor("#123456"),
Color.parseColor("#654321")
});
navigation.setItemIconTintList(iconColorStates);
navigation.setItemTextColor(iconColorStates);
I am using a com.google.android.material.bottomnavigation.BottomNavigationView (not the same as OP's) and I tried a variety of the suggested solutions above, but the only thing that worked was setting app:itemBackground and app:itemIconTint to my selector color worked for me.
<com.google.android.material.bottomnavigation.BottomNavigationView
style="#style/BottomNavigationView"
android:foreground="?attr/selectableItemBackground"
android:theme="#style/BottomNavigationView"
app:itemBackground="#color/tab_color"
app:itemIconTint="#color/tab_color"
app:itemTextColor="#color/bottom_navigation_text_color"
app:labelVisibilityMode="labeled"
app:menu="#menu/bottom_navigation" />
My color/tab_color.xml uses android:state_checked
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/grassSelected" android:state_checked="true" />
<item android:color="#color/grassBackground" />
</selector>
and I am also using a selected state color for color/bottom_navigation_text_color.xml
Not totally relevant here but for full transparency, my BottomNavigationView style is as follows:
<style name="BottomNavigationView" parent="Widget.Design.BottomNavigationView">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">#dimen/bottom_navigation_height</item>
<item name="android:layout_gravity">bottom</item>
<item name="android:textSize">#dimen/bottom_navigation_text_size</item>
</style>
It's too late to answer but might be helpful for someone.
I was doing a very silly mistake, I was using a selector file named as bottom_color_nav.xml for Select and unselect color change but still it was not reflecting any color change in BottomNavigationView.
Then I realize, I was returning false in onNavigationItemSelected method. It will work fine if you'll return true in this method.
In order to set textColor, BottomNavigationView has two style properties you can set directly from the xml:
itemTextAppearanceActive
itemTextAppearanceInactive
In your layout.xml file:
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bnvMainNavigation"
style="#style/NavigationView"/>
In your styles.xml file:
<style name="NavigationView" parent="Widget.MaterialComponents.BottomNavigationView">
<item name="itemTextAppearanceActive">#style/ActiveText</item>
<item name="itemTextAppearanceInactive">#style/InactiveText</item>
</style>
<style name="ActiveText">
<item name="android:textColor">#color/colorPrimary</item>
</style>
<style name="InactiveText">
<item name="android:textColor">#color/colorBaseBlack</item>
</style>
Try using android:state_enabled rather than android:state_selected for the selector item attributes.
This will work:
setItemBackgroundResource(android.R.color.holo_red_light)
Instead of creating selector,
Best way to create a style.
<style name="AppTheme.BottomBar">
<item name="colorPrimary">#color/colorAccent</item>
</style>
and to change the text size, selected or non selected.
<dimen name="design_bottom_navigation_text_size" tools:override="true">11sp</dimen>
<dimen name="design_bottom_navigation_active_text_size" tools:override="true">12sp</dimen>
Enjoy Android!
As the folder structure has changed, the tab_color.xml belongs to res > drawable now which can handle selectors. From there on the accepted solution works.

Android checkbox is not visible well in black background prob

I want make a list of Checkbox with white text in black background. We are using following code:
CheckBox chkAdditionalPack = new CheckBox(MainActivity.this);
chkAdditionalPack.setTag(j);
chkAdditionalPack.setText(offerPackageListForAddl.get(j).getOfferPackageName().toString());
chkAdditionalPack.setTextColor(Color.WHITE);
It gives a view like below:
The problem is now boxes of checkboxes is not clearly visible. How can I make it clearly visible keeping intact other parts?
If you are using android-studio, select your checkbox, and in the properties, set 'buttonTint' property value to whatever color you want using the editor. Or, if you prefer the XML solution, use
android:buttonTint="#color/white"
Note: This assumes that the color white is defined.
try the below xml code ref from solution
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_checked="true"
android:drawable="#drawable/cbchk_blue"
android:state_focused="false" >
</item>
<item
android:state_checked="true"
android:drawable="#drawable/cbchk_blue"
android:state_focused="true" >
</item>
<item
android:state_checked="false"
android:drawable="#drawable/cbunchk_blue"
android:state_focused="false" >
</item>
<item
android:state_checked="false"
android:drawable="#drawable/cbunchk_blue"
android:state_focused="true" >
</item>
</selector>
One really simple way to do it, within the xml for the checkbox, simply set the android:background variable to the colour you wish.
Instead of having the text and check box created together like this, simply create a custom list item layout xml file.
e.g custom_list_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#000000"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
/>
</LinearLayout>
Simply use this :
android:buttonTint="#FFFFFF"
** replace #FFFFFF with any color

Drawable selector not working in Jelly Bean

I have a drawable selector as a background for each item in a ListView to highlight the selected row. Eveything works fine in Ice Cream Sandwich, but doesn't seem to work in Jelly Bean. Can't find any documentation saying what changes could have caused it to stop working and what I need to do to fix it.
By not working, I mean when I click on a row in the ListView the item's background color isn't turning the #color/blue color, but it does in ICS.
This is the selector code I'm using (listing_selector.xml):
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_focused="true" android:drawable="#color/blue" />
<item android:state_pressed="true" android:drawable="#color/blue" />
<item android:state_activated="true" android:drawable="#color/blue_selected" />
<item android:state_selected="true" android:drawable="#color/blue_selected" />
<item android:drawable="#android:color/transparent" />
</selector>
This is the layout of the ListView item:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:background="#color/listing_selector"
>
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
/>
</RelativeLayout>
This the blue color resource:
<resources>
<color name="blue">#ff33b5e5</color>
</resources>
UPDATE 1:
Tried moving the selector from the color folder to the drawable folder and updating the code to this:
android:background="#drawable/listing_selector"
UPDATE 2:
Also, on the ListView, tried adding this:
<ListView android:id="#android:id/list"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:listSelector="#drawable/listing_selector"
/>
UPDATE 3:
I thought it might be something in my code, but I removed all the code from onListItemClick of the ListView and still the selector isn't working.
UPDATE 4:
I've narrowed it down to state_selected or state_activated not working as, state_pressed seems to be working
UPDATE 5:
I think I was mistaken. I don't think the selector is being recognized, at all. I was confusing the built-in ListView highlighting as my selector. I'm now wondering if it has something to do with the way my project is setup. I have the selector in a Library Class. Maybe something changed with that from ICS to JB, however moving the selector to my app's project didn't seem to fix it.
UPDATE 6:
Ok, after some more hair pulling, I've narrowed it down, again, to either state_selected or state_activated not being recognized, as changing the color for state_pressed does work, which means my selector is being recognized. From the comments in seems to be something with my app specifically as others have been able to get selectors working with Jelly Bean.
Though something else that is interesting is that changing the drawable value for the default state is not recognized. Where I have color/transparent, I would think changing that to a color would cause the listing to change to that color, but it doesn't.
Also, this isn't working in ICS either.
UPDATE 7:
After even more hair pulling, I've discovered that long-pressing on a menu item results in that item's color being changed. Just clicking on an item still does not work. Not even sure what the means.
** Final Update:**
I give up, I removed the selector and am just refreshing the ListView on click and remembering the position clicked and highlighting it from code. Not ideal, but not worth the effort to try to fix.
Okay, i think its an issue with your selector. Try removing the state_focused and the state_activated. You could try this for your selector:
<!-- Disabled State -->
<item
android:state_enabled = "false"
android:state_focused = "true"
android:state_pressed = "true"
android:drawable="#android:color/transparent">
</item>
<item
android:state_enabled = "false"
android:state_focused = "true"
android:drawable="#android:color/transparent">
</item>
<!-- Pressed State -->
<item
android:state_pressed = "true"
android:state_focused = "true">
<shape>
<solid android:color="#color/blue"/>
</shape>
</item>
<item
android:state_pressed = "true"
android:state_focused = "false">
<shape>
<solid android:color="#color/blue"/>
</shape>
</item>
<!-- Normal State -->
<item
android:drawable="#android:color/transparent">
</item>
I found that I needed to use a shape object too instead of android:drawable, because on pre-ICS phones, the whole list will be highlighted that color instead of the pressed list item.
You can add in your state_selected code too, but I'm not sure how it will be used. Check out the default selector code for jelly bean for the states they use: list_selector_background.xml.
listing_selector.xml must be in res/drawable folder and set the android:background attribute of your RelativeLayout like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:background="#drawable/listing_selector"
>
I cant say the reason why its working in one version and not working in another, but I got a alternative solution.
Define your color as a drawable in resources
<?xml version="1.0" encoding="utf-8"?>
<resources>
<drawable name="blue">#00F</drawable>
...
</resources>
Use this color drawable in your selector
<?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/blue" />
...
...
</selector>
Try this and let me know.
From the API Docs:
Note: Remember that Android applies the first item in the state list
that matches the current state of the object. So, if the first item in
the list contains none of the state attributes above, then it is
applied every time, which is why your default value should always be
last (as demonstrated in the following example).
Thus, try to reorder the states of your selectors according to the suggested order. In your case that would be this:
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="#color/blue" />
<item android:state_focused="true" android:drawable="#color/blue" />
<item android:state_selected="true" android:drawable="#color/blue_selected" />
<item android:state_activated="true" android:drawable="#color/blue_selected" />
<item android:drawable="#android:color/transparent" />
</selector>
I think it works fine !!
your selector xml file code:-
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/gray" android:state_focused="true"/>
<item android:drawable="#color/gray" android:state_pressed="true"/>
<item android:drawable="#color/orange" android:state_activated="true"/>
<item android:drawable="#color/orange" android:state_selected="true"/>
<item android:drawable="#color/orange"/>
</selector>
now create a folder values-v16 under res folder and put this colors file in it.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="gray">#4f4f4f</color>
<color name="orange">#e26c0e</color>
</resources>
and then the listview :
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="20dp"
android:listSelector="#drawable/listing_selector" >
</ListView>
Hope this works ! Tested on version 4.1
This is a very old question but I am still supporting Jellybean and I've noticed for background selectors to work I need to do something in particular. If I have a viewgroup with a background drawable and I need selector colors on it I need to do things in this order:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/my_drawable_button"/>
my_drawable_button must now reference a selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/primary_background_pressed"
android:state_pressed="true" />
<item android:drawable="#drawable/primary_background"
android:state_enabled="true" />
<item android:drawable="#drawable/primary_background_disabled"
android:state_enabled="false" />
</selector>
primary_background.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="8dp" />
<solid android:color="#color/secondary" />
</shape>
The others are the same with different colors. This is an awful lot of code to do something very basic, but I have found on Jellybean it's the only solution.
Future API levels allow you to specify the color selector on the drawable solid itself, eliminating 4 files:
post api 21:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/purple">
<item>
<shape android:shape="rectangle">
<corners android:radius="8dp" />
<solid android:color="#color/button_selector" />
</shape>
</item>
</ripple>
button_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/gray" android:state_enabled="false"/>
<item android:color="#color/secondary"/>
</selector>

Categories

Resources