2013-05-14 77 views
-1

我正在面臨問題,同時過濾列表。我正在使用onTextChange()方法。它工作正常,但問題是,因爲我在編輯中鍵入單個字符文本軟鍵盤獲取消失並且我必須再次點擊編輯文本才能輸入完整的字符串。我也已經完成了代碼,以便軟鍵盤在文本更改後不會消失,但仍然需要點擊編輯文本。以下是我的代碼:在列表視圖過濾不能正常工作

search.addTextChangedListener(new TextWatcher() { 
     @ Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 
      // TODO Auto-generated method stub 
      String startwith = s.toString(); 
      ArrayList <Myshares> filterList = new ArrayList <Myshares>(); 
      for (int i = 0; i < fileList.size(); i++) { 
       if (fileList.get(i).getName().toLowerCase().startsWith(startwith) || fileList.get(i).getName().toUpperCase().startsWith(startwith)) { 
        filterList.add(fileList.get(i)); 
       } 
      } 
      adapter = new MListAdapter(PlayListActivity.this, filterList); 

      playListView.setAdapter(adapter); 
      adapter.notifyDataSetChanged(); 

     } 
     @ 
     Override 
     public void beforeTextChanged(CharSequence s, int start, int count, 
      int after) {  
     } 
     @ 
     Override 
     public void afterTextChanged(Editable s) { 
      search.setSelection(search.getText().length()); 
      InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
      imm.showSoftInput(search, InputMethodManager.SHOW_IMPLICIT); 
     } 
    }); 

這裏是編輯的文字我的XML代碼:

<EditText 
     android:ems="10" 
     android:id="@+id/search_bar" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:layout_margin="5dp" 
     android:layout_weight="2" 
     android:background="@drawable/searchbox" 
     android:editable="true" 
     android:focusable="true" 
     android:inputType="textFilter" 
     android:hint="Search" 
     android:keepScreenOn="true" 
     android:paddingLeft="10dp" 
     android:textSize="15dp" /> 

我還在列表視圖中設置了android:focusable =「false」屬性,以便它不重疊軟鍵盤。但與編輯文本的問題還是一樣。這裏是截圖

enter image description here

當我插入一個字符列表得到過濾器和光標從編輯文本框消失了。

enter image description here

+0

http://chat.stackoverflow.com/rooms/1278/android-discussion – 2013-05-17 07:07:33

+1

你可以閱讀我的答案從[這裏](http://stackoverflow.com/questions/16536663/how-to-add-search -function-on-list-view-items-in-listview-are-from-baseadap/16536801#16536801)關於這個問題我希望這會有所幫助 – 2013-05-14 13:09:09

回答

1

我通過ArrayAdapter的實際源代碼去了,它看起來就像是實際寫入的行爲是那樣。

ArrayAdapter有兩個以mObjects和mOriginalValues開始的列表。 mObjects是適配器將使用的主要數據集。服用add()函數,例如:

public void add(T object) { 
    if (mOriginalValues != null) { 
    synchronized (mLock) { 
     mOriginalValues.add(object); 
     if (mNotifyOnChange) notifyDataSetChanged(); 
    } 
} else { 
    mObjects.add(object); 
    if (mNotifyOnChange) notifyDataSetChanged(); 
} 

}

mOriginalValues最初空,因此所有操作(添加,插入,刪除,清除)默認情況下有針對性地mObjects。這一切都很好,直到您決定在列表中啓用篩選並實際執行篩選爲止。現在

private class ArrayFilter extends Filter { 
    @Override 
    protected FilterResults performFiltering(CharSequence prefix) { 
    FilterResults results = new FilterResults(); 
    if (mOriginalValues == null) { 
     synchronized (mLock) { 
      mOriginalValues = new ArrayList<T>(mObjects); 
      //mOriginalValues is no longer null 
     } 
    } 
    if (prefix == null || prefix.length() == 0) { 
     synchronized (mLock) { 
      ArrayList<T> list = new ArrayList<T>(mOriginalValues); 
      results.values = list; 
      results.count = list.size(); 
     } 
    } else { 
     //filtering work happens here and a new filtered set is stored in newValues 
     results.values = newValues; 
     results.count = newValues.size(); 
    } 
    return results; 
    } 
@Override 
protected void publishResults(CharSequence constraint, FilterResults results) { 
    //noinspection unchecked 
    mObjects = (List<T>) results.values; 
    if (results.count > 0) { 
     notifyDataSetChanged(); 
    } else { 
     notifyDataSetInvalidated(); 
    } 
    } 
} 

mOriginalValues擁有的,以及副本,原始值/項目,因此該適配器可以做其工作,並顯示過濾列表:過濾首次初始化mOriginalValues與任何mObjects有通過mObjects而不會丟失預過濾的數據。

如果我的想法不正確,現在請原諒我(並且請告訴並解釋),但我覺得這很奇怪,因爲現在mOriginalValues不再爲空,所有後續對任何適配器操作的調用都只會修改mOriginalValues。但是,由於適配器被設置爲將mObjects作爲其主數據集,因此它將出現在屏幕上,沒有任何事情發生。這是直到你執行另一輪過濾。拆卸過濾器觸發此:

if (prefix == null || prefix.length() == 0) { 
     synchronized (mLock) { 
      ArrayList<T> list = new ArrayList<T>(mOriginalValues); 
      results.values = list; 
      results.count = list.size(); 
     } 
    } 

mOriginalValues,這是我們一直以來我們的第一濾波器修改(雖然我們無法看到它發生在屏幕上)存儲在另一個列表,並複製到mObjects,最後顯示所做的更改。不過,從這一點開始,它將會是這樣的:所有操作都將在mOriginalValues上完成,並且更改只會在過濾之後出現。

至於解決方案,我現在想出的是(1)放置一個布爾標誌,告訴適配器操作是否存在正在進行的過濾 - 如果過濾完成,則將mOriginalValues的內容複製到mObjects,或者(2)簡單地調用適配器的Filter對象,並在每次操作之後傳遞一個空字符串* .getFilter()。filter(「」)來強制過濾器[也可以參考Santhosh的建議] 。

如果有人能夠解決這個問題或確認我剛剛做了什麼,我們將非常感謝。謝謝!

+0

謝謝先生,但我根本沒有使用陣列適配器。 – 2013-05-17 07:13:53

+0

試試這個方法.. – 2013-05-17 07:27:17

0
//ArrayAdapter Definition. Make it activity class field. 
ArrayAdapter<String> adapter; 

//initialize the adapter by loading complete data and set Adapter to ListView. 
//**Note: I have used ArrayList<String> below.** 
ArrayList <String> filterList = new ArrayList <Myshares>(); 

for (int i = 0; i < fileList.size(); i++) { 
      if (fileList.get(i).getName().toLowerCase() || fileList.get(i).getName().toUpperCase()) { 
       filterList.add(fileList.get(i)); 
      } 
     } 

adapter = new ArrayAdapter<String>(this, R.layout.searchresult_item, R.id.search_item_name,filterList); 

//Here, searchresult_item is the layout file name. and search_item_name is the Textview inside it. 

search.addTextChangedListener(new TextWatcher() { 

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

     YourActivity.this.Youradapter.getFilter().filter(cs); 

} 

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


} 

@Override 
public void afterTextChanged(Editable s) { 


} 
}); 
+0

我需要爲我的適配器定義getFilter()方法,因爲我正在使用自定義適配器 – 2013-05-14 13:33:22

+0

檢查我編輯的答案。我還沒有使用自定義適配器。我不認爲你可以在你的適配器中覆蓋或定義getFilter()方法。如果它只有一個字段被填充到列表視圖中,我認爲你可以使用上面的方法。其簡單,工作正常。 – SKK 2013-05-14 19:37:50

+0

@ Santhosh謝謝你的回覆,但我沒有過濾問題。它工作正常,但問題是,我不得不點擊編輯文本插入單個字符將光標移回.. – 2013-05-15 05:43:46

0

我想你已經通過addView()方法在列表視圖中添加了編輯文本。它確實發生了,因爲所有的視圖都被重新繪製,所以表示任何用於聚焦的行的編輯文本現在是一個完全不同的對象。在適配器中設置一個變量:int currentlyFocusedRow;

在getView

您的適配器: 添加onFocusChanged監聽器來編輯文本 和當編輯文本獲得焦點,設置 currentlyFocusedRow(int變量)=一行重點(含)編輯文本恰好是在同樣設置。任何在currentlyFocusedRow中被編輯的文本將被聚焦。

回覆我,如果你看到這個問題。