En fait
je remarquai que je suis en utilisant la liste des originalItems de construire le nouveau filtre dans un performFiltering.
Ceci corrigera tous les problèmes que vous voyez concernant la modification du texte dans le filtre. Par exemple. vous recherchez 'Pain' puis retour arrière à juste un 'B' et vous devriez voir tous les 'B'. Dans mon post original, vous n'auriez pas.
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
}
}
}
Fondamentalement, je fais construire une application de santé et de nutrition et un écran aura une liste d'éléments en fonction de l'index glycémique/glycémique. Je veux que les utilisateurs puissent taper et avoir l'autofiltre d'écran. Maintenant, si vous n'utilisez que des chaînes, vous obtiendrez un autofiltrage gratuit. Je ne suis pas cependant, j'ai ma propre classe personnalisée GlycaemicIndexItem qui a des propriétés dessus. Je dois fournir mon propre filtrage pour m'assurer que la liste utilisée à l'écran est mise à jour lorsque l'utilisateur tape.
Actuellement l'écran est un ListActivity simple, avec un ListView et un EditText (que l'utilisateur tape). Nous allons attacher un TextWatcher à cet EditText pour nous assurer que nous sommes informés des mises à jour. Cela signifie qu'il devrait fonctionner pour tous les appareils indépendamment de l'utilisateur qui tape sur un clavier dur ou un clavier logiciel (j'ai un HTC DesireZ et un vieux G1).
Voici la mise en page XML pour l'écran/activité (Quelqu'un peut-il me dire comment coller le code XML en ici, comme lorsque je tente d'utiliser xml bloc de code ne soit pas collé/afficher correctement, mais interprété):
Comme nous voulons afficher nos lignes dans un style personnalisé, nous avons également un fichier xml de mise en page pour la ligne elle-même:
Voici le code pour toute l'activité elle-même. S'étendant de ListActivity, cette classe a une classe interne qui agit comme l'adaptateur, qui s'étend de ArrayAdapter. Ceci est instancié dans le onCreate de l'activité et passé une simple liste de chaînes pour le moment. Faites attention à la façon dont il est créé sur les lignes 39-40. Notre disposition spéciale pour la ligne est transmise avec la liste des éléments.
La clé permettant de remplir les lignes personnalisées se trouve dans la méthode de l'adaptateur getView.
Notre classe d'adaptateur a également sa propre classe interne appelée GlycaemicIndexItemFilter qui effectue le travail lorsqu'un utilisateur tape. Notre filtre est lié à notre EditText sur les lignes 43-44 par l'utilisation d'un TextWatcher et sa méthode afterTextChanged. La ligne 47 est l'indice quant à la façon dont nous réalisons le filtrage. Nous appelons le filtre, sur notre objet filtre. Notre filtre est créé lorsque nous appelons getFilter pour la première fois, ligne 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 - ressemble à cela pourrait répondre à votre question – stealthcopter
@Anton: HAV u .. it.please réponse résolu ....... –