I have a spinner like the image below;
How can I remove the gap on the left x between the spinner and its dropdown - preferably a solution that works on API8 as I am trying to keep my app requirements as low as possible.
I had assumed this would be layout_margin in the spinners style, but after reading this question it seems thats not possible.
In my theme I have;
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:dropDownListViewStyle">#style/DropDownStyle</item>
<item name="android:dropDownSelector">#style/DropDownStyle</item>
</style>
<style name="DropDownTopStyle">
<item name="android:clickable">true</item>
<item name="android:background">#drawable/dropdowntop</item>
</style>
<style name="DropDownStyle">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:layout_marginLeft">0dp</item>
<item name="android:layout_margin">0dp</item>
<item name="android:clickable">true</item>
<item name="android:background">#drawable/dropdownback</item>
<item name="android:popupBackground">#drawable/dropdownback</item>
<item name="android:cacheColorHint">#FFF000</item>
</style>
Thanks,
Thomas
Additional;
I can see there might be a way to make a popup myself in code - if this is necessary, can I somehow get to the adapters popup view? (that is the list that it displays). Trying to recreate the whole adapters behavior from scratch seems a terrible way to go - but if I can get to that view and disable the normal popup behavior, then I could make my own popup without the annoying offset.
Seems you need to extend the Spinner View to make your own AlertDialog that shows the list of items, or in newer version (API 16+) you can use
android:dropDownHorizontalOffset="-8dp"
check the full details here: How to change the position of opened spinner?
Is what you want something like this?
If so, here is the code (works until API level 9) :
Activity:
public class MainActivity extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner spinnerListOptions = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<CharSequence> adapterListOptions = ArrayAdapter.createFromResource(this, R.array.string_array,
R.layout.spinner_item_top);
adapterListOptions.setDropDownViewResource(R.layout.spinner_item_dropdown);
spinnerListOptions.setAdapter(adapterListOptions);
}
}
spinner_item_top.xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="29dp"
android:textSize="12sp"
android:gravity="center">
</TextView>
spinner_item_dropdown.xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="29dp"
android:textSize="12sp"
android:gravity="center">
</TextView>
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Spinner
android:id="#+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
strings.xml:
<resources>
<string-array name="string_array">
<item>item 1</item>
<item>item 2</item>
<item>item 3</item>
</string-array>
</resources>
Try this, This should work
<style name="DropDownStyle">
<item name="android:layout_width">0dp</item>
I dont know it is possible, because all view item like Spinner, EditText, etc... are small images in the android SDK. You should check, is there any default padding in the 9patched SDK image, if yes, I think you cant do it.
Also, don`t forget to check the base Spinner class in Android sourcode, maybe there are some trick.
Related
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 am writing an application that SDK 10+. I would like all of my check boxes in my Activities as well as my PreferenceActivity to look the same. I created a Theme that has a Theme.Black parent. I created a child style of android:Widget.CompoundButton.CheckBox and set the android:checkboxStyle to that child theme. I have applied my theme across the entire app in the application manifest element with:
android:theme="#style/AppTheme"
When I look at the main Activity, the check box style has been applied as expected, but the checkbox in the PreferenceActivity does not have the style. My questions are:
Is it possible to style minor parts of preferences without having to specify an entire new layout for each one?
More generally, I would like to do this for other controls that show up in the preferences, like toggles or switches. Is that possible? (My guess is that the solution to one will pretty much be able to be applied to those particular issues as well)
I know there is an issue for nested preferences, but this question is applicable to Preferences at the top level. Any help is greatly appreciated. I have been banging my head against a wall on this one for a couple hours now...
Here is what I have so far:
prefs.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<CheckBoxPreference
android:key="checkbox1"
android:summary="This is a themed checkbox preference"
android:title="Checkbox 1" />
</PreferenceScreen>
ThemedPreferenceActivity.java
public class ThemedPreferencesActivity extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<CheckBox
android:id="#+id/checkBox1"
android:text="CheckBox"
android:checked="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" style="#style/AppTheme.Preference.Checkbox" />
</LinearLayout>
MainActivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
style.xml
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="android:Theme.Black">
<item name="android:checkboxStyle">#style/AppTheme.Preference.Checkbox</item>
</style>
<style name="AppTheme.Preference.Checkbox" parent="android:Widget.CompoundButton.CheckBox">
<item name="android:button">#drawable/pref_checkbox</item>
<item name="android:background">#FF0000</item>
</style>
</resources>
pref_checkbox.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="true" android:drawable="#android:drawable/ic_menu_call" />
<item android:state_checked="false" android:drawable="#android:drawable/ic_menu_camera" />
</selector>
Looks like the issue was with the line:
<style name="AppTheme.Preference.Checkbox" parent="android:Widget.CompoundButton.CheckBox">
<item name="android:button">#drawable/pref_checkbox</item>
<item name="android:background">#FF0000</item> <---- RIGHT HERE
</style>
Looks like specifying that was causing the check box to misbehave. Turns out that I didn't need that anyway (and in fact, realized I would do it in the "ListView" style anyway if I wanted it) so, problem solved.
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.
I have defined a style for Linear layout but the layout is not visible in graphical view of main.xml
main.xml.
<LinearLayout style="VerticalThemeLayoutInputs">
styles.xml
<resources>
<style name="VerticalThemeLayoutInputs">
<item name="android:background">#6699FF</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item>
</style>
</resources>
Edit:
But below code will work fine but I don't want this code
<LinearLayout
android:background="#6699FF"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
Interesting Fact
I used a scrollview. Within that I placed many Linear layout. Layouts properties are almost same so I decided to have a style for that. But what is happening know? the layout is not visible only in graphical-view but it works fine in emulator.
But actually what is happening? I think its due to Scroll view.
I think what you want is style="#style/VerticalThemeLayoutInputs".
E.g.
<LinearLayout
style="#style/VerticalThemeLayoutInputs">
main.xml in res/layout/:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/VerticalThemeLayoutInputs"
>
</LinearLayout>
styles.xml in res/values/:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<style name="VerticalThemeLayoutInputs">
<item name="android:background">#6699FF</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:orientation">horizontal</item>
<item name="android:gravity">center_vertical</item>
</style>
</resources>
onCreate method in activity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
...
<item name="android:layout_marginTop">#dimen/margin_top</item>
remove this tag and check.. this seems to be an invalid one.. and in main.xml add style="#style/VerticalThemeLayoutInputs" just like the above answer given by steve
Are you sure from that the style.xml located in Value folder NOT in Ar/EN/..
because he called the default in the first "value\style.xml "
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: