使用EditText+ListView并结合TextWatcher实现输入关键字筛选数据

来源:互联网 发布:药智数据库会员 编辑:程序博客网 时间:2024/05/19 13:22
想必大家应该遇到过这样的情况,当点击Spinner控件后弹出的列表内容超多,一个一个滑动着去寻找所要的项很麻烦,尤其是当自己知道想要选择的内容,这时候如果我们只需要输入某些关键字,就可以讲上百条数据筛选出几十条甚至更少,岂不是会方便很多。

    其实这是项目中的一个需求,由于目前公司接触的多数和数据采集相关的PDA项目,有很多填写项一个spinner已经不方便满足需求,虽然客户还没有提出,但提前做好优化总是没有错的,所以项目组的同事提出这个需求并让我尝试着去做出来,当中给了我不少帮助和意见。

    闲言少叙,简单说下这个demo的实现,点击一个button,弹出一个类似spinner的界面,包含一个edittext和listview,当在输入框中键入关键字时,下面的listview所显示的数据可以随之进行筛选,点击item,将所选值返回给button。实现其实不难,只不过接触了一个新的知识而已,就是TextWatcher,它本身是一个接口,需要实现并覆盖它的三个方法,在每个方法中执行相应的操作,然后在需要的控件上添加监听即可。先来看本Demo实现后的效果

                                                                                            

                                               进入后点击按钮                                                                                                    弹出数据界面

                                                                                            

                                             输入关键字进行筛选                                                                                               点击子项目返回给按钮

以下是部分代码的实现,其实比较简单,唯一不太熟悉的就是TextWatcher,因为之前没用过,但是很简单,只有三个方法,现实了就OK了

        首先介绍一下这个自己写的类,它实现了一个数据的值value和显示名称Name的绑定,可以很方便的用于添加数据,当然也可以使用自己的方法去添加数据,本例子我就用这个了。

