Au cas où quelqu'un serait encore intéressé par ce sujet, je trouve que la meilleure approche pour filtrer des listes est de créer une classe Filter générique et de l'utiliser avec quelques techniques de base de réflexion/générique contenues dans le paquetage Java old school SDK. Voici ce que j'ai fait :
public class GenericListFilter<T> extends Filter {
/**
* Copycat constructor
* @param list the original list to be used
*/
public GenericListFilter (List<T> list, String reflectMethodName, ArrayAdapter<T> adapter) {
super ();
mInternalList = new ArrayList<>(list);
mAdapterUsed = adapter;
try {
ParameterizedType stringListType = (ParameterizedType)
getClass().getField("mInternalList").getGenericType();
mCompairMethod =
stringListType.getActualTypeArguments()[0].getClass().getMethod(reflectMethodName);
}
catch (Exception ex) {
Log.w("GenericListFilter", ex.getMessage(), ex);
try {
if (mInternalList.size() > 0) {
T type = mInternalList.get(0);
mCompairMethod = type.getClass().getMethod(reflectMethodName);
}
}
catch (Exception e) {
Log.e("GenericListFilter", e.getMessage(), e);
}
}
}
/**
* Let's filter the data with the given constraint
* @param constraint
* @return
*/
@Override protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
List<T> filteredContents = new ArrayList<>();
if ( constraint.length() > 0 ) {
try {
for (T obj : mInternalList) {
String result = (String) mCompairMethod.invoke(obj);
if (result.toLowerCase().startsWith(constraint.toString().toLowerCase())) {
filteredContents.add(obj);
}
}
}
catch (Exception ex) {
Log.e("GenericListFilter", ex.getMessage(), ex);
}
}
else {
filteredContents.addAll(mInternalList);
}
results.values = filteredContents;
results.count = filteredContents.size();
return results;
}
/**
* Publish the filtering adapter list
* @param constraint
* @param results
*/
@Override protected void publishResults(CharSequence constraint, FilterResults results) {
mAdapterUsed.clear();
mAdapterUsed.addAll((List<T>) results.values);
if ( results.count == 0 ) {
mAdapterUsed.notifyDataSetInvalidated();
}
else {
mAdapterUsed.notifyDataSetChanged();
}
}
// class properties
private ArrayAdapter<T> mAdapterUsed;
private List<T> mInternalList;
private Method mCompairMethod;
}
Ensuite, la seule chose à faire est de créer le filtre en tant que classe membre (éventuellement dans le "onCreate" de la vue) en passant la référence de votre adaptateur, votre liste et la méthode à appeler pour le filtrage :
this.mFilter = new GenericFilter<MyObjectBean> (list, "getName", adapter);
La seule chose qui manque maintenant, c'est de surcharger la méthode "getFilter" dans la classe de l'adaptateur :
@Override public Filter getFilter () {
return MyViewClass.this.mFilter;
}
Tout est fait ! Vous devriez réussir à filtrer votre liste - Bien sûr, vous devez également mettre en œuvre votre algorithme de filtrage de la meilleure façon possible pour répondre à vos besoins. Le code ci-dessous n'est qu'un exemple. . J'espère que cela vous a aidé, prenez soin de vous.
1 votes
Bonjour, essayez cet exemple Premier exemple et le second Exemple 2 J'ai mis en œuvre la même chose sur la base de ce tutoriel. J'espère que cela vous aidera.
5 votes
La réponse du haut n'a pas fourni assez d'informations pour moi. Cette réponse à une question similaire a plus de contexte, et était exactement assez d'informations pour me permettre de m'en sortir.
0 votes
Je suis en train d'utiliser une vue de recyclage, je veux filtrer les enregistrements mais j'utilise des boutons personnalisés pour donner une entrée au texte d'édition comme un clavier personnalisé mais j'obtiens un retard sur le clic rapide du bouton, pouvez-vous m'aider à sortir de cela ?