2012-05-14 31 views
4

我想通過搜索列表,結果顯示在列表中再次 所以我用addtextchangelistener,但不能找到一種方法,使其與ListView的工作與潛臺詞addTextChangedListener與潛臺詞列表視圖

這裏是我的代碼:

package com.android; 

    import java.io.FileNotFoundException; 
    import java.io.IOException; 
    import java.io.InputStream; 
    import java.io.InputStreamReader; 
    import java.io.LineNumberReader; 
    import java.util.ArrayList; 
    import java.util.HashMap; 
    import java.util.List; 
    import java.util.Map; 
    import java.util.StringTokenizer; 

    import android.app.ListActivity; 
    import android.os.Bundle; 
    import android.text.Editable; 
    import android.text.TextWatcher; 
    import android.util.Log; 
    import android.view.View; 
    import android.widget.ArrayAdapter; 
    import android.widget.EditText; 
    import android.widget.ListView; 
    import android.widget.SimpleAdapter; 
    import android.widget.TextView; 

    public class MyListDemoActivity extends ListActivity { 
     /** Called when the activity is first created. */ 
     TextView tv; 



     //** List<String> content; 

     EditText actv; 
     List<String> arr_sort; 
     //** ArrayAdapter<String> adapter; 
     SimpleAdapter simpleadapter; 
     ListView lv; 

     @Override 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.main); 

      String line = " "; 

      LineNumberReader linenoreader = null; 
      StringTokenizer stringtokanixer = null; 
     //** content = new ArrayList<String>(); 
      List<Map<String,String>> data= new ArrayList<Map<String,String>>(); 

      lv = (ListView) findViewById(android.R.id.list); 

      try { 

       InputStream istream = getResources().openRawResource(R.raw.grelist); 
       InputStreamReader streamreader = new InputStreamReader(istream); 

       linenoreader = new LineNumberReader(streamreader); 
       linenoreader.mark(15); 
      } catch (FileNotFoundException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      }// try catch ends here 

      Log.v("getting", "working"); 

      for(int i=0;i<8;i++) 
      { 
       Map<String,String> datum= new HashMap<String,String>(2); 
       try { 
        line = linenoreader.readLine(); 
        Log.v("item",line); 
       } catch (IOException e) { 

        e.printStackTrace(); 
       } 
       Log.v("getting", line); 
       stringtokanixer = new StringTokenizer(line); 

       String st = stringtokanixer.nextToken(); 
       String meaning=""; 
       while (stringtokanixer.hasMoreTokens()) { 
        meaning +=" " +stringtokanixer.nextToken(); 

       }// for ends 

       // map is used to add word and meaning 
       datum.put("word",st); 
       datum.put("meaning",meaning); 
       data.add(datum); 

       //List<String> is usedto add 
     //**  content.add(st); 
      } 


      simpleadapter = new SimpleAdapter(this, data, android.R.layout.simple_list_item_2, new String[]{"word","meaning"}, new int[]{android.R.id.text1,android.R.id.text2}); 

      // setListAdapter(adapter); 

      lv.setAdapter(simpleadapter); 
      tv = (TextView) findViewById(R.id.textView1); 

      actv = (EditText) findViewById(R.id.editText1); 


      /* 
       actv.addTextChangedListener(new TextWatcher() { 
       int len = 0; 


       @Override 
       public void onTextChanged(CharSequence s, int start, int before, 
         int count) { 
         arr_sort = new ArrayList<String>(); 

         len = actv.getText().length(); 

         for (int i = 0; i < content.size(); i++) { 
          if (len <= content.get(i).length()) { 
           if (actv.getText() 
             .toString() 
             .trim() 
             .equalsIgnoreCase(
               (String) content.get(i).subSequence(0, 
                 len))) { 

            arr_sort.add(content.get(i)); 
            Log.v("infor loop afterTextChanged", s.toString()); 
           } 

          } 

         } 

      //   adapter.notifyDataSetChanged(); 

         adapter = new ArrayAdapter<String>(MyListDemoActivity.this, 
          android.R.layout.simple_list_item_1, arr_sort); 
         setListAdapter(adapter); 
       } 

       @Override 
       public void beforeTextChanged(CharSequence s, int start, int count, 
         int after) { 
         Log.v("beforetextchange","hello here"); 
       } 

       @Override 
       public void afterTextChanged(Editable s) { 
        Log.v("aftertextchange","hello here"); 

       } 
      }); // text watcher class ends here 
    */ 


     }// on create ends here 

     public void onListItemClick(ListView ls, View v, int position, long id) { 
      //tv.setText(content.get(position)); 

      // tv.setText(content[position]) // in case of string 

     }// endsd here onListItemClick(
    } 

回答

2

這是我如何會改變你的代碼,使其工作:

我會刪除arr_sort變量,並添加其他的MapsArrayList用於固定過濾值:

// List<String> arr_sort; 
    final ArrayList<Map<String, String>> data = 
     new ArrayList<Map<String, String>>(); 
    final ArrayList<Map<String, String>> filteredData = 
     new ArrayList<Map<String, String>>(); 

我也想讓他們最終,因爲沒有點分配完全新的價值給他們,而我們可以通過修改其內容。

2.simpleadapter應始終顯示過濾後的數據,所以它必須被修改:

filteredData.addAll(data); // fill up filteredData initially with the whole list 
simpleadapter = new SimpleAdapter(this, filteredData, 
     android.R.layout.simple_list_item_2, 
     new String[] { "word", "meaning" }, 
     new int[] {android.R.id.text1, android.R.id.text2 }); 

