I'm trying to create a theme for my first Android app, and it is driving me round the bend. I finally managed to figure out how to style items in a dropdown list, but now I can't change the colour of the divider between list items. I have searched similar questions on stackoverflow, and tried dozens of combinations, but nothing seems to work.
Here is my styles.xml file (abbreviated for clarity):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyTheme" parent="android:Theme.Light">
<item name="android:spinnerStyle">#style/spinnerStyle</item>
<item name="android:spinnerDropDownItemStyle">#style/spinnerDropDownItemStyle</item>
<item name="android:dropDownListViewStyle">#style/spinnerListViewStyle</item>
</style>
<style name="spinnerStyle" parent="#android:style/Widget.Spinner">
<item name="android:background">#drawable/my_theme_spinner</item>
</style>
<style name="spinnerDropDownItemStyle" parent="#android:style/Widget.DropDownItem.Spinner">
<item name="android:background">#drawable/my_theme_spinner_item</item>
<item name="android:paddingLeft">5dp</item>
<item name="android:gravity">center_vertical</item>
</style>
<style name="spinnerListViewStyle" parent="#android:style/Widget.ListView.DropDown">
<item name="android:height">3dp</item>
<item name="android:dividerHeight">3dp</item>
<item name="android:divider">#color/divider</item>
</style>
</resources>
No matter what I do, I just get a 1dp light grey divider between items (which can barely be seen with my light coloured list item background) - neither the height nor colour of the divider is ever affected (I also tried setting it to a drawable, also with no effect). What am I doing wrong?
I have a very simple Activity with the Spinner and it works for the following. The only difference I see is that you have a <item name="android:height">3dp</item> and I don't have that at all.
<style name="TestSpinnerStyle" parent="android:style/Widget.ListView.DropDown">
<item name="android:divider">#ff0000</item>
<item name="android:dividerHeight">5dp</item>
</style>
<style name="SampleTheme" parent="#android:style/Theme.Holo.Light">
<item name="android:dropDownListViewStyle">#style/TestSpinnerStyle</item>
</style>
and in my Activity I have:
Spinner spinner = (Spinner) findViewById(R.id.spinner);
List<String> list = new ArrayList<String>();
list.add("list 1");
list.add("list 2");
list.add("list 3");
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, list);
dataAdapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
spinner.setAdapter(dataAdapter);
and then for the main layout I have the following XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, StylingActivity"
/>
<Spinner android:id="#+id/spinner"
android:layout_width="250dp"
android:layout_height="40dp"
/>
</LinearLayout>
Here is the screenshot
If you can't get it to work from there, I can push up the entire thing to a github repo for you.
You could add a horizontal line to the dropdown layout you use, which would effectively create a divider.
EDIT
Some further searching found this:
SO Answer
Which basically says what you show you are trying to do above should work... although it mentions setting that style in your activity theme and you don't mention doing that.
You can do it in your layout.xml
<Spinner
android:id="#+id/sp_to_create"
android:layout_width="match_parent"
android:layout_height="32dp"
android:layout_marginBottom="10dp"
style="#style/spinner_style"
android:prompt="#string/to_type_prompt" />
XML STYLES ADD it
<style name="spinner_style" parent="Widget.AppCompat.ListView.DropDown">
<item name="android:divider">#d1d1d1</item>
<item name="android:dividerHeight">0.5dp</item>
</style>
Add to your Activity Theme
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:dropDownListViewStyle">#style/spinner_style</item>
</style>
JAVA FILE
your_spinnerList.setAdapter(new ArrayAdapter<>(getActivity(), android.R.layout.simple_dropdown_item_1line, timeOff_type_list));
Let me know if it had been useful for you! Have a nice day!
The style method in the accepted answer works well until you need two spinners with different divider colors.
Here is what I found works as an alternative:
a) Set the popupBackgroundColor attribute on the spinner to the color you want for the divider. This will color the entire list item's background (including the space we think of as the divider).
b) Set the spinners adapters dropDownViewResource to be a CheckedTextView with it's background attribute set to some other color (or a selector if you want the selected items to have a different color). This will override the color we set in step a for everything but the divider. effectively giving us the desired result.
So you will have:
drawable/spinner_dropdown_background_selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/your_unchecked_color" android:state_checked="false"/>
<item android:drawable="#color/your_checked_color" android:state_checked="true"/>
<item android:drawable="#color/your_unchecked_color"/>
</selector>
layout/drop_down_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:background="#drawable/spinner_dropdown_background_selector"
android:textColor="#android:color/white"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee" />
Your spinner definition:
<Spinner
...
android:popupBackground="#color/your_divider_color"
...
/>
And finally your array adapter definition:
ArrayAdapter<String> dataAdapter = new ...
dataAdapter.setDropDownViewResource(android.R.layout.drop_down_item);
spinner.setAdapter(dataAdapter);
Please note that setting the popupBackgroundColor has no effect if the spinner is in dialog mode.
Related
I'm using android databinding and as part of that, I have a spinner with items (array declared in strings.xml) as
android:entries="#string/items"
Now I would like to change the text color and size of the dropdown items.
I want to do this with out creating a separate layout for item and using it through java (passing the item layout to array adapter and setting that adapter to the spinner).
I tried many ways and searched everywhere but didn't find appropriate solution.
Any help is appreciated.
You should use android.support.v7.widget.AppCompatSpinner.
<android.support.v7.widget.AppCompatSpinner
style="#style/Widget.AppCompat.Spinner.Underlined"
android:theme="#style/Spinner"
android:entries="#array/special_fx_arrays"
android:textSize="#dimen/text_size_normal"/>
Here the style to put in styles.xml
<style name="Spinner" parent="Widget.AppCompat.Light.DropDownItem.Spinner">
<item name="android:paddingStart">0dp</item>
<item name="android:paddingEnd">0dp</item>
<item name="android:textColor">#color/white</item>
<item name="android:backgroundTint">#color/red</item>
<item name="android:textSize">14sp</item>
</style>
You can create a style and set it to spinner through xml
<style name="customStyle" parent="#android:style/Widget.Holo.DropDownItem.Spinner">
<item name="android:textColor">#000</item>
<item name="android:textSize">12dp</item>
</style>
set customStyle to your spinner
Just create a new xml with a textview and its properties:
my_spinner.xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textColor="#f51111"
/>
Luego set el nuevo xml en el ArrayAdapter:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.my_spinner,data);
spinner.setAdapter(adapter);
I have a searchview with a content provider for custom suggestions, which are displayed in a dropdown. However, the dropdown background is dark while the text is black so it's not very visible. My app theme is inheriting from Theme.AppCompat.Light so everything else in my app is black text on a light background.
I want to change the background of the dropdown so the text is readable but I haven't found any way of doing so. The closest I got was following the solution here: Style Android SearchView Drop down popup
But when the dropdown appears, stuff looks messed up.
Is there any working solution for this?
Applying styles you can change the dropdown background color and the items text color and size
<!-- ToolBar -->
<style name="ToolBarStyle" parent="Theme.AppCompat">
<item name="android:textColorPrimary">#android:color/white</item>
<item name="android:textColorSecondary">#android:color/white</item>
<item name="actionMenuTextColor">#android:color/white</item>
<item name="android:dropDownItemStyle">#style/myDropDownItemStyle</item>
<item name="android:dropDownListViewStyle">#style/myDropDownListViewStyle</item>
</style>
<style name="myDropDownItemStyle" parent="Widget.AppCompat.DropDownItem.Spinner">
<item name="android:textColor">#color/secondary_text_default_material_light</item>
<item name="android:textSize">14dp</item>
</style>
<style name="myDropDownListViewStyle" parent="Widget.AppCompat.ListView.DropDown">
<item name="android:background">#FFF</item>
</style>
Here's one possibility.
Define a query suggestion row layout, e.g. R.layout.li_query_suggestion, that looks like this:
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="#android:id/text1"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:gravity="center_vertical"
android:minHeight="56dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:textColor="#android:color/black"
tools:text="Blah blah blah"/>
Notice that the background color is white and the text color is black. You can, of course, change these values.
Then, in your cursor adapter, specify the layout you created as the row layout. E.g.:
CursorAdapter suggestionAdapter = new SimpleCursorAdapter(
getActivity(),
R.layout.li_query_suggestion,
null,
new String[]{"name"},
new int[]{android.R.id.text1},
0);
This will give you something that looks like the following:
Just fyi, my current theme looks like this:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
<item name="colorPrimary">#color/light_blue_500</item>
<item name="colorPrimaryDark">#color/light_blue_700</item>
<item name="colorAccent">#color/pink_a200</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="searchViewStyle">#style/CustomSearchView</item>
</style>
i think you should use
SearchView.SearchAutoComplete autoCompleteTextView = (SearchView.SearchAutoComplete) searchView.findViewById(R.id.search_src_text);
if (autoCompleteTextView != null) {
autoCompleteTextView.setDropDownBackgroundDrawable(getResources().getDrawable(R.drawable.abc_popup_background_mtrl_mult));
}
this can set the SearchAutoComplete dropdown background to Light
Simple solution
int autoCompleteTextViewID = getResources().getIdentifier("search_src_text", "id", getPackageName());
mSearchAutoCompleteTextView = mSearchView.findViewById(autoCompleteTextViewID);
mSearchAutoCompleteTextView.setDropDownBackgroundResource(R.color.white);
PROBLEM
I've tried to change the select highlight in my application but with no luck.
I've been doing it via styles because I have quite a lot of them in my app.
I would be grateful if you have told me what is wrong with my code.
CODE
<style name="AppTheme" parent="android:Theme.Holo.Light">
<item name="android:actionBarStyle">#style/MyActionBar</item>
<item name="android:actionOverflowButtonStyle">#style/MyActionBar</item>
<item name="android:imageButtonStyle">#style/MyImgBtn</item>
<item name="android:spinnerDropDownItemStyle">#style/mySpinnerItemStyle</item>
<item name="android:spinnerStyle">#style/MySpinnerTheme</item>
<item name="android:windowBackground">#android:color/white</item>
</style>
<style name="MySpinnerTheme" parent="android:Widget.Holo.Light.Spinner">
<item name="android:activatedBackgroundIndicator">#drawable/custom_activated_background</item>
</style>
UPDATE
So I've managed to merge two selectors with setting style on setDropDownViewResource layout element. But what I get at the moment are two selectors appearing at the same time.
I've tried to set android:dropDownSelector="#android:color/transparent" on Spinner in XML but still no luck. Posting more code below.
SPINNER
final Spinner yearSpinner = (Spinner) rootView.findViewById(R.id.yearSpinner);
ArrayAdapter<SpinnerItem> adapterYear = new ArrayAdapter<SpinnerItem>(getActivity(),
R.layout.spinner_item_layout , yearsItems);
yearSpinner.setOnItemSelectedListener(itemSelectedListener);
yearSpinner.setAdapter(adapterYear);
<Spinner
android:id="#+id/yearSpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:dropDownSelector="#android:color/transparent"
android:layout_below="#id/yearTxt"
android:layout_marginLeft="20dp"
android:popupBackground="#drawable/podpowiedzi"
android:layout_marginRight="20dp"
android:layout_centerHorizontal="true"
>
</Spinner>
SPINNER_ITEM_LAYOUT
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
style="#style/mySpinnerItemStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:ellipsize="marquee"
android:singleLine="true"
android:textStyle="italic"
android:textAlignment="inherit"
android:textColor="#color/text_color"
>
</TextView>
To change the style and colours of your spinner drop down items add the following to your style.xml
<style name="mySpinnerItemStyle" parent="#style/android:Theme.Holo">
<item name="android:background">#drawable/spinner_selector</item>
<item name="android:gravity">center_vertical</item>
</style>
And then create the "spinner_selector.xml" in your drawable folder:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="true" android:drawable="#color/orange" /> <!-- current selected -->
<item android:state_pressed="true" android:drawable="#color/orange_bright" />
<item android:drawable="#android:color/transparent" />
</selector>
If you want to custom highlight colour when you press on the spinner, we need 9 patch images for spinner backgrounds. Do the following steps:
1) visit this website:http://android-holo-colors.com/, select Spinner, select the colour you want for your spinner highlight and download the zip file. (there are many other options depends on your app)
2) In the zip file open res-->drawable and save file "apptheme_spinner_background_holo_light.xml" to your drawable folder
3) save the following images in the right drawable folders:
apptheme_spinner_default_holo_light.9.png
apptheme_spinner_disabled_holo_light.9.png
apptheme_spinner_focused_holo_light.9.png
apptheme_spinner_pressed_holo_light.9.png
4) add this to your style.xml file:
<style name="MySpinnerTheme" parent="#android:Widget.Holo.Light.Spinner">
<item name="android:background">#drawable/apptheme_spinner_background_holo_light</item>
</style>
In future, you can auto generate any style you want with all the resources required (including spinner highlight colour) thr this website:
http://android-holo-colors.com/
I have successfully styled spinner background like here: How to set font custom font to Spinner text programmatically?
My opened spinner looks like this:
Only thing that is left to style is spinner prompt box (and text inside). How can i change background color and font of spinner prompt?
EDIT:Based on 2red13 advice i created style:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="spinner_style">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
<item name="android:background">#8b4513</item>
</style>
and aplied it to spinner like this:
<Spinner
android:id="#+id/spinner"
style="#style/spinner_style"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:prompt="#string/header_prompt"
android:background="#drawable/spinaca"
android:layout_margin="5dip"/>
But nothing has changed. I guess i don't understand something :(
the style is defined here:
style="?android:attr/spinnerItemStyle"
you have to build your own style and set it instaed of the above
I using listviews and expandedviews that has dividers and I can set them but on spinner its looks like it is no divider between items.
Someone that has a idea of how to fix this?
This worked for me:
<style name="SpinnerStyle" parent="Widget.AppCompat.ListView.DropDown">
<item name="android:divider">#d1d1d1</item>
<item name="android:dividerHeight">0.5dp</item>
</style>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="android:dropDownListViewStyle">#style/SpinnerStyle</item>
The advantage of using this is that it doesn't remove the ripple effect on hover.
I managed to find a more proper solution for this issue (without including the divider in the single item layout).
What you have to do is define in your activity's theme
<item name="android:dropDownListViewStyle">#style/App.Style.Spinner</item>
and then create the proper style with
<style name="App.Style.Spinner" parent="#style/Widget.Sherlock.Light.ListView.DropDown">
<item name="android:dividerHeight">10dip</item>
<item name="android:divider">#drawable/mydivider</item>
</style>
Based on #Talihawk answer, I made it work for specific spinner only. Instead of setting your activity theme, set the theme directly for the spinner view:
<style name="MatchSpinnerStyle" parent="android:style/Widget.ListView.DropDown">
<item name="android:divider">#123456</item>
<item name="android:dividerHeight">1dp</item>
</style>
<style name="MatchSpinnerTheme" parent="AppTheme">
<item name="android:dropDownListViewStyle">#style/MatchSpinnerStyle</item>
</style>
and
<android.support.v7.widget.AppCompatSpinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/MatchSpinnerTheme"/>
Sorry, I am answering years after the question was asked but the solution is very simple, you just have to do a simple thing.
Go to your style.xml file and add this item in your active theme
<item name="android:dropDownListViewStyle">#style/MySpinner</item>
after this add another theme with the name MySpinner and same parent of your active theme
<style name="MySpinner" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:dividerHeight">2dp</item>
<item name="android:divider">#000</item>
</style>
this will separate your single item and will not show the separator while we hover on a single item
but be sure while doing this, we are applying this theme on all the spinner in the activity. Now after every spinner is will work on this same spinner theme.
For people with same problem i after almost gived up i got an idea of how to get the divider.
I added the divider line at the bottom of my custom layout for each item
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="#+id/RelativeLayout01"
android:layout_width="fill_parent" android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android" style="#style/ListItem2">
<TextView android:id="#+id/Text" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_alignParentLeft="true"
style="#style/SpinnerView_Text" android:paddingLeft="10dip" />
<ImageView android:id="#+id/icon" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:src="#drawable/arrowright"
android:layout_alignParentRight="true" android:layout_centerInParent="true"
android:layout_marginRight="20dip" />
</RelativeLayout>
<ImageView android:id="#+id/Divider1" android:layout_width="fill_parent"
android:layout_height="1dip" style="#style/Divider"></ImageView>
None of the other solutions worked for me, so I used a drawable as the background of the Spinner items to produce the desired effect.
I have created a new Drawable dropdown_divider.xml and a custom SpinnerAdapter class where I adapted the getDropDownView() method to set the background to the Spinner items.
The android:bottom="-56dp" in the drawable is what centers the line perfectly between two items for me, but that depends on the exact margins and paddings that you've applied in your layout.
dropdown_divider.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:left="16dp"
android:right="16dp"
android:bottom="-56dp">
<shape android:shape="line" >
<stroke
android:width=".2dp"
android:color="#FF666666" />
</shape>
</item>
</layer-list>
SpinnerAdapter:
#Override
public View getDropDownView(int position, View convertView,
#NonNull ViewGroup parent) {
TextView text = (TextView) super.getDropDownView(position, convertView, parent);
text.setBackground(context.getDrawable(R.drawable.dropdown_divider));
label.setTextColor(Color.BLACK);
label.setText(lists.get(position).getTitle());
return text;
}
The result looks like this: