How to customize a Spinner in Android
Asked Answered
I

6

174

I want to add a custom height to the dropdown of a Spinner, say 30dp, and I want to hide the dividers of the dropdown list of Spinner.

So far I tried to implement following style to the Spinner:

<style name="spinner_style">
        <item name="android:paddingLeft">0dp</item>
        <item name="android:dropDownWidth">533dp</item>
        <item name="android:showDividers">none</item>
        <item name="android:dividerHeight">0dp</item>
        <item name="android:popupBackground">@drawable/new_bg</item>
        <item name="android:dropDownHeight">70dp</item>
        <item name="android:scrollbarAlwaysDrawVerticalTrack">true</item>
        <item name="android:dropDownSelector">@android:color/white</item>
 </style>

and the code of my spinner is :

<Spinner
            android:id="@+id/pioedittxt5"
            android:layout_width="543dp"
            android:layout_height="63dp"
            android:layout_toRightOf="@+id/piotxt5"
            android:background="@drawable/spinner"
            style="@style/spinner_style"
            android:dropDownVerticalOffset="-53dp"
            android:spinnerMode="dropdown"
            android:drawSelectorOnTop="true"
            android:entries="@array/travelreasons"
            android:prompt="@string/prompt" />

But nothing seems to be working.

Interleave answered 22/5, 2013 at 14:42 Comment(8)
stephenpengilley.blogspot.com/2013/01/… custom-android-dn.blogspot.com/2012/12/…Decurrent
None of the style is applied ? popupBackGround or anything else ? Strange.Addia
@Decurrent : i already tried those examples .. i want to adjust height of the dropdown listInterleave
@shree202 : no style appliesInterleave
@Interleave see this youtube.com/watch?v=JX9RmLAoOUY&feature=g-uplWesleyanism
You have "style=" don't you want "android:style="Henrique
@Henrique , it's not an Android style, but a custom one he created. That's why he has just "style="Frowzy
There are main steps to fully customize the default Spinner. Step 01 - Create a layout Step 02 - Create an Adapter Step 03 - Create drawables Finally marge all the elements. Here is the complete guide : dailycoding.in/android-custom-spinnerSadi
F
215

Create a custom adapter with a custom layout for your spinner.

Spinner spinner = (Spinner) findViewById(R.id.pioedittxt5);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
        R.array.travelreasons, R.layout.simple_spinner_item);
adapter.setDropDownViewResource(R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);

R.layout.simple_spinner_item

<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@android:id/text1"
    style="@style/spinnerItemStyle"
    android:maxLines="1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ellipsize="marquee" />

R.layout.simple_spinner_dropdown_item

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@android:id/text1"
    style="@style/spinnerDropDownItemStyle"
    android:maxLines="1"
    android:layout_width="match_parent"
    android:layout_height="?android:attr/dropdownListPreferredItemHeight"
    android:ellipsize="marquee" />

In styles add your custom dimensions and height as per your requirement.

 <style name="spinnerItemStyle" parent="android:Widget.TextView.SpinnerItem">

  </style>

  <style name="spinnerDropDownItemStyle" parent="android:TextAppearance.Widget.TextView.SpinnerItem">

  </style>
