使用RelativeLayout实现自定义下拉列表Spinner
2015-10-07 16:24
435 查看
Android有提供Spinner,但并不是什么时候都可以满足需求。我们可以通过ReLativeLayout+TextView+ImageView来实现我们自己的一个Spinner,可以完成一些复杂的功能,而且更灵活。
现在进入正题:
先来看一下效果
下面开始具体的实现,作为一个demo,我只写一些核心的代码
首先我们把XML文件先写好。定义一个ListView作为我们显示的下拉列表。我们建一个XML,叫myspinner_list.xml,里面只需放一个ListView即可。
myspinner_list.xml
有了ListView,那我们还需要写ListView里面的Item的XML文件,新建myspinner_list_item.xml,我们的demo比较简单里面就一个TextView。
myspinner_list_item.xml
最后在actitity_main.xml,写好我们的下拉列表的样式,具体的样式就根据项目要求去写
4000
就好了。
actitity_main.xml
到这里我们XML文件就都写好了,我们开始java代码的编写
首先我们需要写一个适配器,我们定义为SpinnerListAdapter.java,继承BaseAdapter
适配器的作用主要是给list_item进行赋值
SpinnerListAdapter.java
然后来到我们最重要的一个类,我们定义为MySpinner.java,继承PopupWindow,PopupWindow其实也是对话框,与AlertDialog不一样的是PopupWindow在界面任何地方显示,像悬浮窗体,具体自行Google,我就不啰嗦了。
MySpinner.java
其实也没多少东西,上面也有相应的注释。
准备工作已经做完了,我们来调用上面的方法,实现我们的目的
我们在MainActivity进行调用,我们需要监听rl_spinner的点击事件,设置显示的数据源,当选择item时,将数据源的值赋给tv_conten进行显示。
MainActivity .java
这里是作为一个简单demo,通过这种方法我们可以实现更多更丰富的功能,比如在ListView里可以显示图片,比Spinner会更灵活一点,更多的用法可以自己进行研究。
最后附上源码
源码 http://pan.baidu.com/s/1c0jW2cC
现在进入正题:
先来看一下效果
下面开始具体的实现,作为一个demo,我只写一些核心的代码
首先我们把XML文件先写好。定义一个ListView作为我们显示的下拉列表。我们建一个XML,叫myspinner_list.xml,里面只需放一个ListView即可。
myspinner_list.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#ffffffff"> <ListView android:id="@+id/lv_list" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:divider="#ffffff" android:dividerHeight="0dp"/> </LinearLayout>
有了ListView,那我们还需要写ListView里面的Item的XML文件,新建myspinner_list_item.xml,我们的demo比较简单里面就一个TextView。
myspinner_list_item.xml
<TextView android:id="@+id/tv_text" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:layout_gravity="center_vertical" android:text="item" android:padding="10dp" android:textSize="17sp" android:background="#ffffff"/>
最后在actitity_main.xml,写好我们的下拉列表的样式,具体的样式就根据项目要求去写
4000
就好了。
actitity_main.xml
<RelativeLayout android:id="@+id/rl_spinner" android:layout_width="200dp" android:layout_height="wrap_content" android:background="@drawable/relayout_spinner_bg"> <TextView android:id="@+id/tv_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="10dp" android:textSize="18sp" android:singleLine="true"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:src="@drawable/invert_triangle"/> </RelativeLayout>
到这里我们XML文件就都写好了,我们开始java代码的编写
首先我们需要写一个适配器,我们定义为SpinnerListAdapter.java,继承BaseAdapter
适配器的作用主要是给list_item进行赋值
SpinnerListAdapter.java
public class SpinnerListAdapter extends BaseAdapter { private int mPosition; private String[] mItems; private MySpinner mSpinner; private Activity mActivity; private onItemClickListener mListener; public SpinnerListAdapter(MySpinner spinner, Activity activity, String[] items){ this.mActivity=activity; this.mItems=items; this.mSpinner =spinner; } public int getCount() { return mItems.length; } public Object getItem(int position) { return null; } public long getItemId(int position) { return 0; } private class ViewHolder { public TextView text; } public View getView(final int arg0, final View arg1, ViewGroup arg2) { //获取设置好的listener mListener= mSpinner.getListener(); View view=arg1; ViewHolder holder=null; if(view==null){ view= View.inflate(mActivity, R.layout.myspinner_list_item, null); holder = new ViewHolder(); holder.text=(TextView) view.findViewById(R.id.tv_text); view.setTag(holder); }else { holder = (ViewHolder) view.getTag(); } holder.text.setText(mItems[arg0]); view.setOnClickListener(new OnClickListener() { public void onClick(View v) { mPosition=arg0; mSpinner.close(); mListener.click(mPosition,arg1); } }); return view; } //回调接口 public interface onItemClickListener{ public void click(int position, View view); } }
然后来到我们最重要的一个类,我们定义为MySpinner.java,继承PopupWindow,PopupWindow其实也是对话框,与AlertDialog不一样的是PopupWindow在界面任何地方显示,像悬浮窗体,具体自行Google,我就不啰嗦了。
MySpinner.java
public class MySpinner extends PopupWindow implements OnItemClickListener { private String[] mItems; private MySpinner mWindow; private SpinnerListAdapter.onItemClickListener mListener; public MySpinner(Context context, AttributeSet attrs) { super(context, attrs); } public MySpinner(Activity activity, int width, String[] items){ LayoutInflater inflater=activity.getLayoutInflater(); View contentView=inflater.inflate(R.layout.myspinner_list, null); // 设置PopupWindow的View this.setContentView(contentView); // 设置PopupWindow弹出窗体的宽 this.setWidth(width); // 设置PopupWindow弹出窗体的高 this.setHeight(android.view.WindowManager.LayoutParams.WRAP_CONTENT); this.setFocusable(true); this.setOutsideTouchable(true); // 刷新状态 this.update(); // 实例化一个ColorDrawable颜色 ColorDrawable dw = new ColorDrawable(0xffffffff); this.setBackgroundDrawable(dw); this.mItems=items; ListView listView=(ListView) contentView.findViewById(R.id.lv_list); mWindow=this; SpinnerListAdapter adapter=new SpinnerListAdapter(mWindow,activity, mItems); listView.setAdapter(adapter); listView.setOnItemClickListener(this); } public void onItemClick(AdapterView<?> parent, View view, int position, long id) { MySpinner.this.dismiss(); } public void showAtLocation(View parent, int gravity, int x, int y) { super.showAtLocation(parent, gravity, x, y); } public void close(){ this.dismiss(); } public int position(){ return 0; } public void setOnItemClickListener(SpinnerListAdapter.onItemClickListener listener){ this.mListener=listener; } public SpinnerListAdapter.onItemClickListener getListener(){ //可以通过this的实例来获取设置好的listener return mListener; } }
其实也没多少东西,上面也有相应的注释。
准备工作已经做完了,我们来调用上面的方法,实现我们的目的
我们在MainActivity进行调用,我们需要监听rl_spinner的点击事件,设置显示的数据源,当选择item时,将数据源的值赋给tv_conten进行显示。
MainActivity .java
public class MainActivity extends AppCompatActivity { private RelativeLayout rl_spinner; private TextView tv_content; private String array[]; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); rl_spinner = (RelativeLayout) findViewById(R.id.rl_spinner); tv_content = (TextView) findViewById(R.id.tv_content); //初始化 array = new String[]{"item1", "item2", "item3", "item4", "item5", "item6"}; tv_content.setText(array[0]); rl_spinner.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MySpinner mySpinner = new MySpinner(MainActivity.this, rl_spinner.getWidth(), array); mySpinner.showAsDropDown(rl_spinner, 0, 0);//显示在rl_spinner的下方 mySpinner.setOnItemClickListener(new SpinnerListAdapter.onItemClickListener() { @Override public void click(int position, View view) { tv_content.setText(array[position]); } }); } }); } }
这里是作为一个简单demo,通过这种方法我们可以实现更多更丰富的功能,比如在ListView里可以显示图片,比Spinner会更灵活一点,更多的用法可以自己进行研究。
最后附上源码
源码 http://pan.baidu.com/s/1c0jW2cC
相关文章推荐
- Android布局属性详解
- 嵌入式学习之路
- 数据结构之线性表的顺序存储结构(数组)的插入与删除
- HDU 2602 Bone Collector (01背包问题 基础)
- ocp-170
- 第二次作业
- HDU 2602 Bone Collector (01背包问题 基础)
- [译]学习IPython进行交互式计算和数据可视化(二)
- 10.Swift 数据存取
- OpenGl 名词解释之大白话
- Android 封装http请求的工具类
- JSP-标准动作标记
- ocp-169
- ocp-168
- ocp-167
- 数据结构例程——对称矩阵的压缩存储及基本运算
- ocp-166
- ocp-165
- [译]学习IPython进行交互式计算和数据可视化(一)
- 2015年传智播客各学科学费价格表