Android中Spinner组件的使用解析

Android中Spinner组件的使用解析

1,Spinner概述

Spinner是ViewGroup类得一个子孙类,其继承关系如下:

View--->ViewGroup--->AdapterView--->AbsSpinner--->Spinner

默认情况下Spinner显示的是当前选中的元素值,当每次点击Spinner时,都会弹出菜单列表供用户选择,从该菜单列表中可以为Spinner选择一个新的元素值.


2,Spinner的简单用法

在activity_spinner_demo1.xml中添加Spinner控件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Spinner
        android:id="@+id/spinner1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:entries="@array/languages" />
</LinearLayout>

其中android:entries="@array/languages"表示Spinner的数据集合是从资源数组languages中获取的,languages数组资源定义在values/arrays.xml中:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="languages">
        <item>c语言</item>
        <item>java </item>
        <item>php</item>
        <item>xml</item>
        <item>html</item>
    </string-array>
</resources>

SpinnerDemo1Activity中通过OnItemSelectedListener的回调方法实现响应Spinner选择事件:

/*
布局中获取数据源
 */
public class SpinnerDemo1Activity extends AppCompatActivity {
    protected Spinner spinner1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_spinner_demo1);
        initView();
    }

    private void initView() {
        //布局中获取数据源
        spinner1 = (Spinner) findViewById(R.id.spinner1);
        spinner1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String[] array = getResources().getStringArray(R.array.languages);
                Toast.makeText(SpinnerDemo1Activity.this, "选择了" + array[position], Toast.LENGTH_LONG).show();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
    }
}

运行结果如下图所示:


21.jpg

22.jpg

3,通过适配器的方式获取数据集合

使用这种方式来获取数据源,就不要在activity_spinner_demo2.xml布局中设置 android:entries="@array/languages" 属性了:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <Spinner
        android:id="@+id/spinner2"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:dropDownWidth="60dp"
        android:gravity="center"
        android:padding="10dp"
        android:spinnerMode="dropdown" />
</LinearLayout>

这里我们使用的适配器为ArrayAdapter,SpinnerDemo2Activity代码如下

        //实例化控件
        spinner2 = (Spinner) findViewById(R.id.spinner2);
        //创建数据适配器并绑定数据
        final ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.languages, android.R.layout.simple_spinner_item);
        spinner2.setAdapter(adapter);
        spinner2.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                CharSequence item = adapter.getItem(position);
                Toast.makeText(MainActivity.this, "---->" + item, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

4,使用自定义的BaseAdapter获取数据集合

这种情况适用于Spinner的选择条目比较复杂的情况,比如带有图标.
首先activity_spinner_mode_dropdown.xml布局放置控件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <Spinner
        android:dropDownVerticalOffset="40dp"
        android:dropDownHorizontalOffset="10dp"
        android:spinnerMode="dropdown"
        android:id="@+id/spinner3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:dropDownWidth="wrap_content"
        android:gravity="center"
        android:padding="10dp"
         />
</LinearLayout>

SpinnerDemo3Activity中:

public class SpinnerDemo3Activity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        int mode = getIntent().getIntExtra("mode", Spinner.MODE_DROPDOWN);
        if (mode == Spinner.MODE_DROPDOWN) {
            setContentView(R.layout.activity_spinner_mode_dropdown);
        } else {
            setContentView(R.layout.activity_spinner_mode_dialog);
        }
        //使用自定义的BaseAdapter
        Spinner spinner3 = (Spinner) findViewById(R.id.spinner3);
        final List<Person> persons = new ArrayList<Person>();
        persons.add(new Person("张三", "上海 "));
        persons.add(new Person("李四", "上海 "));
        persons.add(new Person("王五", "北京"));
        persons.add(new Person("赵六", "广州 "));
        //  建立Adapter绑定数据源
        MyAdapter pAdapter = new MyAdapter(this, persons);
        spinner3.setAdapter(pAdapter);
        spinner3.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(SpinnerDemo3Activity.this, "--->" + persons.get(position).getName() + "--" + persons.get(position).getCity(), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
    }
}

实体对象Person:

public class Person {

    private String name;
    private String city;
    public Person() {
    }

    public Person(String name,String city) {
        super();
        this.name = name;
        this.city = city;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
}

MyAdapter:

public class MyAdapter extends BaseAdapter {

    private List<Person> mPersons;

    public MyAdapter(Context context, List<Person> persons) {
        mPersons = persons;
    }

    @Override
    public int getCount() {
        return mPersons == null ? 0 : mPersons.size();
    }