Feeney answered 20/6, 2013 at 12:10 Comment(7)
I tried using the styles options that you suggested. But it is not working for me! I added: <item name="android:height"> 40sp </item> <item name="android:textSize">15sp</item> in between the spinnerItemStyle tag but of no use. Could you please help me out as the default spinner size is too small!Detached
Try changing <item name="android:height"> to <item name="android:layout_height">Feeney
thanx for replying.. tried but to no effect... working on it on/off for last 3-4 days.. Just getting irritated now :(Detached
Actually you are using an array to populate the spinner.. What i have done is populated the spinner with an array of objects by implementing the toString() method in the class of which the custom array of objects belong. So i can't use the create from resource.. what i have to do is create a custom adapter but i am trying to avoid it. I want to do it so that it is applicable in the entire application without the need for custom adapter for all spinners as i have too many spinners in the application.Detached
@Tarun, Don't you need android:id="@+android:id/text1" in the simple_spinner_dropdown_item.xml file?Friseur
In R.layout.simple_spinner_dropdown_item, change android:layout_height value to "?attr/dropdownListPreferredItemHeight" or you will get an error: "Error: Attribute is not public"Careaga
For future visitors to this answer: do not wrap TextView and CheckedTextview inside a layout. Post it directly in your layout_file.xml file. I was stuck here for some hours until I found what was the mistake.Estellaestelle
T
115

You can create fully custom spinner design like as

Step1: In drawable folder make background.xml for a border of the spinner.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/transparent" />
<corners android:radius="5dp" />
<stroke
android:width="1dp"
   android:color="@android:color/darker_gray" />
</shape>

Step2: for layout design of spinner use this drop-down icon or any image drop.png enter image description here

 <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginRight="3dp"
    android:layout_weight=".28"
    android:background="@drawable/spinner_border"
    android:orientation="horizontal">

    <Spinner
        android:id="@+id/spinner2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_gravity="center"
        android:background="@android:color/transparent"
        android:gravity="center"
        android:layout_marginLeft="5dp"
        android:spinnerMode="dropdown" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_gravity="center"
        android:src="@mipmap/drop" />

</RelativeLayout>

Finally looks like below image and it is everywhere clickable in round area and no need to write click Lister for imageView.

enter image description here

Step3: For drop-down design, remove the line from Dropdown ListView and change the background color, Create custom adapter like as

Spinner spinner = (Spinner) findViewById(R.id.spinner1);
String[] years = {"1996","1997","1998","1998"};
ArrayAdapter<CharSequence> langAdapter = new ArrayAdapter<CharSequence>(getActivity(), R.layout.spinner_text, years );
langAdapter.setDropDownViewResource(R.layout.simple_spinner_dropdown);
mSpinner5.setAdapter(langAdapter);

In layout folder create R.layout.spinner_text.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layoutDirection="ltr"
android:id="@android:id/text1"
style="@style/spinnerItemStyle"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:paddingLeft="2dp"
/>

In layout folder create simple_spinner_dropdown.xml

<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="@style/spinnerDropDownItemStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp"
android:singleLine="true" />

In styles, you can add custom dimensions and height as per your requirement.

<style name="spinnerItemStyle" parent="android:Widget.TextView.SpinnerItem">
</style>

<style name="spinnerDropDownItemStyle" parent="android:TextAppearance.Widget.TextView.SpinnerItem">
</style>

Finally looks like as

enter image description here

According to the requirement, you can change background color and text of drop-down color by changing the background color or text color of simple_spinner_dropdown.xml

Tat answered 16/6, 2016 at 12:35 Comment(9)
in the first code snipped do you mean android:height="1dp" in line 6?Ney
By mistake two times write android:width = "1dp"Tat
No problem, I just didn't want to edit it myself because I was not sure, if you wanted to specify to height with "1dp" or if it was just a duplicate. good answer though. :)Ney
@BineshKumar Hey may I know where you declared CheckedTextView? Because when I pasted in the code, it told me the element must be declared firstRamentum
No need to declare because it in the part of androidTat
Man, you could have used names in your layouts and drawables, I have spend half an hour and still no clue what to do. Minus for bad answer.Cavalry
what is "@drawable/spinner_border" referring to ?Beater
its easier to put it as github, i could not make it work , sorry am android beginner, i wish some one willDeclassify
You have to define your own ArrayAdapter, so you can inflate the RelativeLayout. More details here codinginflow.com/tutorials/android/custom-spinnerBozeman
L
25

The most elegant and flexible solution I have found so far is here: http://android-er.blogspot.sg/2010/12/custom-arrayadapter-for-spinner-with.html

Basically, follow these steps:

  1. Create custom layout xml file for your dropdown item, let's say I will call it spinner_item.xml
  2. Create custom view class, for your dropdown Adapter. In this custom class, you need to overwrite and set your custom dropdown item layout in getView() and getDropdownView() method. My code is as below:

    public class CustomArrayAdapter extends ArrayAdapter<String>{
    
    private List<String> objects;
    private Context context;
    
    public CustomArrayAdapter(Context context, int resourceId,
         List<String> objects) {
         super(context, resourceId, objects);
         this.objects = objects;
         this.context = context;
    }
    
    @Override
    public View getDropDownView(int position, View convertView,
        ViewGroup parent) {
        return getCustomView(position, convertView, parent);
    }
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      return getCustomView(position, convertView, parent);
    }
    
    public View getCustomView(int position, View convertView, ViewGroup parent) {
    
    LayoutInflater inflater=(LayoutInflater) context.getSystemService(  Context.LAYOUT_INFLATER_SERVICE );
    View row=inflater.inflate(R.layout.spinner_item, parent, false);
    TextView label=(TextView)row.findViewById(R.id.spItem);
     label.setText(objects.get(position));
    
    if (position == 0) {//Special style for dropdown header
          label.setTextColor(context.getResources().getColor(R.color.text_hint_color));
    }
    
    return row;
    }
    
    }
    
  3. In your activity or fragment, make use of the custom adapter for your spinner view. Something like this:

    Spinner sp = (Spinner)findViewById(R.id.spMySpinner);
    ArrayAdapter<String> myAdapter = new CustomArrayAdapter(this, R.layout.spinner_item, options);
    sp.setAdapter(myAdapter);
    

