Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 一步一步學android控件(之六) —— MultiAutoCompleteTextView

一步一步學android控件(之六) —— MultiAutoCompleteTextView

編輯:關於Android編程

今天學習的控件是MultiAutoCompleteTextView 。 提到MultiAutoCompleteTextView 我們就自然而然地想到AutoCompleteTextView ,就想知道他們之間到底有什麼區別。        [java]  public static class SelfDedineTokenizer implements Tokenizer {              private char mTokenizer = ',';              public SelfDedineTokenizer() {           }              public SelfDedineTokenizer(char token) {               mTokenizer = token;           }              public int findTokenEnd(CharSequence text, int cursor) {               int i = cursor;               int len = text.length();               while (i < len) {                   if (text.charAt(i) == mTokenizer) {                       return i;                   } else {                       i++;                   }               }               return len;              }              public int findTokenStart(CharSequence text, int cursor) {               int i = cursor;               while (i > 0 && text.charAt(i - 1) != mTokenizer) {                   i--;               }               while (i < cursor && text.charAt(i) == ' ') {                   i++;               }               return i;           }              public CharSequence terminateToken(CharSequence text) {               int i = text.length();               while (i > 0 && text.charAt(i - 1) == ' ') {                   i--;               }               if (i > 0 && text.charAt(i - 1) == mTokenizer) {                   return text;               } else {                   if (text instanceof Spanned) {                       SpannableString sp = new SpannableString(text                               + String.valueOf(mTokenizer));                       TextUtils.copySpansFrom((Spanned) text, 0, text.length(),                               Object.class, sp, 0);                       return sp;                   } else {                       return text + String.valueOf(mTokenizer);                   }               }           }              public void setToken(char token) {               mTokenizer = token;           }              public char getToken() {               return mTokenizer;           }       }   這段代碼是自定義的Tokenizer , 默認使用 ‘ , ’ 作為分隔符, 若想用其他的符號替換 ‘ , ’ 使用setToken方法即可。   廢話也說了那麼多了,現在說說今天要做的事情   1、使用異步調用方法(Executors)加載MultiAutoCompleteTextView 中 Adapter 需要的數據(數據跟AutoCompleteTextView一樣,有疑問的可參見 點擊一步一步學android控件(之五) —— AutoCompleteTextView)   2、在MultiAutoCompleteTextView中使用自定義的Tokenizer而不是默認的Tokenizer。     下面就來實現這些功能,老規矩先准備資源文件   1、 創建布局文件 multi_auto_complete_textview.xml    [html]   <?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" >          <MultiAutoCompleteTextView           android:id="@+id/show_multi_complete"           android:layout_width="match_parent"           android:layout_height="wrap_content"           android:padding="10dp"           android:layout_marginTop="20dp" />      </LinearLayout>   2、創建activity ——WidgetMultiAutoCompleteActivity.java [java]   package com.xy.zt.selfdefinewieget;      import java.io.File;   import java.util.ArrayList;   import java.util.LinkedList;   import java.util.List;   import java.util.concurrent.Callable;   import java.util.concurrent.ExecutionException;   import java.util.concurrent.ExecutorService;   import java.util.concurrent.Executors;   import java.util.concurrent.Future;      import android.annotation.SuppressLint;   import android.app.Activity;   import android.os.Bundle;   import android.os.Environment;   import android.os.Handler;   import android.os.Message;   import android.text.SpannableString;   import android.text.Spanned;   import android.text.TextUtils;   import android.widget.ArrayAdapter;   import android.widget.MultiAutoCompleteTextView;   import android.widget.MultiAutoCompleteTextView.Tokenizer;      public class WidgetMultiAutoCompleteActivity extends Activity {          public static final String[] DEFAULT_DATAS = new String[] { "China",               "chengdu", "xueyu", "ting", "baba", "mama", "meimei" };       public static final int MSG_RECEIVE_TASK_DATA = 1024;          private ExecutorService mExecutor;       private ArrayAdapter<String> mMultiAdapter;       private MultiAutoCompleteTextView mShowMulti;       // private CommaTokenizer mComma = new CommaTokenizer();       private Future<List<String>> mListFileTask;          private static final Callable<List<String>> LIST_FILES = new Callable<List<String>>() {           public List<String> call() throws Exception {               File rootDir = Environment.getRootDirectory();               LinkedList<File> queue = new LinkedList<File>();               ArrayList<String> result = new ArrayList<String>(100);               queue.offer(rootDir);               File tmpFile, tmpDirAllFile[];               while ((tmpFile = queue.poll()) != null) {                   if (tmpFile.isDirectory()) {                       tmpDirAllFile = tmpFile.listFiles();                       if (tmpDirAllFile != null) {                           for (File f : tmpDirAllFile) {                               queue.offer(f);                           }                       }                   } else {                       result.add(tmpFile.getName());                   }               }               return result;           }          };          Handler mHandler = new Handler() {              @SuppressWarnings("unchecked")           @Override           public void handleMessage(Message msg) {               switch (msg.what) {               case MSG_RECEIVE_TASK_DATA:                   List<String> datas;                   try {                       datas = (List<String>) msg.obj;                   } catch (ClassCastException e) {                       datas = useDefaultData();                   }                      mShowMulti.setEnabled(true);                   mMultiAdapter = new ArrayAdapter<String>(                           WidgetMultiAutoCompleteActivity.this,                           R.layout.auto_complete_item, R.id.auto_item_file_name,                           datas);                   mShowMulti.setAdapter(mMultiAdapter);                   break;               }               ;           }          };          @Override       public void onCreate(Bundle savedInstanceState) {           super.onCreate(savedInstanceState);           setContentView(R.layout.multi_auto_complete_textview);           init();           mExecutor = Executors.newCachedThreadPool();           mListFileTask = mExecutor.submit(LIST_FILES);           mExecutor.submit(new Runnable() {               @SuppressLint("HandlerLeak")               public void run() {                   List<String> datas;                   try {                       datas = mListFileTask.get();                   } catch (InterruptedException e) {                       datas = useDefaultData();                   } catch (ExecutionException e) {                       datas = useDefaultData();                   }                   Message msg = mHandler.obtainMessage(MSG_RECEIVE_TASK_DATA);                   msg.obj = datas;                   mHandler.sendMessage(msg);               }              });          }          void init() {           mShowMulti = (MultiAutoCompleteTextView) findViewById(R.id.show_multi_complete);           mShowMulti.setEnabled(false);           mShowMulti.setTokenizer(mCustomerToken);           mShowMulti.setThreshold(1);       }          private List<String> useDefaultData() {           List<String> datas = new ArrayList<String>();           for (String s : DEFAULT_DATAS) {               datas.add(s);           }           return datas;       }          @Override       protected void onDestroy() {           super.onDestroy();           mExecutor.shutdown();       }          SelfDedineTokenizer mCustomerToken = new SelfDedineTokenizer(';');          public static class SelfDedineTokenizer implements Tokenizer {              private char mTokenizer = ',';              public SelfDedineTokenizer() {           }              public SelfDedineTokenizer(char token) {               mTokenizer = token;           }              public int findTokenEnd(CharSequence text, int cursor) {               int i = cursor;               int len = text.length();               while (i < len) {                   if (text.charAt(i) == mTokenizer) {                       return i;                   } else {                       i++;                   }               }               return len;              }              public int findTokenStart(CharSequence text, int cursor) {               int i = cursor;               while (i > 0 && text.charAt(i - 1) != mTokenizer) {                   i--;               }               while (i < cursor && text.charAt(i) == ' ') {                   i++;               }               return i;           }              public CharSequence terminateToken(CharSequence text) {               int i = text.length();               while (i > 0 && text.charAt(i - 1) == ' ') {                   i--;               }               if (i > 0 && text.charAt(i - 1) == mTokenizer) {                   return text;               } else {                   if (text instanceof Spanned) {                       SpannableString sp = new SpannableString(text                               + String.valueOf(mTokenizer));                       TextUtils.copySpansFrom((Spanned) text, 0, text.length(),                               Object.class, sp, 0);                       return sp;                   } else {                       return text + String.valueOf(mTokenizer);                   }               }           }              public void setToken(char token) {               mTokenizer = token;           }              public char getToken() {               return mTokenizer;           }       }   }   今天主要的內容就在這個文件中,先來看看 [java]  private static final Callable<List<String>> LIST_FILES = new Callable<List<String>>()   Callable接口類似於Runnable,只是他是有返回結果的Runnable , 在他的call方法中做搜索系統文件的工作。  在onCreat函數中有下面代碼: [java]   mExecutor = Executors.newCachedThreadPool();           mListFileTask = mExecutor.submit(LIST_FILES);   這段代碼第一句創建了一個線程池,第二句將ListFILES提交到線程池進行處理。接下來的代碼: [java]   mExecutor.submit(new Runnable() {               @SuppressLint("HandlerLeak")               public void run() {                   List<String> datas;                   try {                       datas = mListFileTask.get();                   } catch (InterruptedException e) {                       datas = useDefaultData();                   } catch (ExecutionException e) {                       datas = useDefaultData();                   }                   Message msg = mHandler.obtainMessage(MSG_RECEIVE_TASK_DATA);                   msg.obj = datas;                   mHandler.sendMessage(msg);               }              });   這段代碼將一個Runnable提交到線程池執行,mListFileTask.get(); 這句在Callable中的call函數沒有執行完之前一直處於阻塞狀態(不可以放到主線程中),得到數據後發送消息更新UI。   在init函數中有這麼一句:   [java]   mShowMulti.setTokenizer(mCustomerToken);   表示使用的是自定義的Tokenizer,他的定義如下 [java]   SelfDedineTokenizer mCustomerToken = new SelfDedineTokenizer(';');   這樣看到的效果跟圖二的就有點不同了哦 ^_^......   3、 完善真個工程,下面滴內容也是不可少滴。也寫了幾個控件了,看看現在ViewData.java中的內容   [java]   package com.xy.zt.selfdefinewieget.data;      import java.util.ArrayList;      final public class ViewData {          public final static ArrayList<ViewData> View_Datas = new ArrayList<ViewData>();          public static final int TEXT_VIEW_ID = 90000;       public static final String TEXT_VIEW_NAME = "TextView";          public static final int BUTTON_ID = TEXT_VIEW_ID + 1;       public static final String BUTTON_NAME = "Button";          public static final int EDIT_TEXT_ID = BUTTON_ID + 1;       public static final String EDIT_TEXT_NAME = "EditText";          public static final int AUTO_COMPLETE_TEXTVIEW_ID = EDIT_TEXT_ID + 1;       public static final String AUTO_COMPLETE_TEXTVIEW_NAME = "AutoCompleteTextView";          public static final int MULTI_AUTO_COMPLETE_TEXTVIEW_ID = AUTO_COMPLETE_TEXTVIEW_ID + 1;       public static final String MULTI_AUTO_COMPLETE_TEXTVIEW_NAME = "MultiAutoCompleteTextView";          private static final ViewData mTextView = new ViewData(TEXT_VIEW_NAME,               TEXT_VIEW_ID);       private static final ViewData mButton = new ViewData(BUTTON_NAME, BUTTON_ID);       private static final ViewData mEditText = new ViewData(EDIT_TEXT_NAME,               EDIT_TEXT_ID);       private static final ViewData mAutoCompleteTextView = new ViewData(               AUTO_COMPLETE_TEXTVIEW_NAME, AUTO_COMPLETE_TEXTVIEW_ID);       private static final ViewData mMultiAutoCompleteTextView = new ViewData(               MULTI_AUTO_COMPLETE_TEXTVIEW_NAME, MULTI_AUTO_COMPLETE_TEXTVIEW_ID);          public final String mViewName;       public final int mViewId;          private ViewData(String name, int id) {           mViewName = name;           mViewId = id;       }          static {           View_Datas.add(mTextView);           View_Datas.add(mButton);           View_Datas.add(mEditText);           View_Datas.add(mAutoCompleteTextView);           View_Datas.add(mMultiAutoCompleteTextView);       }   }     最後在WidgetsAdapter的handleItemClicked函數中加入如下內容: [java]   case ViewData.MULTI_AUTO_COMPLETE_TEXTVIEW_ID:               intent.setClass(mContext, WidgetMultiAutoCompleteActivity.class);               mContext.startActivity(intent);               break;   handleItemClicked 最新內容如下: [java]   private void handleItemClicked(int action) {           Intent intent = new Intent();           switch (action) {           case ViewData.TEXT_VIEW_ID:               intent.setClass(mContext, WidgetTextView.class);               mContext.startActivity(intent);               break;           case ViewData.BUTTON_ID:               intent.setClass(mContext, WidgetButtonActivity.class);               mContext.startActivity(intent);               break;           case ViewData.EDIT_TEXT_ID:               intent.setClass(mContext, WidgetEditTextActivity.class);               mContext.startActivity(intent);               break;           case ViewData.AUTO_COMPLETE_TEXTVIEW_ID:               intent.setClass(mContext, WidgetAutoCompleteActivity.class);               mContext.startActivity(intent);               break;           case ViewData.MULTI_AUTO_COMPLETE_TEXTVIEW_ID:               intent.setClass(mContext, WidgetMultiAutoCompleteActivity.class);               mContext.startActivity(intent);               break;           }       }     MultiAutoCompleteTextView 就介紹到這裡了,下一個控件 Toast 。  
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved