На самом деле
я заметил, что я должен был с помощью списка «originalItems», чтобы построить новый отфильтрованный один в performFiltering.
Это устранит любые проблемы, которые вы видите относительно изменения текста в фильтре. Например. вы ищите «Хлеб», а затем обратно - просто «B», и вы должны увидеть все «B». В моем оригинальном посте у вас не было бы.
private class GlycaemicIndexItemAdapter extends ArrayAdapter<GlycaemicIndexItem> {
private ArrayList<GlycaemicIndexItem> items;
private ArrayList<GlycaemicIndexItem> originalItems = new ArrayList<GlycaemicIndexItem>();
private GlycaemicIndexItemFilter filter;
private final Object mLock = new Object();
public GlycaemicIndexItemAdapter(Context context, int textViewResourceId, ArrayList<GlycaemicIndexItem> newItems) {
super(context, textViewResourceId, newItems);
this.items = newItems;
cloneItems(newItems);
}
protected void cloneItems(ArrayList<GlycaemicIndexItem> items) {
for (Iterator iterator = items.iterator(); iterator
.hasNext();) {
GlycaemicIndexItem gi = (GlycaemicIndexItem) iterator.next();
originalItems.add(gi);
}
}
@Override
public int getCount() {
synchronized(mLock) {
return items!=null ? items.size() : 0;
}
@Override
public GlycaemicIndexItem getItem(int item) {
GlycaemicIndexItem gi = null;
synchronized(mLock) {
gi = items!=null ? items.get(item) : null;
}
return gi;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row, null);
}
GlycaemicIndexItem i = null;
synchronized(mLock) {
i = items.get(position);
}
if (i != null) {
TextView tt = (TextView) v.findViewById(R.id.rowText);
TextView bt = (TextView) v.findViewById(R.id.rowText2);
if (tt != null) {
tt.setText("Name: "+i.getName());
}
if(bt != null){
bt.setText("GI Value: " + i.getGlycaemicIndex());
}
}
return v;
}
/**
* Implementing the Filterable interface.
*/
public Filter getFilter() {
if (filter == null) {
filter = new GlycaemicIndexItemFilter();
}
return filter;
}
/**
* Custom Filter implementation for the items adapter.
*
*/
private class GlycaemicIndexItemFilter extends Filter {
protected FilterResults performFiltering(CharSequence prefix) {
// Initiate our results object
FilterResults results = new FilterResults();
// No prefix is sent to filter by so we're going to send back the original array
if (prefix == null || prefix.length() == 0) {
synchronized (mLock) {
results.values = originalItems;
results.count = originalItems.size();
}
} else {
synchronized(mLock) {
// Compare lower case strings
String prefixString = prefix.toString().toLowerCase();
final ArrayList<GlycaemicIndexItem> filteredItems = new ArrayList<GlycaemicIndexItem>();
// Local to here so we're not changing actual array
final ArrayList<GlycaemicIndexItem> localItems = new ArrayList<GlycaemicIndexItem>();
localItems.addAll(originalItems);
final int count = localItems.size();
for (int i = 0; i < count; i++) {
final GlycaemicIndexItem item = localItems.get(i);
final String itemName = item.getName().toString().toLowerCase();
// First match against the whole, non-splitted value
if (itemName.startsWith(prefixString)) {
filteredItems.add(item);
} else {} /* This is option and taken from the source of ArrayAdapter
final String[] words = itemName.split(" ");
final int wordCount = words.length;
for (int k = 0; k < wordCount; k++) {
if (words[k].startsWith(prefixString)) {
newItems.add(item);
break;
}
}
} */
}
// Set and return
results.values = filteredItems;
results.count = filteredItems.size();
}//end synchronized
}
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence prefix, FilterResults results) {
//noinspection unchecked
synchronized(mLock) {
final ArrayList<GlycaemicIndexItem> localItems = (ArrayList<GlycaemicIndexItem>) results.values;
notifyDataSetChanged();
clear();
//Add the items back in
for (Iterator iterator = localItems.iterator(); iterator
.hasNext();) {
GlycaemicIndexItem gi = (GlycaemicIndexItem) iterator.next();
add(gi);
}
}//end synchronized
}
}
}
В принципе я строй приложения для здоровья и питания и один экран будет иметь список элементов на основе гликемического/гликемический индекс. Я хочу, чтобы пользователи могли печатать и иметь экранный автофильтр. Теперь, если вы используете только строки, вы бесплатно получаете автофильтр. Я не знаю, у меня есть свой собственный класс GlycaemicIndexItem, который имеет свойства на нем. Мне нужно предоставить свою собственную фильтрацию, чтобы убедиться, что список, используемый для рисования на экране, обновляется, когда пользователь набирает.
В настоящее время экран является простым ListActivity, с ListView и EditText (который пользователь вводит). Мы добавим TextWatcher в этот EditText, чтобы гарантировать, что мы будем уведомлены об обновлениях. Это означает, что он должен работать на всех устройствах независимо от ввода пользователем жесткой или мягкой клавиатуры (у меня есть HTC DesireZ и старый G1).
Вот макет XML для экрана/активности (Может кто-нибудь сказать мне, как вставить код XML в здесь, как и когда я пытаюсь использовать блок кода XML не получает вставили/отображается правильно, но интерпретированы):
Как мы хотим показать наши строки в пользовательском стиле, у нас есть файл XML макет для самой строки:
Вот код для самой всей деятельности. Расширяясь от ListActivity, этот класс имеет внутренний класс, который действует как адаптер, который распространяется от ArrayAdapter. Это создается в onCreate для Activity и теперь содержит простой список строк. Обратите внимание на то, как он создается на линиях 39-40. Наш специальный макет для строки передается вместе со списком элементов.
Ключом к заполнению пользовательских строк является метод адаптера getView.
Наш адаптерный класс также имеет собственный внутренний класс GlycaemicIndexItemFilter, который выполняет работу, когда пользователь вводит данные. Наш фильтр привязан к нашему EditText на строках 43-44 с использованием TextWatcher и его метода afterTextChanged. Линия 47 - это ключ к тому, как мы добиваемся фильтрации. Мы называем фильтр на нашем объекте фильтра. Наш фильтр создается, когда мы вызываем getFilter в первый раз, строка 148-149.
package com.tilleytech.android.myhealthylife;
import java.util.ArrayList;
import java.util.Iterator;
import android.app.ListActivity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.ListView;
import android.widget.TextView;
public class GlycaemicIndexAtoZActivity extends ListActivity {
/** Called when the activity is first created. */
private GlycaemicIndexItemAdapter giAdapter;
private TextWatcher filterTextWatcher;
private EditText filterText = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.giatoz);
ListView lv = getListView();
lv.setTextFilterEnabled(true);
// By using setAdapter method in listview we an add string array in list.
ArrayList<GlycaemicIndexItem> list = getListItems();
giAdapter = new GlycaemicIndexItemAdapter(this, R.layout.row, list);
giAdapter.notifyDataSetChanged();
setListAdapter(giAdapter);
filterText = (EditText)findViewById(R.id.GI_AtoZSearchEditText);
filterTextWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
giAdapter.getFilter().filter(s); //Filter from my adapter
giAdapter.notifyDataSetChanged(); //Update my view
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
};
filterText.addTextChangedListener(filterTextWatcher);
}
private ArrayList<GlycaemicIndexItem> getListItems() {
ArrayList<GlycaemicIndexItem> result = new ArrayList<GlycaemicIndexItem>();
Resources res = getResources();
//Get our raw strings
String[] array = res.getStringArray(R.array.GIList);
for (int i = 0; i < array.length; i++) {
GlycaemicIndexItem gi = new GlycaemicIndexItem();
gi.setName(array[i]);
gi.setGlycaemicIndex(1);
result.add(gi);
}
return result;
}
private class GlycaemicIndexItemAdapter extends ArrayAdapter<GlycaemicIndexItem> {
private ArrayList<GlycaemicIndexItem> items;
private ArrayList<GlycaemicIndexItem> originalItems = new ArrayList<GlycaemicIndexItem>();
private GlycaemicIndexItemFilter filter;
private final Object mLock = new Object();
public GlycaemicIndexItemAdapter(Context context, int textViewResourceId, ArrayList<GlycaemicIndexItem> newItems) {
super(context, textViewResourceId, newItems);
this.items = newItems;
cloneItems(newItems);
}
protected void cloneItems(ArrayList<GlycaemicIndexItem> items) {
for (Iterator iterator = items.iterator(); iterator
.hasNext();) {
GlycaemicIndexItem gi = (GlycaemicIndexItem) iterator.next();
originalItems.add(gi);
}
}
@Override
public int getCount() {
synchronized(mLock) {
return items!=null ? items.size() : 0;
}
}
@Override
public GlycaemicIndexItem getItem(int item) {
GlycaemicIndexItem gi = null;
synchronized(mLock) {
gi = items!=null ? items.get(item) : null;
}
return gi;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row, null);
}
GlycaemicIndexItem i = null;
synchronized(mLock) {
i = items.get(position);
}
if (i != null) {
TextView tt = (TextView) v.findViewById(R.id.rowText);
TextView bt = (TextView) v.findViewById(R.id.rowText2);
if (tt != null) {
tt.setText("Name: "+i.getName());
}
if(bt != null){
bt.setText("GI Value: " + i.getGlycaemicIndex());
}
}
return v;
}
/**
* Implementing the Filterable interface.
*/
public Filter getFilter() {
if (filter == null) {
filter = new GlycaemicIndexItemFilter();
}
return filter;
}
/**
* Custom Filter implementation for the items adapter.
*
*/
private class GlycaemicIndexItemFilter extends Filter {
protected FilterResults performFiltering(CharSequence prefix) {
// Initiate our results object
FilterResults results = new FilterResults();
// No prefix is sent to filter by so we're going to send back the original array
if (prefix == null || prefix.length() == 0) {
synchronized (mLock) {
results.values = originalItems;
results.count = originalItems.size();
}
} else {
synchronized(mLock) {
// Compare lower case strings
String prefixString = prefix.toString().toLowerCase();
final ArrayList<GlycaemicIndexItem> filteredItems = new ArrayList<GlycaemicIndexItem>();
// Local to here so we're not changing actual array
final ArrayList<GlycaemicIndexItem> localItems = new ArrayList<GlycaemicIndexItem>();
localItems.addAll(originalItems);
final int count = localItems.size();
for (int i = 0; i < count; i++) {
final GlycaemicIndexItem item = localItems.get(i);
final String itemName = item.getName().toString().toLowerCase();
// First match against the whole, non-splitted value
if (itemName.startsWith(prefixString)) {
filteredItems.add(item);
} else {} /* This is option and taken from the source of ArrayAdapter
final String[] words = itemName.split(" ");
final int wordCount = words.length;
for (int k = 0; k < wordCount; k++) {
if (words[k].startsWith(prefixString)) {
newItems.add(item);
break;
}
}
} */
}
// Set and return
results.values = filteredItems;
results.count = filteredItems.size();
}//end synchronized
}
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence prefix, FilterResults results) {
//noinspection unchecked
synchronized(mLock) {
final ArrayList<GlycaemicIndexItem> localItems = (ArrayList<GlycaemicIndexItem>) results.values;
notifyDataSetChanged();
clear();
//Add the items back in
for (Iterator iterator = localItems.iterator(); iterator
.hasNext();) {
GlycaemicIndexItem gi = (GlycaemicIndexItem) iterator.next();
add(gi);
}
}//end synchronized
}
}
}
}
http://stackoverflow.com/questions/2718202/custom-filtering-in-android-using-arrayadapter - похоже, что это может ответить на ваш вопрос – stealthcopter
@Anton: Hav U решил it.please ответ .. ....... –