[java] view plaincopyprint?
  1. package com.cogent.enumbutton; 
  2.  
  3. /**
  4. * 一个Value(绑定值)-Name(显示名称)对象,如:1-汉族
  5. */ 
  6. public class ValueNameDomain { 
  7.  
  8.     private String Value;//绑定的值 
  9.     private String Name;//显示的选项名称 
  10.      
  11.     public ValueNameDomain(){} 
  12.      
  13.     public ValueNameDomain(String name,String value){ 
  14.         this.Name = name; 
  15.         this.Value = value; 
  16.     } 
  17.      
  18.     /**
  19.      * 获取绑定的值
  20.      */ 
  21.     public String getValue() { 
  22.         return Value; 
  23.     } 
  24.     /**
  25.      * 设置绑定的值
  26.      */ 
  27.     public void setValue(String value) { 
  28.         this.Value = value; 
  29.     } 
  30.     /**
  31.      * 获取显示的选项名称
  32.      */ 
  33.     public String getName() { 
  34.         return Name; 
  35.     } 
  36.     /**
  37.      * 设置显示的选项名称
  38.      */ 
  39.     public void setName(String name) { 
  40.         this.Name = name; 
  41.     } 
  42.     @Override 
  43.     public String toString() { 
  44.         return Name; 
  45.     } 
  46.      
  47.      


这个是demo的关键了,运用一个窗口样式的activity实现类似spinner的功能,具体的地方我都进行了自己能看懂的注解,对输入控件添加addTextChangedListener,并实现其中的三个方法就完成了,三个方法比较简单,为别

也就是文字发生改变之前,改变时,和改变之后进行相应的操作,看看SDK就神马都解决了

[html] view plaincopyprint?
  1. package com.cogent.enumbutton; 
  2.  
  3. import java.util.ArrayList; 
  4. import java.util.List; 
  5. import android.app.Activity; 
  6. import android.os.Bundle; 
  7. import android.text.Editable; 
  8. import android.text.TextWatcher; 
  9. import android.view.View; 
  10. import android.view.Window; 
  11. import android.widget.AdapterView; 
  12. import android.widget.AdapterView.OnItemClickListener; 
  13. import android.widget.Button; 
  14. import android.widget.EditText; 
  15. import android.widget.ListView; 
  16. import android.widget.TextView; 
  17.  
  18. public class EditTextListView extends Activity { 
  19.     //按钮静态缓存,该用法可以避免使用startActivityForResult来获取按钮返回的时间 
  20.     public static Button btn; 
  21.     private EditText edit_search; 
  22.     private ListView lv; 
  23.     private EditTextListViewAdapter adapter; 
  24.     List<ValueNameDomain>list = new ArrayList<ValueNameDomain>();//所有的数据list 
  25.     List<ValueNameDomain>newlist = new ArrayList<ValueNameDomain>();//查询后的数据list 
  26.  
  27.     @Override 
  28.     protected void onCreate(Bundle savedInstanceState) { 
  29.         super.onCreate(savedInstanceState); 
  30.         requestWindowFeature(Window.FEATURE_NO_TITLE); 
  31.         setContentView(R.layout.edittextlistview); 
  32.         init(); 
  33.         initDefaultLists(); 
  34.  
  35.     } 
  36.  
  37.     //初始化控件 
  38.     private void init() { 
  39.         edit_search = (EditText) findViewById(R.id.edit_search); 
  40.         //为输入添加TextWatcher监听文字的变化 
  41.         edit_search.addTextChangedListener(new TextWatcher_Enum()); 
  42.         adapter = new EditTextListViewAdapter(this, list); 
  43.         lv = (ListView) findViewById(R.id.edittextListview); 
  44.         lv.setAdapter(adapter); 
  45.         lv.setOnItemClickListener(new onclick()); 
  46.     } 
  47.  
  48.     //添加数据 
  49.     private void initDefaultLists() { 
  50.         ValueNameDomain domain = new ValueNameDomain(); 
  51.         for (int i = 1; i <= 20; i++) { 
  52.             domain = new ValueNameDomain(); 
  53.             domain.setName("测试数据" + i); 
  54.             domain.setValue(i + ""); 
  55.             list.add(domain); 
  56.         } 
  57.  
  58.     } 
  59.  
  60.     //当editetext变化时调用的方法,来判断所输入是否包含在所属数据中 
  61.     private List<ValueNameDomain> getNewData(String input_info) { 
  62.         //遍历list 
  63.         for (int i = 0; i <list.size(); i++) { 
  64.             ValueNameDomain domain =list.get(i); 
  65.             //如果遍历到的名字包含所输入字符串 
  66.             if (domain.getName().contains(input_info)) { 
  67.                 //将遍历到的元素重新组成一个list 
  68.                 ValueNameDomain domain2 =new ValueNameDomain(); 
  69.  
  70.                 domain2.setName(domain.getName()); 
  71.                 domain2.setValue(i + ""); 
  72.                 newlist.add(domain2); 
  73.             } 
  74.         } 
  75.         return newlist; 
  76.     } 
  77.  
  78.     //button的点击事件 
  79.     class onclick implements OnItemClickListener { 
  80.  
  81.         @Override 
  82.         public void onItemClick(AdapterView<?> parent, View view, int position,long id) { 
  83.             TextView text = (TextView) view.findViewById(R.id.tvData); 
  84.             String str = (String) text.getText(); 
  85.             btn.setText(str); 
  86.             EditTextListView.this.finish(); 
  87.         } 
  88.  
  89.     } 
  90.  
  91.     //TextWatcher接口 
  92.     class TextWatcher_Enum implements TextWatcher { 
  93.  
  94.         //文字变化前 
  95.         @Override 
  96.         public void beforeTextChanged(CharSequence s, int start, int count, 
  97.                 int after) { 
  98.  
  99.         } 
  100.  
  101.         //文字变化时 
  102.         @Override 
  103.         public void onTextChanged(CharSequence s, int start, int before, 
  104.                 int count) { 
  105.             newlist.clear(); 
  106.             if (edit_search.getText() != null) { 
  107.                 String input_info =edit_search.getText().toString(); 
  108.                 newlist = getNewData(input_info); 
  109.                 adapter =new EditTextListViewAdapter(EditTextListView.this, 
  110.                         newlist); 
  111.                 lv.setAdapter(adapter); 
  112.             } 
  113.         } 
  114.  
  115.         //文字变化后 
  116.         @Override 
  117.         public void afterTextChanged(Editable s) { 
  118.  
  119.         } 
  120.  
  121.     } 
  122.