android中自定义下拉框(转)
android自带的下拉框好用不?我觉得有时候好用,有时候难有,项目规定这样的效果,自带的控件实现不了,那么只有我们自己来老老实实滴写一个新的了,其实最基本的下拉框就像一些资料填写时,点击的时候出现在编辑框的下面,然后又很多选项的下拉框,可是我在网上找了一下,没有这种下拉框额,就自己写了一个,看效果图先:
,这个是资料填写的一部分界面,三个下拉框,选择故乡所在地;
点击之后弹出下拉框,选择下面的选项;
三个下拉框时关联的,第一个决定了第二数据内容,第二个决定了第三个数据内容,如果三个全部选好之后,再次点击第一个,那么第二个、第三个都会清空,点击第二个则第三个会清空。
要实现它,也就是一个PopupWindow时主要的界面,下面来看看代码:
创建一个DefineSpinnerView.java文件,继承至View,然后给出如下属性:
- /**
- * 用于弹出的下拉框
- */
- private PopupWindow pWindow = null;
- // **************************************************************************
- // 这些是用来当点击一个时,根据他们之间的关系来显示下拉框中的内容
- // **************************************************************************
- /**
- * 祖父
- */
- private DefineSpinnerView gradeParent = null;
- /**
- * 父控件
- */
- private DefineSpinnerView parents = null;
- /**
- * 子控件
- */
- private DefineSpinnerView child1 = null;
- /**
- * 孙子控件
- */
- private DefineSpinnerView child2 = null;
- private Context context = null;
- private OptionsAdapter adapter = null; // 下拉框适配器
- private List<String> datas = null; // 下拉框数据
- private RelativeLayout layout = null; // 父控件
- private TextView text = null; // 文本显示
- private ImageView image = null; // 下拉箭头
- private int p_width = -1; // 下拉框宽度
- private ListView list = null; // 下拉表
在构造函数中,构造出一个TextView和一个ImageView控件,并将它们都添加到layout中,代码如下:
- TextListener lis = new TextListener();
- text = new TextView(context);
- text.setBackgroundResource(R.drawable.edit_normal);
- text.setTextColor(getResources().getColor(R.color.spinner_text));
- text.setGravity(Gravity.CENTER);
- text.setOnClickListener(lis);
- LayoutParams params1 = new LayoutParams(width, hight);
- params1.leftMargin = left;
- params1.topMargin = top;
- image = new ImageView(context);
- image.setBackgroundResource(R.drawable.gerendang_jiantou);
- image.setOnClickListener(lis);
- if (LoginAct.MACHINE_PIXELS == IFinalConstant.XHDPI_RESOLUTION) {
- text.setTextSize(20.0f);
- LayoutParams params2 = new LayoutParams(19, 17);
- params2.topMargin = top + 15;
- params2.leftMargin = left + width - 28;
- map.put(image, params2);
- } else {
- text.setTextSize(15.0f);
- LayoutParams params2 = new LayoutParams(8, 8);
- params2.topMargin = top + 13;
- params2.leftMargin = left + width - 16;
- map.put(image, params2);
- }
- map.put(text, params1);
里面涉及到一个TextListener内部类,是我们自己定义的一个类,它继承至OnClickListener接口
- /**
- * @author ZYJ
- * 当点击Text时,根据上一级的内容来设置下一级的内容
- */
- class TextListener implements OnClickListener {
- public void onClick(View v) {
- hideSoft ();
- if (gradeParent != null && parents != null) {
- DefineSpinnerView.this.setDatas(DefineSpinnerView.this
- .getGuxiang3(gradeParent.getText(), parents.getText()));
- }
- if (gradeParent == null && parents != null) {
- DefineSpinnerView.this.setDatas(DefineSpinnerView.this
- .getGuxiang2(parents.getText()));
- }
- cleanText();
- changPopState(text);
- }
这个里面调用了一个方法changPopState,它的定义如下:
- /**
- * 显示或者隐藏下拉框
- *
- * @param v
- */
- private void changPopState(View v) {
- if (pWindow == null) {
- popWindow(v);
- return;
- }
- if (!pWindow.isShowing()) {
- popWindow(v);
- } else {
- if (pWindow != null) {
- pWindow.dismiss();
- }
- }
- }
这个里面又调用了一个popWindow方法,定义如下:
- /**
- * 初始化下拉框
- *
- * @param par 父控件
- */
- private void popWindow(final View par) {
- if (pWindow == null) {
- // 布局文件
- View v = LayoutInflater.from(context).inflate(R.layout.list, null);
- list = (ListView) v.findViewById(R.id.list);
- list.setOnItemClickListener(new OnItemClickListener() {
- public void onItemClick(AdapterView<?> arg0, View arg1,
- int arg2, long arg3) {
- // R.String.butian代表的是“不填”
- if (datas.get(arg2).toString().equals(context.getString(R.string.butian))) {
- text.setText("");
- } else {
- text.setText(datas.get(arg2).toString()); // 将当前点击的item中的字符串显示出来
- }
- if (pWindow != null) { // 关闭下拉框
- changPopState(par);
- }
- }
- });
- adapter = new OptionsAdapter(context, datas); // 根据数据,设置下拉框显示
- list.setAdapter(adapter);
- list.setDivider(null); // 屏蔽下拉框每个item之间的线条
- /**
- * 两种不同长度的下拉框,主要是为了适应屏幕的大小
- */
- if (p_width > 0) {
- pWindow = new PopupWindow(v, par.getWidth(), 150);
- } else {
- pWindow = new PopupWindow(v, par.getWidth(), 300);
- }
- pWindow.setFocusable(true);
- pWindow.setBackgroundDrawable(new BitmapDrawable());
- pWindow.setOutsideTouchable(true);
- pWindow.update();
- }
- pWindow.showAsDropDown(text);
- }
然后是一些细节了,提供一个TextView设置上面文字和得到上面文字的方法,设置下拉框数据的方法setDatas,如下:
- public void setText(String str) {
- if (text != null) {
- text.setText(str);
- }
- }
- public void setDatas(List<String> datas) {
- this.datas = datas;
- if (adapter != null) {
- adapter.setDatas(datas);
- adapter.notifyDataSetInvalidated();
- }
- }
- public String getText() {
- if (text != null) {
- return text.getText().toString();
- }
- LoginAct.LogW("spinner's textView is null");
- return "";
- }
- private void cleanText() {
- if (child1 != null) {
- child1.text.setText("");
- }
- if (child2 != null) {
- child2.text.setText("");
- }
- }
然后添加几个关联控件的get方法:
- public void setChild1(DefineSpinnerView child1) {
- this.child1 = child1;
- }
- public void setChild2(DefineSpinnerView child2) {
- this.child2 = child2;
- }
- public void setGradeParent(DefineSpinnerView gradeParent) {
- this.gradeParent = gradeParent;
- }
- public void setParents(DefineSpinnerView parents) {
- this.parents = parents;
- }
- public void setP_width(int p_width) {
- this.p_width = p_width;
- }
接下来提供一个设置子控件和算子控件数据的方法:
- /**
- * @param s1 父控件中的字符串
- * @param s2 子控件中的字符串
- * @return 返回一个List<String>集合
- * @功能 通过父控件的字符串来设置子控件中的内容
- */
- private List<String> getGuxiang3(String s1, String s2) {
- List<String> dd = new ArrayList<String>();
- dd.add(context.getString(R.string.butian));
- Map<String, ArrayList<String>> mapTmp1 = MaterialView.cityMap.get(s1);
- if (mapTmp1 != null) {
- List<String> list = mapTmp1.get(s2);
- if (list != null) {
- for (String str : list) {
- dd.add(str);
- }
- }
- }
- return dd;
- }
- /**
- * @param s 字符串
- * @return
- * @author ZYJ
- * @功能 设置父亲辈的下拉框中的内容
- */
- private List<String> getGuxiang2(String s) {
- List<String> dd = new ArrayList<String>();
- dd.add(context.getString(R.string.butian));
- Map<String, ArrayList<String>> mapTmp = MaterialView.cityMap.get(s);
- if (mapTmp != null) {
- for (String str : mapTmp.keySet()) {
- dd.add(str);
- }
- }
- return dd;
- }
最后提供一个隐藏软键盘的方法:
- private void hideSoft() {
- putMethodManager imm = (InputMethodManager) context
- .getSystemService(Context.INPUT_METHOD_SERVICE);
- m.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT,
- InputMethodManager.HIDE_NOT_ALWAYS);
到这里,自定义控件的代码基本上写完了;我们还要来看看下拉框中的xml布局和适配器的写法:
xml文件:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
- <TextView
- android:id="@+id/info"
- android:layout_width="wrap_content"
- android:layout_height="30dp"
- android:textSize="15sp"
- android:textColor="@color/spinner_text"
- android:layout_gravity="center"
- android:gravity="center"/>
- </LinearLayout>
然后是适配器类(OptionsAdapter),看全部代码吧:
- public class OptionsAdapter extends BaseAdapter {
- private Context context = null;
- private List<String> datas = null;
- public OptionsAdapter(Context context, List<String> d) {
- this.context = context;
- this.datas = d;
- }
- public int getCount() {
- return datas.size();
- }
- public Object getItem(int arg0) {
- return datas.get(arg0);
- }
- public long getItemId(int arg0) {
- return arg0;
- }
- /**
- * @author ZYJ
- * @功能 一个简单TextView显示
- */
- public View getView(int arg0, View arg1, ViewGroup arg2) {
- View view = LayoutInflater.from(context).inflate(R.layout.childlist,
- null);
- TextView textStr = (TextView) view.findViewById(R.id.info);
- textStr.setText("\t" + getItem(arg0).toString());
- return view;
- }
- public void setDatas(List<String> datas) {
- this.datas = datas;
- }
- }
这样,上面的功能基本上都实现了,我的这个控件在我项目中是手动添加上去的,而不是定义在xml文件中的,所以也不知道定义在xml文件中能不能生效,各位尽管试试吧。
转自:http://blog.csdn.net/a497393102/article/details/9279309
android中自定义下拉框(转)的更多相关文章
- easyui中自定义下拉框的使用
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 030 Android 第三方开源下拉框:NiceSpinner的使用+自定义Button样式+shape绘制控件背景图+图片选择器(selector)
1.NiceSpinner下拉框控件介绍 Android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Android原生提供的下拉框 ...
- Android 第三方开源下拉框:NiceSpinner
Android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Android原生提供的下拉框Spinner所提供的设计样式,而改用自定 ...
- jquery美化select,自定义下拉框样式
select默认的样式比较丑,有些应用需要美化select,在网上找到一个很好的美化样式效果,本人很喜欢,在这里分享一下. <!DOCTYPE html PUBLIC "-//W3C/ ...
- easyui源码翻译1.32--Combo(自定义下拉框)
前言 扩展自$.fn.validatebox.defaults.使用$.fn.combo.defaults重写默认值对象.下载该插件翻译源码 自定义下拉框显示一个可编辑的文本框和下拉面板在html页面 ...
- Combo( 自定义下拉框) 组件
本节课重点了解 EasyUI 中 Combo(自定义下拉框)组件的使用方法,这个组件依赖于ValidateBox(验证框)组件 一. 加载方式自定义下拉框不能通过标签的方式进行创建.<input ...
- 第二百一十二节,jQuery EasyUI,Combo(自定义下拉框)组件
jQuery EasyUI,Combo(自定义下拉框)组件 学习要点: 1.加载方式 2.属性列表 3.事件列表 4.方法列表 本节课重点了解 EasyUI 中 Combo(自定义下拉框)组件的使用方 ...
- android 开发-spinner下拉框控件的实现
Android提供实现下拉框功能的非常实用的控件Spinner. spinner控件需要向xml资源文件中添加spinner标签,如下: <Spinner android:id="@+ ...
- Android第三方开源下拉框:NiceSpinner
Android第三方开源下拉框:NiceSpinner Android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Andro ...
随机推荐
- JS原型、原型链、构造函数、实例与继承
https://cloud.tencent.com/developer/article/1408283 https://cloud.tencent.com/developer/article/1195 ...
- 【Python】使用cmd模块构造一个带有后台线程的交互命令行界面
最近写一些测试工具,实在懒得搞GUI,然后意识到python有一个自带模块叫cmd,用了用发现简直是救星. 1. 基本用法 cmd模块很容易学到,基本的用法比较简单,继承模块下的Cmd类,添加需要的功 ...
- 数据库:SQL Server自增长列的编号
SQL Server表中的自动编号ID重新开始排列 说法一: 有两种方法: 方法1: truncate table 你的表名 --这样不但将数据删除,而且可以重新置位identity属性的字段. 方法 ...
- 利用VS自带的命令行工具查看和生产PublicKeyToken
使用VS2008(或其他版本)命令行工具,键入:SN -T C:\*****.dll 就会显示出该dll具体的PublicKeyToken数值. 如果该程序集没有强命 名,则不会有PublicKeyT ...
- ios UITableViewCell重用问题
在写sina 微博界面的过程中使用到了cell,那么就是在cell上添加一些控件,但是由于每条微博的内容都是不同的,所以在显示的过程中,出现了内容重叠的问题,其实就是UITableViewCell重用 ...
- JS与IOS、安卓的交互
最近做的项目中涉及到了与安卓和ios的交互问题,对于一个新手来说,多多少少会有点迷糊.在调用安卓和ios的callback回调时,很轻松的就调用成功了,而且,步骤也不那么繁琐.刚开始,只知道那样使用可 ...
- CF-1096C Polygon for the Angle
CF-1096C Polygon for the Angle https://codeforces.com/contest/1096/problem/C 题意:给一个角度ang(1<=ang&l ...
- [LUOGU] 2820 局域网
题目背景 某个局域网内有n(n<=100)台计算机,由于搭建局域网时工作人员的疏忽,现在局域网内的连接形成了回路,我们知道如果局域网形成回路那么数据将不停的在回路内传输,造成网络卡的现象.因为连 ...
- 十:MYSQL中的事务
前言: 因为没有多少时间和精力,目前无法深入研究数据库中的事务,比如 但是,对于事务的一些基本知识,还是需要牢牢掌握的,做到了解事务的基本常识,在实际开发中能够理解各个持久层框架对事务的处理 一:是么 ...
- STM32中如何对printf函数重定向
通过USART1向计算机的串口调试助手打印数据,或者接收计算机串口调试助手的数据,接下来我们现STM32工程上的printf()函数,方便用于程序开发中调试信息的打印. 方法一:使用MicroLIB库 ...