    @Override
    public Object getItem(int position) {
        return mPersons.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        ViewHolder viewHolder = null;
        if (convertView == null) {
            convertView = layoutInflater.inflate(R.layout.item_spinner_person, null);
            viewHolder = new ViewHolder(convertView);
            convertView.setTag(viewHolder);
        }else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.tvName.setText(mPersons.get(position).getName());
        viewHolder.tvCity.setText(mPersons.get(position).getCity());
        return convertView;
    }

    static class ViewHolder {
        protected TextView tvName;
        protected TextView tvCity;

        ViewHolder(View rootView) {

            initView(rootView);
        }

        private void initView(View rootView) {
            tvName = (TextView) rootView.findViewById(R.id.tv_name);
            tvCity = (TextView) rootView.findViewById(R.id.tv_city);
        }
    }
}

item_spinner_person.xml菜单条目:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal">
    <ImageView
        android:src="@mipmap/ic_launcher_round"
        android:layout_width="30dp"
        android:layout_height="30dp" />
    <TextView
        android:id="@+id/tv_name"
        android:layout_marginLeft="10dp"
        android:text="张三"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_city"
        android:layout_marginLeft="10dp"
        android:text="上海"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

运行效果:


2345截图20180107132407.jpg

5,Spinner的菜单显示方式

Spinner有两种显示形式,一种是下拉菜单,一种是弹出框,菜单显示形式是spinnerMode属性决定的:

android:spinnerMode="dropdown"
android:spinnerMode="dialog"

以上用的都是下拉菜单的显示,我们接下来看看弹出框的显示,只需将SpinnerDemo3Activity中的布局使用activity_spinner_mode_dialog.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <Spinner
        android:spinnerMode="dialog"
        android:id="@+id/spinner3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:dropDownWidth="match_parent"
        android:gravity="center"
        android:padding="10dp"
        android:prompt="@string/dialog_title"
         />
</LinearLayout>

其运行效果如下:


002.jpg

6,Spinner的常用其他xml属性汇总:

entries: 直接在xml布局文件中绑定数据源
android:entries="@array/languages"
prompt:在Spinner弹出选择对话框的时候对话框的标题
android:prompt="@string/dialog_title"
dropDownVerticalOffset:
spinnerMode=”dropdown”时,下拉的项目选择窗口在垂直方向相对于Spinner窗口的偏移量
android:dropDownVerticalOffset="40dp"
对应代码中的方法:
public void setDropDownVerticalOffset(int pixels){}
dropDownWidth:
在spinnerMode=”dropdown”时,设定下拉框的宽度
android:dropDownWidth="wrap_content"
对应代码中的方法:
public void setDropDownWidth(int pixels) {}
dropDownSelector:
用于设定spinnerMode=”dropdown”时列表选择器的显示效果
popupBackground:设置下拉框背景色
android:popupBackground="@drawable/bg_d_sp_spinner"
对应代码中的方法:
public void setPopupBackgroundResource(int resId) { }


7,自定义Spinner下三角样式

隐藏下三角:
1,自己写一个xml背景不带小图标,把原来的背景替换掉

<Spinner
        android:id="@+id/spinner3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="@drawable/bg_d_sc_spinner_no_icon"
        android:dropDownHorizontalOffset="10dp"
        android:dropDownVerticalOffset="40dp"
        android:dropDownWidth="wrap_content"
        android:gravity="center"
        android:spinnerMode="dropdown" />

bg_d_sc_spinner_no_icon.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <layer-list>
            <item>
                <shape>
                    <padding android:bottom="3dp" android:right="3dp" />
                </shape>
            </item>

        </layer-list>
    </item>

2,只需将spinner的背景设置为透明即可

<Spinner
        android:id="@+id/spinner3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="@android:color/transparent"
        android:drawableEnd="@mipmap/ic_launcher_round"
        android:drawableRight="@mipmap/ic_launcher_round"
        android:dropDownHorizontalOffset="10dp"
        android:dropDownVerticalOffset="40dp"
        android:dropDownWidth="wrap_content"
        android:gravity="center"
        android:spinnerMode="dropdown" />

运行效果如下图:


001.jpg

自定义一个下三角或者其他图标:
自己写一个xml背景带小图标,把原来的背景替换掉

<Spinner
        android:id="@+id/spinner3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/bg_d_sc_spinner"
        android:dropDownWidth="wrap_content"
        android:spinnerMode="dropdown" />

bg_d_sc_spinner.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <layer-list>
            <item>
                <shape>
                    <padding android:bottom="3dp" android:right="3dp" />
                </shape>
            </item>
            <item>
                <bitmap android:gravity="right" android:src="@mipmap/ic_find_next_holo_light" />
            </item>
        </layer-list>
    </item>
</selector>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容