How to customize a Spinner in Android

2019-01-01 05:13发布

问题:

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.

回答1:

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>


回答2:

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

 <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

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

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



回答3:

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.



回答4:

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;
    }
    

    }



回答5:

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\" />