where options is the list of dropdown item string.

Latini answered 13/10, 2014 at 2:43 Comment(2)
The trick for me was overriding getDropDownView, I was overriding getView, but didn't realized I had to override that method.Nodarse
How do I change the background color of the spinner? Because if I change the background color of R.layout.spinner_item it does change the background color, but the dropdown arrow and its surroundings stay in the "old" color.Exude
E
10

Try this

i was facing lot of issues when i was trying other solution...... After lot of R&D now i got solution

  1. create custom_spinner.xml in layout folder and paste this code

     <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorGray">
    <TextView
    android:id="@+id/tv_spinnervalue"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textColor="@color/colorWhite"
    android:gravity="center"
    android:layout_alignParentLeft="true"
    android:textSize="@dimen/_18dp"
    android:layout_marginTop="@dimen/_3dp"/>
    <ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:background="@drawable/men_icon"/>
    </RelativeLayout>
    
  2. in your activity

    Spinner spinner =(Spinner)view.findViewById(R.id.sp_colorpalates);
    String[] years = {"1996","1997","1998","1998"};
    spinner.setAdapter(new SpinnerAdapter(this, R.layout.custom_spinner, years));
    
  3. create a new class of adapter

    public class SpinnerAdapter extends ArrayAdapter<String> {
    private String[] objects;
    
    public SpinnerAdapter(Context context, int textViewResourceId, String[] objects) {
        super(context, textViewResourceId, objects);
        this.objects=objects;
    }
    
    @Override
    public View getDropDownView(int position, View convertView, @NonNull ViewGroup parent) {
        return getCustomView(position, convertView, parent);
    }
    
    @NonNull
    @Override
    public View getView(int position, View convertView, @NonNull ViewGroup parent) {
        return getCustomView(position, convertView, parent);
    }
    
    private View getCustomView(final int position, View convertView, ViewGroup parent) {
        View row = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_spinner, parent, false);
        final TextView label=(TextView)row.findViewById(R.id.tv_spinnervalue);
        label.setText(objects[position]);
        return row;
    }
    }
    
Electroacoustics answered 20/5, 2017 at 11:29 Comment(1)
This gave me the men_icon image on all items after clicking on the spinner, which wasn't what I was looking for. If you don't want the men_icon image (or other customizations) to appear on all rows after clicking on the spinner, then remove the "getDropDownView" override.Phemia
N
2

This worked for me :

ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),R.layout.simple_spinner_item,areas);
            Spinner areasSpinner = (Spinner) view.findViewById(R.id.area_spinner);
            areasSpinner.setAdapter(adapter);

and in my layout folder I created simple_spinner_item:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
// add custom fields here 
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
android:paddingRight="?android:attr/listPreferredItemPaddingRight" />
Novikoff answered 17/5, 2016 at 15:20 Comment(0)
L
0

I have build a small demo project on this you could have a look to it Link to project

Liquefacient answered 5/4, 2020 at 5:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.