android自带的下拉框好用不?我觉得有时候好用,有时候难有,项目规定这样的效果,自带的控件实现不了,那么只有我们自己来老老实实滴写一个新的了,其实最基本的下拉框就像一些资料填写时,点击的时候出现在编辑框的下面,然后又很多选项的下拉框,可是我在网上找了一下,没有这种下拉框额,就自己写了一个,看效果图先:

,这个是资料填写的一部分界面,三个下拉框,选择故乡所在地;

点击之后弹出下拉框,选择下面的选项;

三个下拉框时关联的,第一个决定了第二数据内容,第二个决定了第三个数据内容,如果三个全部选好之后,再次点击第一个,那么第二个、第三个都会清空,点击第二个则第三个会清空。

要实现它,也就是一个PopupWindow时主要的界面,下面来看看代码:

创建一个DefineSpinnerView.java文件,继承至View,然后给出如下属性:

  1. /**
  2. * 用于弹出的下拉框
  3. */
  4. private PopupWindow pWindow = null;
  5. // **************************************************************************
  6. // 这些是用来当点击一个时,根据他们之间的关系来显示下拉框中的内容
  7. // **************************************************************************
  8. /**
  9. * 祖父
  10. */
  11. private DefineSpinnerView gradeParent = null;
  12. /**
  13. * 父控件
  14. */
  15. private DefineSpinnerView parents = null;
  16. /**
  17. * 子控件
  18. */
  19. private DefineSpinnerView child1 = null;
  20. /**
  21. * 孙子控件
  22. */
  23. private DefineSpinnerView child2 = null;
  24. private Context context = null;
  25. private OptionsAdapter adapter = null; // 下拉框适配器
  26. private List<String> datas = null; // 下拉框数据
  27. private RelativeLayout layout = null; // 父控件
  28. private TextView text = null; // 文本显示
  29. private ImageView image = null; // 下拉箭头
  30. private int p_width = -1; // 下拉框宽度
  31. private ListView list = null; // 下拉表

在构造函数中,构造出一个TextView和一个ImageView控件,并将它们都添加到layout中,代码如下:

  1. TextListener lis = new TextListener();
  2. text = new TextView(context);
  3. text.setBackgroundResource(R.drawable.edit_normal);
  4. text.setTextColor(getResources().getColor(R.color.spinner_text));
  5. text.setGravity(Gravity.CENTER);
  6. text.setOnClickListener(lis);
  7. LayoutParams params1 = new LayoutParams(width, hight);
  8. params1.leftMargin = left;
  9. params1.topMargin = top;
  10. image = new ImageView(context);
  11. image.setBackgroundResource(R.drawable.gerendang_jiantou);
  12. image.setOnClickListener(lis);
  13. if (LoginAct.MACHINE_PIXELS == IFinalConstant.XHDPI_RESOLUTION) {
  14. text.setTextSize(20.0f);
  15. LayoutParams params2 = new LayoutParams(19, 17);
  16. params2.topMargin = top + 15;
  17. params2.leftMargin = left + width - 28;
  18. map.put(image, params2);
  19. } else {
  20. text.setTextSize(15.0f);
  21. LayoutParams params2 = new LayoutParams(8, 8);
  22. params2.topMargin = top + 13;
  23. params2.leftMargin = left + width - 16;
  24. map.put(image, params2);
  25. }
  26. map.put(text, params1);

