使用EditText+ListView並結合TextWatcher實現輸入關鍵字篩選數據

想必你們應該遇到過這樣的狀況,當點擊Spinner控件後彈出的列表內容超多,一個一個滑動着去尋找所要的項很麻煩,尤爲是當本身知道想要選擇的內容,這時候若是咱們只須要輸入某些關鍵字,就能夠講上百條數據篩選出幾十條甚至更少,豈不是會方便不少。

    其實這是項目中的一個需求,因爲目前公司接觸的多數和數據採集相關的PDA項目,有不少填寫項一個spinner已經不方便知足需求,雖然客戶尚未提出,但提早作好優化老是沒有錯的,因此項目組的同事提出這個需求並讓我嘗試着去作出來,當中給了我很多幫助和意見。 html

    閒言少敘,簡單說下這個demo的實現,點擊一個button,彈出一個相似spinner的界面,包含一個edittext和listview,當在輸入框中鍵入關鍵字時,下面的listview所顯示的數據能夠隨之進行篩選,點擊item,將所選值返回給button。實現其實不難,只不過接觸了一個新的知識而已,就是TextWatcher,它自己是一個接口,須要實現並覆蓋它的三個方法,在每一個方法中執行相應的操做,而後在須要的控件上添加監聽便可。先來看本Demo實現後的效果 java

                                                                                             

                                               進入後點擊按鈕                                                                                                    彈出數據界面 android

 

                                                                                             

                                             輸入關鍵字進行篩選                                                                                               點擊子項目返回給按鈕 緩存

 

如下是部分代碼的實現,其實比較簡單,惟一不太熟悉的就是TextWatcher,由於以前沒用過,可是很簡單,只有三個方法,現實了就OK了 app

 

        首先介紹一下這個本身寫的類,它實現了一個數據的值value和顯示名稱Name的綁定,能夠很方便的用於添加數據,固然也可使用本身的方法去添加數據,本例子我就用這個了。 dom

  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.       
  48. }  
package com.cogent.enumbutton;

/**
 * 一個Value(綁定值)-Name(顯示名稱)對象,如:1-漢族
 */
public class ValueNameDomain {

	private String Value;//綁定的值
	private String Name;//顯示的選項名稱
	
	public ValueNameDomain(){}
	
	public ValueNameDomain(String name,String value){
		this.Name = name;
		this.Value = value;
	}
	
	/**
	 * 獲取綁定的值
	 */
	public String getValue() {
		return Value;
	}
	/**
	 * 設置綁定的值
	 */
	public void setValue(String value) {
		this.Value = value;
	}
	/**
	 * 獲取顯示的選項名稱
	 */
	public String getName() {
		return Name;
	}
	/**
	 * 設置顯示的選項名稱
	 */
	public void setName(String name) {
		this.Name = name;
	}
	@Override
	public String toString() {
		return Name;
	}
	
	
}


 

 

這個是demo的關鍵了,運用一個窗口樣式的activity實現相似spinner的功能,具體的地方我都進行了本身能看懂的註解,對輸入控件添加addTextChangedListener,並實現其中的三個方法就完成了,三個方法比較簡單,爲別 ide

也就是文字發生改變以前,改變時,和改變以後進行相應的操做,看看SDK就神馬都解決了 學習

 

  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.   
  123. }  
package com.cogent.enumbutton;

import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

public class EditTextListView extends Activity {
	//按鈕靜態緩存,該用法能夠避免使用startActivityForResult來獲取按鈕返回的時間
	public static Button btn;
	private EditText edit_search;
	private ListView lv;
	private EditTextListViewAdapter adapter;
	List<ValueNameDomain> list = new ArrayList<ValueNameDomain>();//全部的數據list
	List<ValueNameDomain> newlist = new ArrayList<ValueNameDomain>();//查詢後的數據list

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.edittextlistview);
		init();
		initDefaultLists();

	}

	//初始化控件
	private void init() {
		edit_search = (EditText) findViewById(R.id.edit_search);
		//爲輸入添加TextWatcher監聽文字的變化
		edit_search.addTextChangedListener(new TextWatcher_Enum());
		adapter = new EditTextListViewAdapter(this, list);
		lv = (ListView) findViewById(R.id.edittextListview);
		lv.setAdapter(adapter);
		lv.setOnItemClickListener(new onclick());
	}

	//添加數據
	private void initDefaultLists() {
		ValueNameDomain domain = new ValueNameDomain();
		for (int i = 1; i <= 20; i++) {
			domain = new ValueNameDomain();
			domain.setName("測試數據" + i);
			domain.setValue(i + "");
			list.add(domain);
		}

	}

	//當editetext變化時調用的方法,來判斷所輸入是否包含在所屬數據中
	private List<ValueNameDomain> getNewData(String input_info) {
		//遍歷list
		for (int i = 0; i < list.size(); i++) {
			ValueNameDomain domain = list.get(i);
			//若是遍歷到的名字包含所輸入字符串
			if (domain.getName().contains(input_info)) {
				//將遍歷到的元素從新組成一個list
				ValueNameDomain domain2 = new ValueNameDomain();

				domain2.setName(domain.getName());
				domain2.setValue(i + "");
				newlist.add(domain2);
			}
		}
		return newlist;
	}

	//button的點擊事件
	class onclick implements OnItemClickListener {

		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
			TextView text = (TextView) view.findViewById(R.id.tvData);
			String str = (String) text.getText();
			btn.setText(str);
			EditTextListView.this.finish();
		}

	}

	//TextWatcher接口
	class TextWatcher_Enum implements TextWatcher {

		//文字變化前
		@Override
		public void beforeTextChanged(CharSequence s, int start, int count,
				int after) {

		}

		//文字變化時
		@Override
		public void onTextChanged(CharSequence s, int start, int before,
				int count) {
			newlist.clear();
			if (edit_search.getText() != null) {
				String input_info = edit_search.getText().toString();
				newlist = getNewData(input_info);
				adapter = new EditTextListViewAdapter(EditTextListView.this,
						newlist);
				lv.setAdapter(adapter);
			}
		}

		//文字變化後
		@Override
		public void afterTextChanged(Editable s) {

		}

	}

}


這是個比較實用的demo,打算進一步整理出來封裝起來,之後項目要是用到的話就能夠直接拿來用啦,結尾附上源碼,但願你們能夠一塊兒學習分享,堅持記錄本身的android路程 測試

相關文章
相關標籤/搜索