I use a spinner to display a dropdown list.
I want to have the items in the list to have rounded corners.
So I use 9-patch containing an image with rounded corners (transparent on the outside of the corners) for the views items background and a selector to display a different color 9-patch when pressed.
Problem: When I press the items in the spinner's list, I can see a blue background in the corners, where the 9-patch is transparent.
I can't seem to get rid of this blue background that appears when the items are pressed. If I remove the 9-patches and any setting in the spinner, I can see that the items views in the list are by default grey, and blue when pressed.
I tried also to not use 9 patches as the background but just a color selector, and set the pressed color in the selector to be transparent. Then when I press the item, it's not transparent, but blueish. I think the view in the list is really transparent, but there is still the blue color in the background when pressed...
I use a custom SpinnerAdapter to create the items view.
Here is the simplified code:
private class MySpinnerAdapter implements SpinnerAdapter {
#Override
public View getDropDownView(int i, View recycledView, ViewGroup viewGroup) {
View view = new View(context);
view.setBackground(context.getResources().getDrawable(R.drawable.testspinner));
view.setMinimumHeight(100);
return (View) view;
}
}
The selector used for the background. Here with just a color, and no 9-patch. The pressed color should be transparent:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:drawable="#android:color/transparent" />
<item
android:drawable="#android:color/holo_purple" />
</selector>
I set the custom adapter on the spinner:
spinner.setAdapter(new MySpinnerAdapter());
And the spinner is fetched from XML layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent" android:layout_height="wrap_content">
<Spinner
android:id="#+id/myDropDown"
android:spinnerMode="dropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:dropDownWidth="match_parent"/>
</LinearLayout>
I have tried setting many different attributes on the Spinner, and tried some styling attributes, but I could not get rid of this blue background...
Thank you #Vikram for pointing out the use of styles.
However, after investigations it turns out that the background of the pressed item in the Spinner doesn't come from the attribute you suggested, but from android:listSelector. So I could fix the problem like this:
Define a new style in styles.xml:
<style name="MyListView">
<item name="android:listSelector">#android:color/transparent</item>
</style>
Define a new theme in themes.xml:
<style name="MyTheme" parent="#android:style/Theme.NoTitleBar.Fullscreen">
<item name="android:dropDownListViewStyle">#style/MyListView</item>
</style>
Apply the theme to my activity in AndroidManifest.xml:
<activity android:name=".MyActivity"
...
android:theme="#style/MyTheme">
Problem: When I press the items in the spinner's list, I can see a
blue background in the corners, where the 9-patch is transparent.
I think the blue background comes from android:selectableItemBackground attribute. To change this attribute, add the following to your application's theme in styles.xml:
<item name="android:selectableItemBackground">#drawable/whicheverDrawable</item>
For reference: By default, selectableItemBackground points to the following drawable in API 19 (for Theme.Holo). You should define whicheverDrawable in a similar way:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
<item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="#drawable/list_selector_disabled_holo_dark" />
<item android:state_focused="true" android:state_enabled="false" android:drawable="#drawable/list_selector_disabled_holo_dark" />
<item android:state_focused="true" android:state_pressed="true" android:drawable="#drawable/list_selector_background_transition_holo_dark" />
<item android:state_focused="false" android:state_pressed="true" android:drawable="#drawable/list_selector_background_transition_holo_dark" />
<item android:state_focused="true" android:drawable="#drawable/list_focused_holo" />
<item android:drawable="#color/transparent" />
</selector>
In your case, you can define rounded corners for another drawable, which is used for statePressed in whicheverDrawable.
Related
So I have a listview in my app and it seems that the AppTheme value "colorControlHighlight" changes the colors for ripple and onclick row in that listview to (blue). However I made a listview with identical xml attributes that relate to color on a widget and for some reason the ripple and on press colors are still the default color (white). If I change the android:listselector attribute for the listview on my widget, it works but it doesn't act the same and the ripple effect is gone. How it acts; after I change listselector it stays blue unless I press a different row on the list. This is not what I want (is this because i haven't set onclick actions yet? or is this how that attribute is designed to work?). Any help would be appreciated.
This is my app activity listview
<ListView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="#+id/AppUrlList"
android:background="#color/dark_black"
android:layout_gravity="center_horizontal"
android:dividerHeight="1px"
android:divider="#color/faded_blue"
android:clickable="true"
/>
now this is my widget listview
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:dividerHeight="2px"
android:divider="#color/faded_blue"
android:background="#color/black"
android:id="#+id/WidgetListView"
android:layout_gravity="center_horizontal" />
now this is my apptheme
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="colorControlNormal">#color/faded_blue</item>
<item name="colorControlActivated">#color/bright_blue</item>
<item name="colorControlHighlight">#color/bright_blue</item>
thanks for the suggestions to improve my question i'm new here
I figured it out i had to do this:
app_list_item.xml
<TextView
android:id="#+id/AppListTextViewGreen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/List_Hint"
android:gravity="center"
android:background="#drawable/list_background_green"
style="#style/liststyleGreen"
/>
then in list_background_green.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="#color/faded_green" />
<item android:state_pressed="true" android:drawable="#color/faded_green"/>
<item android:drawable="#color/black" />
</selector>
the state_pressed is what defines the color when the list item is pressed (obviously)
and the default background is black.
this works on my widget whereas setting the default colors in the app theme did not change the colors in my widget.
EDIT: forgot to put the ripple selector here too, here it is, and i'll also include how to make it work on versions above api 21.
you have to name the ripple selector the same name as the list selector. so you would make another xml named "list_background_green" but put it in drawable-v21 folder. This folder probably won't exist so right click on res folder in android studio and click show in explorer, then create drawable-v21 folder and put the same named xml there. here is an example.
drawable-v21/list_background_green.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/bright_green">
<item>
<selector>
<item android:state_selected="true">
<color android:color="#color/transp_green" />
</item>
<item android:state_activated="true">
<color android:color="#color/transp_green" />
</item>
<item android:state_pressed="true">
<color android:color="#color/transp_green" />
</item>
<item>
<color android:color="#color/semi_trans_black" />
</item>
</selector>
</item>
you want to be careful how transparent you make this value.
<color android:color="#color/semi_trans_black" />
i couldn't figure out why the selector wasn't showing up for a while and then realized that if this value is too transparent it makes the ripple not show up. I can't explain why if someone can please do, just warning people because it took me a while to figure out that was the cause. That value is the default background for each textview in the list, so maybe the selectors inherit it's transparency although that doesn't make alot of sense. I only had to do this on my appwidget, for some reason beyond my current understanding. In my regular app listview i didn't need to do any of this. My suspicion is that widgets inherit their theme from the system but i'm not sure of this.
cheers, hope this helps someone.
I'm following this color scheme of Navigation View.
I created 3 selectors, for background, text and icon.
When I set the selectors, my navigation view looked like this:
The problem is that no item is shown selected and if I press one item, all items' background color changes to gray. Icon never gets the primary color.
Here is are the XMLs:
<android.support.design.widget.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#android:color/white"
app:itemTextColor="#drawable/nav_item_text"
app:itemIconTint="#drawable/nav_item_icon_tint"
app:itemBackground="#drawable/nav_item_background"
app:headerLayout="#layout/drawer_student_data_header"
app:menu="#menu/drawer"
android:id="#+id/navigationView"/>
nav_item_icon_tint.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#color/gray_600"/>
<item android:state_selected="true" android:color="#color/primary" />
<item android:color="#color/gray_600" />
</selector>
nav_item_text.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#color/black_87_percent"/>
<item android:state_selected="true" android:color="#color/primary" />
<item android:color="#color/black_87_percent" />
</selector>
nav_item_background.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="#color/gray_400"/>
<item android:state_selected="true" android:drawable="#color/gray_200" />
<item android:drawable="#android:color/white" />
</selector>
I've had a similar problem and looks like the way to solve it is to use android:state_checked instead of the android:state_selected in all three selectors (at least that solved it for me).
You can use setItemTextColor and setItemIconTintList for set text color tint and icon color tint to item of NavigationDrawer,
To use this methods add this code to end of onCreateView:
int[][] states = new int[][]{
new int[]{-android.R.attr.state_checked},// unchecked state
new int[]{android.R.attr.state_checked}, // checked state
};
int[] colors = new int[]{
ContextCompat.getColor(this, R.color.colorPrimary),
ContextCompat.getColor(this, R.color.colorPrimaryDark)
};
ColorStateList colorStateList = new ColorStateList(states, colors);
navigationView.setItemTextColor(colorStateList);
navigationView.setItemIconTintList(colorStateList);
This code set color to unchecked state and checked state. You can set color to other states.
Color array and state array should be have equals member count. You can select color whatever you want.
You can use Color class or like the sample use resource. In this link you can find list of available states developer.android.
Make sure you are not accessing the menu item from bottom navigation and setting its state to 'checked' twice. To avoid that, use:
mBottomNavigationView.selectedItemId(R.id.your_menu_item_id);
instead of
mBottomNavigationView.menu.getItem(position).setChecked(true);
I want to change the default color (blue) of a selected item in a Navigation Drawer in Android. I have gotten it to work in past projects, but I cannot in the project I am currently working on.
This is the app theme.
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="android:actionBarStyle">#style/AppTheme.ActionBar</item>
<item name="android:activatedBackgroundIndicator">#drawable/activated_background</item>
<item name="android:buttonStyle">#style/AppTheme.Button</item>
</style>
This is the activated_background drawable.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true" android:drawable="#drawable/list_selected"/>
<item android:state_selected="true" android:drawable="#drawable/list_selected"/>
<item android:state_pressed="true" android:drawable="#drawable/list_selected"/>
</selector>
Finally, this is the navigation drawer fragment.
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#cccc"
tools:context=".NavigationDrawerFragment" />
Like I said, this has worked for me before. The only difference between projects that I can think of is that before, my app theme was inherited from "Theme.AppCompat" and this project's theme is inherited from "android:Theme.Holo.Light.DarkActionBar". Also, I am using v4 support fragments in my new project, while as in the other project I was just using the standard fragment.
Any advice would be greatly appreciated. Thanks.
Edit:
Seems like the question is how to keep an item in a ListView selected, not actually how to set the resulting background of a selected item.
See this great answer for how change the background of a ListView item once it is selected:
Android - Keep ListView's item highlighted once one has been clicked
The basic idea is that when the item is tapped, you change it's background (or whatever else). The tricky part is you must have your List adapter remember the row that is selected. Otherwise when/if you scroll the list/navigation drawer, you'll lose the selection.
Original Answer:
You need to set a custom ListView style in AppTheme in which you set the android:listSelector item to #drawable/activated_background.
If you don't want that style for your entire app, just specify that style for the ListView in your application drawer layout, or even more simply just set the android:listSelector property of that ListView and don't even bother defining a style.
I figured it out. Instead of using my theme to try and apply the style, I just created my own xml layout for the list items instead of using the default and set the selector from there.
Here is what the list item xml looks like.
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:textColor="#drawable/list_txtcolor"
android:gravity="center_vertical"
android:paddingStart="?android:listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="#drawable/activated_background"
android:minHeight="?android:attr/listPreferredItemHeightSmall">
</TextView>
As you can see, I just set the item background to my selector.
android:background="#drawable/activated_background"
And again, here is my selector.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true" android:drawable="#drawable/list_selected"/>
<item android:state_selected="true" android:drawable="#drawable/list_selected"/>
<item android:state_pressed="true" android:drawable="#drawable/list_selected"/>
</selector>
I've created a list view and set up a selector for it so that it has a background on it. I did the same for the list item elements in it.
http://dl.dropbox.com/u/67419/list.png
The list itself is grey and has the dark grey border on the right side. When a list item is activated, I have the background of the list item changed to white via its own selector. However, I can't seem to get the white background to take up the entire space of the listview and it leaves a few pixels to the right (just enough to only show the border from the background). Is there a way to make it extend all of the way? To the right of the list is a white fragment so I want the white from the list item to connect to the white of the fragment.
my list_item_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_activated="true"
android:drawable="#color/white" />
<item android:state_selected="true"
android:drawable="#color/grey" />
<item android:state_pressed="true"
android:drawable="#color/grey" />
</selector>
and my list_selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/rightborder" />
</selector>
Have you tried: android:constantSize="true" in the selector attributes?
This is a pretty specific question. I have a spinner on an ActionBar that is added in the onCreate() method. I have been able to style the text white, but I can't get the underline and the triangle/arrow at the bottom right to appear as white. Here is my styling:
<item name="android:actionDropDownStyle">#style/customActionBarDropDownStyle</item>
<style name="customActionBarDropDownStyle" parent="android:style/Widget.Holo.Light.Spinner">
<item name="android:textColor">#FFFFFF</item>
</style>
I can't find a style item/property that makes the underline and triangle white. Does one exists?
Here's an example. I have highlighted in red the triangle and underline that I want to make white.
A bit late answer, but better than never :)
You should create a new 9 patch drawable and set it as a background to android:actionDropDownStyle.
here is an example:
<item name="android:actionDropDownStyle">#style/customActionBarDropDownStyle</item>
<style name="customActionBarDropDownStyle"parent="android:style/Widget.Holo.Light.Spinner">
<item name="android:background">#drawable/custom_spinner_dropdown</item>
</style>
You can't set a color to almost every native component, as their backgrounds are (in most cases) 9-patch pngs.
The actionDropDownStyle can not used to change the style of spinner you added on actionbar; its for one of the actionbar mode ActionBar.NAVIGATION_MODE_LIST;
As for your problem, you can define a selector for your spinner in the layout file,just like this:
enter code here
<Spinner
android:dropDownWidth="200dp"
android:background="#drawable/actionbar_spinner"
android:id="#+id/action_spinner"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="10dp" />
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:drawable="#drawable/spinner_ab_disabled" />
<item android:state_pressed="true"
android:drawable="#drawable/spinner_ab_pressed" />
<item android:state_pressed="false" android:state_focused="true"
android:drawable="#drawable/spinner_ab_focused" />
<item android:drawable="#drawable/spinner_ab_default" />
</selector>
Try this : android:background="#null"