3.接着我的過濾代碼從onTextChanged方法移動到afterTextChanged方法,根據輸入的全文執行過濾。使用正則表達式也少的資源消耗比所有的字符串操作(+,子...)

這樣你TextWatcher實現會是什麼樣子:

actv.addTextChangedListener(new TextWatcher() 
{ 
    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) 
    {} 

    @Override 
    public void beforeTextChanged(CharSequence s,int start,int count,int after) 
    {} 

    @Override 
    public void afterTextChanged(Editable s) 
    { 
     Log.v("MLDA", "afterTextChanged"); 
     // a temporary source list for better performance: 
     // if it's possible, use the smaller filtered list 
     final ArrayList<Map<String, String>> tmpSource = 
      new ArrayList<Map<String,String>>(); 
     tmpSource.addAll(
      (filterText.length() > 0 && s.toString().contains(filterText)) 
      ? filteredData : data); 
     filterText = s.toString(); 

     // a temporary result list to fill with the filtered data 
     final ArrayList<Map<String, String>> tmpResult = 
      new ArrayList<Map<String,String>>(); 

     if (filterText.length() == 0) 
      tmpResult.addAll(data); //if no filter, return the base data 
     else 
     { 
      final Pattern pattern = 
       Pattern.compile("(?i)" + Pattern.quote(s.toString())); 
      Matcher matcher; 
      for (final Map<String, String> map : tmpSource) 
      { 
       //first match against the "word": 
       matcher = pattern.matcher(map.get("word")); 
       if (!matcher.find()) 
       { 
        //if no matches were found, try to match the "meaning" 
        matcher = pattern.matcher(map.get("meaning")); 
        if (!matcher.find()) 
         continue; //if no match, move to the next map 
       } 
       tmpResult.add(map); //match found: add to new list 
      } 
     } 

     filteredData.clear(); 
     filteredData.addAll(tmpResult); 
     simpleadapter.notifyDataSetChanged(); // update display 
    } 
}); 

使用臨時表的工作可以讓你建立全過濾的數據沒有gui更新(如果直接刪除/添加項目到filteredData列表,適配器將觸發更新方法)。

另請注意,通過檢查新過濾器文本是否包含舊過濾器文本,我們可以使用當前的filteredData列表作爲源。

同樣,如果filterText是一個空字符串,沒有意義執行任何匹配,我們可以簡單地返回base列表。

+1

+1爲說明Excellent .. –

+1

感謝它的工作... –

1
ArrayList<String> tempList ; 
edtText.addTextChangedListener(new TextWatcher() { 
      @Override 
      public void onTextChanged(CharSequence s, int start, int before, int count) { 
       // TODO Auto-generated method stub 
      } 

      @Override 
      public void beforeTextChanged(CharSequence s, int start, int count, 
        int after) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void afterTextChanged(Editable s) { 
       // TODO Auto-generated method stub 
       if (!edtText.getText().toString().equalsIgnoreCase("")){ 
        tempList = new ArrayList<String>(); 
        tempList.clear(); 
        String text = filterText.getText().toString(); 
        for(int i=0 ;i< listname.size();i++){ 
         //if(globalconstant.mosq_list.get(globalconstant.hashformosq.get(globalconstant.tempList.get(i))).name.toUpperCase().toString().contains(text.toUpperCase())){ 
         if(listname.get(i).toUpperCase().toString().contains(text.toUpperCase())){ 
          tempList.add(listname.get(i)); 
         } 
        } 
       used changed tempList 
       }else{ 

        unchaged tempList 
       } 
      } 
     }); 
    } 
3

我的理解是: - 只要你想篩選ListView。對?

讓我知道如果我誤解了這個問題!

main.xml中

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" 
    android:layout_width="fill_parent" android:layout_height="fill_parent"> 

    <EditText android:id="@+id/search" android:layout_width="fill_parent" android:layout_height="wrap_content" 
     android:inputType="text" /> 

    <ListView android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" /> 

</LinearLayout> 

ListViewSearchActivity

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 

import android.app.Activity; 
import android.os.Bundle; 
import android.text.Editable; 
import android.text.TextWatcher; 
import android.widget.EditText; 
import android.widget.ListView; 
import android.widget.SimpleAdapter; 

public class ListViewSearchActivity extends Activity implements TextWatcher { 

    private SimpleAdapter simpleAdapter; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.main); 

     EditText search = (EditText) findViewById(R.id.search); 
     search.addTextChangedListener(this); 

     List<Map<String, String>> data = new ArrayList<Map<String, String>>(); 
     for(int i=0;i<8;i++) { 
      Map<String,String> map = new HashMap<String, String>(2); 
      map.put("word", "word " + i); 
      map.put("meaning", "meaning " + (i + 10)); 
      data.add(map); 
     } 

     ListView listView = (ListView) findViewById(R.id.list); 
     this.simpleAdapter = new SimpleAdapter(this, data, android.R.layout.simple_list_item_2, new String[]{"word","meaning"}, new int[]{android.R.id.text1,android.R.id.text2}); 
     listView.setAdapter(this.simpleAdapter); 
    } 

    @Override 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
    } 

    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
    } 

    @Override 
    public void afterTextChanged(Editable s) { 
     this.simpleAdapter.getFilter().filter(s.toString()); 
    } 

} 
4

我在兩個StackOverflow的問題,本身你可以把它們已經回答了,

首先使用getFilter()是android提供了使用Filt進行過濾適配器類的可修改接口。您可以從here查詢。

其次是使用外部罐子Lambdaj這是從列表過濾大量數據的最佳和有效的方式。您也可以從here檢查。