里面涉及到一个TextListener内部类,是我们自己定义的一个类,它继承至OnClickListener接口

  1. /**
  2. * @author ZYJ
  3. *         当点击Text时,根据上一级的内容来设置下一级的内容
  4. */
  5. class TextListener implements OnClickListener {
  6. public void onClick(View v) {
  7. hideSoft ();
  8. if (gradeParent != null && parents != null) {
  9. DefineSpinnerView.this.setDatas(DefineSpinnerView.this
  10. .getGuxiang3(gradeParent.getText(), parents.getText()));
  11. }
  12. if (gradeParent == null && parents != null) {
  13. DefineSpinnerView.this.setDatas(DefineSpinnerView.this
  14. .getGuxiang2(parents.getText()));
  15. }
  16. cleanText();
  17. changPopState(text);
  18. }

这个里面调用了一个方法changPopState,它的定义如下:

  1. /**
  2. * 显示或者隐藏下拉框
  3. *
  4. * @param v
  5. */
  6. private void changPopState(View v) {
  7. if (pWindow == null) {
  8. popWindow(v);
  9. return;
  10. }
  11. if (!pWindow.isShowing()) {
  12. popWindow(v);
  13. } else {
  14. if (pWindow != null) {
  15. pWindow.dismiss();
  16. }
  17. }
  18. }

这个里面又调用了一个popWindow方法,定义如下:

  1. /**
  2. * 初始化下拉框
  3. *
  4. * @param par 父控件
  5. */
  6. private void popWindow(final View par) {
  7. if (pWindow == null) {
  8. // 布局文件
  9. View v = LayoutInflater.from(context).inflate(R.layout.list, null);
  10. list = (ListView) v.findViewById(R.id.list);
  11. list.setOnItemClickListener(new OnItemClickListener() {
  12. public void onItemClick(AdapterView<?> arg0, View arg1,
  13. int arg2, long arg3) {
  14. // R.String.butian代表的是“不填”
  15. if (datas.get(arg2).toString().equals(context.getString(R.string.butian))) {
  16. text.setText("");
  17. } else {
  18. text.setText(datas.get(arg2).toString()); // 将当前点击的item中的字符串显示出来
  19. }
  20. if (pWindow != null) { // 关闭下拉框
  21. changPopState(par);
  22. }
  23. }
  24. });
  25. adapter = new OptionsAdapter(context, datas); // 根据数据,设置下拉框显示
  26. list.setAdapter(adapter);
  27. list.setDivider(null); // 屏蔽下拉框每个item之间的线条
  28. /**
  29. * 两种不同长度的下拉框,主要是为了适应屏幕的大小
  30. */
  31. if (p_width > 0) {
  32. pWindow = new PopupWindow(v, par.getWidth(), 150);
  33. } else {
  34. pWindow = new PopupWindow(v, par.getWidth(), 300);
  35. }
  36. pWindow.setFocusable(true);
  37. pWindow.setBackgroundDrawable(new BitmapDrawable());
  38. pWindow.setOutsideTouchable(true);
  39. pWindow.update();
  40. }
  41. pWindow.showAsDropDown(text);
  42. }

然后是一些细节了,提供一个TextView设置上面文字和得到上面文字的方法,设置下拉框数据的方法setDatas,如下:

  1. public void setText(String str) {
  2. if (text != null) {
  3. text.setText(str);
  4. }
  5. }
  6. public void setDatas(List<String> datas) {
  7. this.datas = datas;
  8. if (adapter != null) {
  9. adapter.setDatas(datas);
  10. adapter.notifyDataSetInvalidated();
  11. }
  12. }
  13. public String getText() {
  14. if (text != null) {
  15. return text.getText().toString();
  16. }
  17. LoginAct.LogW("spinner's textView is null");
  18. return "";
  19. }
  20. private void cleanText() {
  21. if (child1 != null) {
  22. child1.text.setText("");
  23. }
  24. if (child2 != null) {
  25. child2.text.setText("");
  26. }
  27. }

然后添加几个关联控件的get方法:

  1. public void setChild1(DefineSpinnerView child1) {
  2. this.child1 = child1;
  3. }
  4. public void setChild2(DefineSpinnerView child2) {
  5. this.child2 = child2;
  6. }
  7. public void setGradeParent(DefineSpinnerView gradeParent) {
  8. this.gradeParent = gradeParent;
  9. }
  10. public void setParents(DefineSpinnerView parents) {
  11. this.parents = parents;
  12. }
  13. public void setP_width(int p_width) {
  14. this.p_width = p_width;
  15. }

接下来提供一个设置子控件和算子控件数据的方法:

  1. /**
  2. * @param s1 父控件中的字符串
  3. * @param s2 子控件中的字符串
  4. * @return 返回一个List<String>集合
  5. * @功能 通过父控件的字符串来设置子控件中的内容
  6. */
  7. private List<String> getGuxiang3(String s1, String s2) {
  8. List<String> dd = new ArrayList<String>();
  9. dd.add(context.getString(R.string.butian));
  10. Map<String, ArrayList<String>> mapTmp1 = MaterialView.cityMap.get(s1);
  11. if (mapTmp1 != null) {
  12. List<String> list = mapTmp1.get(s2);
  13. if (list != null) {
  14. for (String str : list) {
  15. dd.add(str);
  16. }
  17. }
  18. }
  19. return dd;
  20. }
  21. /**
  22. * @param s 字符串
  23. * @return
  24. * @author ZYJ
  25. * @功能 设置父亲辈的下拉框中的内容
  26. */
  27. private List<String> getGuxiang2(String s) {
  28. List<String> dd = new ArrayList<String>();
  29. dd.add(context.getString(R.string.butian));
  30. Map<String, ArrayList<String>> mapTmp = MaterialView.cityMap.get(s);
  31. if (mapTmp != null) {
  32. for (String str : mapTmp.keySet()) {
  33. dd.add(str);
  34. }
  35. }
  36. return dd;
  37. }

最后提供一个隐藏软键盘的方法:

  1. private void hideSoft() {
  2. putMethodManager imm = (InputMethodManager) context
  3. .getSystemService(Context.INPUT_METHOD_SERVICE);
  4. m.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT,
  5. InputMethodManager.HIDE_NOT_ALWAYS);

到这里,自定义控件的代码基本上写完了;我们还要来看看下拉框中的xml布局和适配器的写法:

xml文件:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="horizontal">
  6. <TextView
  7. android:id="@+id/info"
  8. android:layout_width="wrap_content"
  9. android:layout_height="30dp"
  10. android:textSize="15sp"
  11. android:textColor="@color/spinner_text"
  12. android:layout_gravity="center"
  13. android:gravity="center"/>
  14. </LinearLayout>

然后是适配器类(OptionsAdapter),看全部代码吧:

  1. public class OptionsAdapter extends BaseAdapter {
  2. private Context context = null;
  3. private List<String> datas = null;
  4. public OptionsAdapter(Context context, List<String> d) {
  5. this.context = context;
  6. this.datas = d;
  7. }
  8. public int getCount() {
  9. return datas.size();
  10. }
  11. public Object getItem(int arg0) {
  12. return datas.get(arg0);
  13. }
  14. public long getItemId(int arg0) {
  15. return arg0;
  16. }
  17. /**
  18. * @author ZYJ
  19. * @功能 一个简单TextView显示
  20. */
  21. public View getView(int arg0, View arg1, ViewGroup arg2) {
  22. View view = LayoutInflater.from(context).inflate(R.layout.childlist,
  23. null);
  24. TextView textStr = (TextView) view.findViewById(R.id.info);
  25. textStr.setText("\t" + getItem(arg0).toString());
  26. return view;
  27. }
  28. public void setDatas(List<String> datas) {
  29. this.datas = datas;
  30. }
  31. }

这样,上面的功能基本上都实现了,我的这个控件在我项目中是手动添加上去的,而不是定义在xml文件中的,所以也不知道定义在xml文件中能不能生效,各位尽管试试吧。

转自:http://blog.csdn.net/a497393102/article/details/9279309

android中自定义下拉框(转)的更多相关文章

  1. easyui中自定义下拉框的使用

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. 030 Android 第三方开源下拉框:NiceSpinner的使用+自定义Button样式+shape绘制控件背景图+图片选择器(selector)

    1.NiceSpinner下拉框控件介绍 Android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Android原生提供的下拉框 ...

  3. Android 第三方开源下拉框:NiceSpinner

    Android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Android原生提供的下拉框Spinner所提供的设计样式,而改用自定 ...

  4. jquery美化select,自定义下拉框样式

    select默认的样式比较丑,有些应用需要美化select,在网上找到一个很好的美化样式效果,本人很喜欢,在这里分享一下. <!DOCTYPE html PUBLIC "-//W3C/ ...

  5. easyui源码翻译1.32--Combo(自定义下拉框)

    前言 扩展自$.fn.validatebox.defaults.使用$.fn.combo.defaults重写默认值对象.下载该插件翻译源码 自定义下拉框显示一个可编辑的文本框和下拉面板在html页面 ...

  6. Combo( 自定义下拉框) 组件

    本节课重点了解 EasyUI 中 Combo(自定义下拉框)组件的使用方法,这个组件依赖于ValidateBox(验证框)组件 一. 加载方式自定义下拉框不能通过标签的方式进行创建.<input ...

  7. 第二百一十二节,jQuery EasyUI,Combo(自定义下拉框)组件

    jQuery EasyUI,Combo(自定义下拉框)组件 学习要点: 1.加载方式 2.属性列表 3.事件列表 4.方法列表 本节课重点了解 EasyUI 中 Combo(自定义下拉框)组件的使用方 ...

  8. android 开发-spinner下拉框控件的实现

    Android提供实现下拉框功能的非常实用的控件Spinner. spinner控件需要向xml资源文件中添加spinner标签,如下: <Spinner android:id="@+ ...

  9. Android第三方开源下拉框:NiceSpinner

     Android第三方开源下拉框:NiceSpinner Android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Andro ...

随机推荐

  1. tomcat假死现象 - 二

    1 编写背景 最近服务器发现tomcat的应用会偶尔出现无法访问的情况.经过一段时间的观察最近又发现有台tomcat的应用出现了无法访问情况.简单描述下该台tomcat当时具体的表现:客户端请求没有响 ...

  2. java后台验证码的生成

    前台代码: <tr> <td>验证码</td> <td><input name="checkCode" type=" ...

  3. graphviz 布局和子图,表格教程

    有了这三个利器,就搞定架构图了. 子图间互相调用要开启 http://graphviz.org/pdf/dotguide.pdf

  4. nib、xib、storyboard(故事板)

    nib:NeXT Interface Builder的缩写 xib:XML nib的缩写 相同点: nib和xib都是Interface Builder的图形界面设计文档.Interface Buil ...

  5. ios 团购信息客户端demo(三)

    接上二篇的内容,今天我们就来介绍一下如何将解析出来的数据放入AQGridView中显示出来,因为我们的工程中已经将AQGridView导入了,所以我们在KKFirstViewController中直接 ...

  6. 移动网页端HTML5 meta便签

    width = device-width:标识宽度是设备屏幕的宽度 initial-scale = 1.0 :标识初始的缩放比例 minimum-scale =0.5 :表示最小的缩放比例 maxim ...

  7. [LUOGU] P1387 最大正方形

    题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m ...

  8. Day08字符编码

    Day08: 知识储备: 硬盘:由硬盘加载到内存,cpu从内存中取 软件产生的数据都是先保存在内存中 文件,输入文字,保存到内存,内存是硬件,硬件只能保存2进制,所以需要转换 文本编辑器,输入文字的时 ...

  9. PAT Basic 1014

    1014 福尔摩斯的约会 大侦探福尔摩斯接到一张奇怪的字条:“我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm” ...

  10. 在loadrunner中用头文件的形式对字符串进行MD5加密操作

    1.首先要有md5.h的头文件 2.然后在global.h中加入#include "md5.h" 3.在action中调用md5.h中的Change_to_Md5(const ch ...