Android 自定义下拉列表

时间: 2023-07-11 admin IT培训

Android 自定义下拉列表

Android 自定义下拉列表

Android 下拉列表也是一个比较常用的控件,但是Android自带的下拉框样式效果较差,没办法,只好自己来自定义一个。其实主要是利用弹窗来实现的,看一下效果图先~~


我这边仅仅是实现简单的自定义控件,简单易懂,布局上有需要其他效果如边框、虚线等可自行加上。下拉列表是List,所以item也是可以根据需要进行内容上的丰富,修改适配器便可以。

好了,进入正题。首先,我们先创建一个标题及箭头布局,目的是用于点击后弹出下拉菜单。,代码如下所示:

接下来,创建下拉列表ListView布局,代码如下:
创建ListView,自然也要对应创建其Item的布局,代码如下:
接下来,我们来封装一个自定义控件MySpinerView,由于我没有去找向上箭头的图片资源,大家箭头自行替换。代码如下:
package com.newland.myspinerdemo;import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;import java.util.List;/*** 封装好的下拉列表,包括头部*/
public class MySpinerView extends LinearLayout implements View.OnClickListener, MySpinerAdapter.IOnItemSelectListener {private String mExampleString = "";private int mExampleColor = Color.RED;private float mExampleDimension = 0;private Context context;private RelativeLayout spiner;private TextView tvSpiner;private ImageView ivSpiner;private ListnameList;private MySpinerPopWindow mSpinerPopWindow;public MySpinerView(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;LayoutInflater.from(context).inflate(R.layout.sample_my_spiner_view, this);init(attrs, 0);spiner = (RelativeLayout) this.findViewById(R.id.spiner);spiner.setOnClickListener(this);tvSpiner = (TextView) this.findViewById(R.id.tv_spiner);ivSpiner = (ImageView) this.findViewById(R.id.iv_spiner);}/*** 设置弹出下拉表单的数据,在Activity那边得到控件后记得调用否则抛异常* @param nameList*/public void setData(ListnameList) {this.nameList = nameList;mSpinerPopWindow = new MySpinerPopWindow(context);mSpinerPopWindow.refreshData(nameList, 0);mSpinerPopWindow.setItemListener(this); // 设置下拉列表item点击的监听,响应onItemClick回调函数}/*** 头部点击事件* @param v*/@Overridepublic void onClick(View v) {switch (v.getId()){case R.id.spiner:showSpinWindow();break;}}/*** 弹出下拉列表*/public void showSpinWindow() {/**这里还有一步要做,就是让右边箭头向上。自己替换掉ivSpiner图片**/mSpinerPopWindow.setWidth(((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth());mSpinerPopWindow.showAsDropDown(tvSpiner);}/*** 下拉列表项点击事件,把选中的值显示在界面上* @param pos*/@Overridepublic void onItemClick(int pos) {/**这里还有一步要做,就是让右边箭头还原向下。自己替换掉ivSpiner图片**/if (pos >= 0 && pos <= nameList.size()) { // pos为-1就是弹窗消失,不管他String value = nameList.get(pos);tvSpiner.setText(value);}}/*** 初始化顶部显示数据* @param txt*/public void initText(String txt){tvSpiner.setText(txt);}
}
自定义控件创建完毕,点击后弹出的下拉列表。
下拉列表实际上是一个PopWindow,里面有一个ListView,所以我们新建一个自定义弹窗PopWindow。代码如下:
package com.newland.myspinerdemo;import java.util.List;import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.PopupWindow;/*** 下拉列表弹窗*/
public class MySpinerPopWindow extends PopupWindow implements OnItemClickListener {private Context mContext;private ListView mListView;private MySpinerAdapter mAdapter;private MySpinerAdapter.IOnItemSelectListener mItemSelectListener;public MySpinerPopWindow(Context context) {super(context);mContext = context;init();}/*** 为MySpinnerView提供一个item点击事件的监听器,MySpinnerView实例调用此方法设置监听* @param listener*/public void setItemListener(MySpinerAdapter.IOnItemSelectListener listener) {mItemSelectListener = listener;}/*** 初始化弹窗布局*/private void init() {View view = LayoutInflater.from(mContext).inflate(R.layout.spiner_window_layout, null);setContentView(view);setWidth(LayoutParams.WRAP_CONTENT);setHeight(LayoutParams.WRAP_CONTENT);setFocusable(true);ColorDrawable dw = new ColorDrawable(0x00);setBackgroundDrawable(dw);mListView = (ListView) view.findViewById(R.id.listview);mAdapter = new MySpinerAdapter(mContext);mListView.setAdapter(mAdapter);mListView.setOnItemClickListener(this);this.setOnDismissListener(new OnDismissListener() { // 弹窗消失的监听@Overridepublic void onDismiss() {if (mItemSelectListener != null) {mItemSelectListener.onItemClick(-1); // 弹窗消失,要让布局那边的箭头还原向下,所以那边还得判断一下,>=0的数据在显示,-1就忽略掉,箭头还原}}});}/*** 刷新下拉列表的数据* @param list* @param selIndex*/public void refreshData(Listlist, int selIndex) {if (list != null && selIndex != -1) {mAdapter.refreshData(list, selIndex);}}/*** 下拉列表ListView的点击事件。* @param arg0* @param view* @param pos* @param arg3*/@Overridepublic void onItemClick(AdapterViewarg0, View view, int pos, long arg3) {dismiss();if (mItemSelectListener != null) {mItemSelectListener.onItemClick(pos); //点击后调用此方法,则MySpinerView会监听到(因为mItemSelectListener是MySpinerView那边设置的监听器)}}
}
既然是ListView,那么马上想到的就是适配器,那么我们接下来设置弹窗里面的ListView适配器,代码如下:
package com.newland.myspinerdemo;import java.util.ArrayList;
import java.util.List;import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;public class MySpinerAdapterextends BaseAdapter {private Context mContext;private ListmObjects = new ArrayList();private LayoutInflater mInflater;public MySpinerAdapter(Context context) {mContext = context;mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);}/*** 刷新数据* @param objects* @param selIndex*/public void refreshData(Listobjects, int selIndex) {mObjects = objects;if (selIndex < 0) {selIndex = 0;}if (selIndex >= mObjects.size()) {selIndex = mObjects.size() - 1;}}@Overridepublic int getCount() {return mObjects.size();}@Overridepublic Object getItem(int pos) {return mObjects.get(pos).toString();}@Overridepublic long getItemId(int pos) {return pos;}@Overridepublic View getView(int pos, View convertView, ViewGroup arg2) {ViewHolder viewHolder;if (convertView == null) {convertView = mInflater.inflate(R.layout.spiner_item_layout, null);viewHolder = new ViewHolder();viewHolder.mTextView = (TextView) convertView.findViewById(R.id.textView);convertView.setTag(viewHolder);} else {viewHolder = (ViewHolder) convertView.getTag();}String item = (String) getItem(pos);viewHolder.mTextView.setText(item);return convertView;}public static class ViewHolder {public TextView mTextView;}/*** 提供一个设置点击事件监听的接口回调*/public interface IOnItemSelectListener {void onItemClick(int pos);}}
好了,功能性的东西都完成了,来看看主页面布局
主页面布局由4个自定义控件(MySpinerView)组成,代码如下:
最后一步,编写Activity,代码如下
package com.newland.myspinerdemo;import java.util.ArrayList;
import java.util.List;import android.app.Activity;
import android.os.Bundle;public class MainActivity extends Activity{/*** 四个下拉列表头部数据*/private String name1 = "课程类型";private String name2 = "教练";private String name3 = "卡路里";private String name4 = "时间";/*** 四个下拉列表数据*/private ListnameList1 = new ArrayList();private ListnameList2 = new ArrayList();private ListnameList3 = new ArrayList (); private List nameList4 = new ArrayList (); /** * 四个自定义下拉列表 */ private MySpinerView mySpinerView1; private MySpinerView mySpinerView2; private MySpinerView mySpinerView3; private MySpinerView mySpinerView4; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); setupViews(); } /** * 初始化四个下拉列表 */ private void setupViews() { mySpinerView1 = (MySpinerView)findViewById(R.id.mysv1); mySpinerView1.initText(name1); String[] names1 = { "高级课程", "中级课程", "所有课程" }; for (int i = 0; i < names1.length; i++) { nameList1.add(names1[i]); } mySpinerView1.setData(nameList1); mySpinerView2 = (MySpinerView)findViewById(R.id.mysv2); mySpinerView2.initText(name2); String[] names2 = {"小鱼","布拉特", "杰克逊", "菲尔顿", "希伯特"}; for (int i = 0; i < names2.length; i++) { nameList2.add(names2[i]); } mySpinerView2.setData(nameList2); mySpinerView3 = (MySpinerView)findViewById(R.id.mysv3); mySpinerView3.initText(name3); String[] names3 = {"10.0","20.0", "30.0", "40.0", "50.0"}; for (int i = 0; i < names3.length; i++) { nameList3.add(names3[i]); } mySpinerView3.setData(nameList3); mySpinerView4 = (MySpinerView)findViewById(R.id.mysv4); mySpinerView4.initText(name4); String[] names4 = {"1min","1hour", "1day", "1year", "forever"}; for (int i = 0; i < names4.length; i++) { nameList4.add(names4[i]); } mySpinerView4.setData(nameList4); } } 

大功告成~~~

附上源码下载链接: Android 自定义下拉列表 源码