【Android】下拉菜单Spinner控件的实现

Android开发中Spinner控件有多种建立方式,我总结下来有两类:静态方式和动态方式。动态方式又可以根据需求直接使用现成的适配器或者是自定义适配器(复杂对象)

静态方式

静态方式首先需要在values下新建一个xml文件,写入Spinner中的项目名称,如新建如下array.xml,写入名为sptype的数组。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="sptype">
        <item>type1</item>
        <item>type2</item>
        <item>type3</item>
        <item>type4</item>
    </string-array>
</resources>

静态有两种方式与控件进行绑定,第一种是在布局中直接添加entries属性。

<Spinner
            android:id="@+id/sp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:entries="@array/sptype"/>

另一种是通过适配器进行关联。

ArrayAdapter<CharSequence> adapter=ArrayAdapter.createFromResource(this, R.array.sptype, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spDataType.setAdapter(adapter);

动态方式

简单对象

动态方式直接在活动中进行建立List,再通过适配器与Spinner控件进行关联。

配置适配器

List<String> splist = new ArrayList<String>();
splist.add("type1");
splist.add("type2");
splist.add("type3");
splist.add("type4");
ArrayAdapter<String> adapter=new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, splist); 
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spDataType.setAdapter(adapter);

Spinner选择监听

当选择下拉菜单的某一项后,做出响应。

    private Spinner spDataType = null;

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

        spDataType = (Spinner)findViewById(R.id.sp);
		
		//...中间部分就是上面那些
		
		//监听实现
        spDataType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
                String[] dataType = getResources().getStringArray(R.array.sptype);
                Toast.makeText(DBViewActivity.this, "你点击的是:"+ pos + parent.getItemAtPosition(pos).toString(), Toast.LENGTH_SHORT).show();
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                // Another interface callback
            }
        });

自定义适配器(复杂对象)

但往往,我们需要放进下拉列表中的不仅仅是单个数据,可能还涉及复杂的对象,比如对于spinner的每个item需要展示编号、内容甚至是图像等。

简单定一个User

public class User{
	private Integer userId;
	private String userName;
	//... getter, setter等
}

Item布局

需要自己写一个容纳Item的布局文件,这里就简单放一下,具体的布局还是得自己设计一下,比如说GuidLine啊等等。

    <TextView
        android:id="@+id/tv_region_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:textStyle="bold"/>

    <TextView
        android:id="@+id/tv_region_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp" />

自定义适配器

public class MySpinnerAdapter extends BaseAdapter implements SpinnerAdapter {

    private List<User> users;
    private Context context;
    private LayoutInflater li;

    public MySpinnerAdapter(List<User> users,Context context) {
        this.users = users;
        this.context = context;
        this.li = LayoutInflater.from(context);
    }
 	
 	// 返回item总数
    @Override
    public int getCount() {
        return users.size();
    }

	// 按序号获取item
    @Override
    public Object getItem(int position) {
        return users.get(position);
    }

	// 按序号获取item的id
    @Override
    public long getItemId(int position) {
        return position;
    }

	// 按序号获取视图对象
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = View.inflate(context, R.layout.item_user_spinner, null);
            new ViewHolder(convertView);
        }
        //获取我们设置过的标签,实现复用convertView
        ViewHolder holder = (ViewHolder) convertView.getTag();
        //分别给每个控件设置相应的内容
        holder.userId.setText(String.valueOf(users.get(position).getUserId()));
        holder.userName.setText(users.get(position).getName());
        //返回convertView对象
        return convertView;
    }

    //新建ViewHolder内部类,用来定义我们行布局中所用到的控件
    class ViewHolder {
        TextView userId;
        TextView uesrName;


        public ViewHolder(View convertView){
            userId = (TextView) convertView.findViewById(R.id.tv_user_id);
            userName = (TextView) convertView.findViewById(R.id.tv_user_name);
            convertView.setTag(this);//set a viewholder
        }
    }

}

配置Spinner及适配器

private Spinner spinner;
private List<User> users = new ArrayList<>(); // 这里面加一堆的User对象

...

spinner = getView().findViewById(R.id.regionSpinner);

spinner.setAdapter(new RegionSpinnerAdapter(regions, getContext())); // 视当前所处空间的来决定传哪个Context,这里是fragment的context
//设置监听
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    //当item被选择后调用此方法
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, lon
        //获取我们所选中的内容
        String s = regions.get(position).getInfo();
        //弹一个Toast提示我们所选中的内容
        Toast.makeText(getContext(), s, Toast.LENGTH_SHORT).show();
    }
    
    //只有当patent中的资源没有时,调用此方法
    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }
});

获取当前item对象

User user = (User)spinner.getSelectedItem();
posted @ 2024-12-23 14:29  Zang998  阅读(789)  评论(0)    收藏  举报  来源