1. J'ai un ListView
qui contient des images, des noms de personnes, des anniversaires de personnes.
J'ai créé une barre de recherche où elle peut être utilisée pour rechercher le contenu dans la ListView
.
2. J'ai ajouté à la barre de recherche addTextChangedListener , et dans TextWatcher onTextChanged pour obtenir le filtre de l'adaptateur, mais par conséquent, lorsque je recherche un nom de personne, rien ne se passe.
Aussi pendant le débogage, j'ai vérifié que je recevais données de l'adaptateur et onTextchanged le seq de caractères saisi.
3. Activité principale:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:padding="15dp" android:layout_height="match_parent" android:weightSum="100" > <ImageView android:id="@+id/imgP" android:layout_width="399dp" android:layout_height="150dp" android:layout_weight="66.6" /> <RelativeLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="33.3"> <TextView android:gravity="center" android:text="TextView2" android:layout_width="match_parent" android:layout_height="30dp" android:id="@+id/txtView2"/> <TextView android:id="@+id/txtView3" android:layout_width="match_parent" android:layout_height="30dp" android:layout_below="@+id/txtView2" android:gravity="center" android:text="TextView3" /> <RelativeLayout android:layout_width="wrap_content" android:layout_height="match_parent" /> <Button android:id="@+id/btn_add" android:layout_width="69dp" android:layout_height="wrap_content" android:layout_below="@+id/txtView3" android:layout_marginRight="20dp" android:text="ADD" /> <Button android:layout_width="69dp" android:layout_height="wrap_content" android:layout_toRightOf="@+id/btn_add" android:layout_below="@id/txtView3" android:id="@+id/btn_edit" android:text="edit"/> <Button android:layout_width="80dp" android:layout_height="wrap_content" android:layout_toRightOf="@+id/btn_edit" android:layout_below="@+id/txtView3" android:id="@+id/btn_delete" android:text="Delete"/> </RelativeLayout> </LinearLayout>
Classe d'adaptateur de liste d'étudiants:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <EditText android:layout_width="match_parent" android:layout_height="50dp" android:id="@+id/searchFilter"/> <ListView android:id="@+id/li_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" tools:layout_algignParentStart="true" /> </androidx.constraintlayout.widget.ConstraintLayout>
Classe PersonInfo:
public class PersonInfo { private int image; private String name; private String birthday; public PersonInfo(int image, String name, String birthday) { this.image = image; this.name = name; this.birthday = birthday; } public String getName(){ return name; } public int getImage() { return image; } public void setName(String name) { this.name = name; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } }
XML de l'activité principale:
public class StudentsListAdapter extends ArrayAdapter<PersonInfo>{ private Context contxt; private int rsrc; private List<PersonInfo> persons; private boolean isAdmin; public StudentsListAdapter( Context context, int resource, List<PersonInfo> _persons, boolean _isAadmin) { super(context, resource, _persons); contxt = context; rsrc = resource; persons=_persons; isAdmin = _isAadmin; } Filter myFilter = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults filterResults = new FilterResults(); ArrayList<PersonInfo> tempList=new ArrayList<PersonInfo>(); // Add the filter code here if(constraint != null && persons!=null) { int length= persons.size(); int i=0; while(i<length){ PersonInfo item= persons.get(i); //do whatever you wanna do here //adding result set output array String name = item.getName(); if(name.toLowerCase().contains(constraint.toString())) { tempList.add(item); } i++; } //following two lines is very important //as publish result can only take FilterResults users filterResults.values = tempList; filterResults.count = tempList.size(); } return filterResults; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence contraint, FilterResults results) { persons = (ArrayList<PersonInfo>) results.values; if (results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } }; @NonNull @Override public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(contxt); View view = inflater.inflate(rsrc, null,false); ImageView imageView = view.findViewById(R.id.imgP); TextView pName = view.findViewById(R.id.txtView2); TextView pBirthday = view.findViewById(R.id.txtView3); Button btn_add = view.findViewById(R.id.btn_add); Button btn_edit = view.findViewById(R.id.btn_edit); Button btn_delete = view.findViewById(R.id.btn_delete); btn_add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(contxt,AddItems.class) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); contxt.startActivity(intent); } }); if(isAdmin) { btn_add.setVisibility(View.VISIBLE); btn_edit.setVisibility(View.VISIBLE); btn_delete.setVisibility(View.VISIBLE); } else { btn_add.setVisibility(View.GONE); btn_edit.setVisibility(View.GONE); btn_delete.setVisibility(View.GONE); } PersonInfo p = persons.get(position); imageView.setImageDrawable(contxt.getResources().getDrawable(p.getImage())); pBirthday.setText(p.getBirthday()); pName.setText(p.getName()); btn_edit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { persons.get(position); } }); btn_delete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { removePerson(position); } }); return view; } }
Adaptateur XML:
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private Button btn_add,btn_edit,btn_delete; private StudentsListAdapter test1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = getIntent(); String username = intent.getStringExtra("Username"); String password = intent.getStringExtra("Password"); btn_add = findViewById(R.id.btn_add); btn_edit = findViewById(R.id.btn_edit); btn_delete = findViewById(R.id.btn_delete); EditText search = (EditText) findViewById(R.id.searchFilter); ListView listView1 = (ListView) findViewById(R.id.li_view); ArrayList<PersonInfo> students1 = new ArrayList<>(); students1.add(new PersonInfo(android.R.drawable.btn_star, "Julien", "03/27/1998")); students1.add(new PersonInfo(android.R.drawable.btn_star, "Jamaica", "03/27/1998")); students1.add(new PersonInfo(android.R.drawable.btn_star, "Bara", "03/27/1998")); students1.add(new PersonInfo(android.R.drawable.btn_star, "Bere", "03/27/1998")); test1 = new StudentsListAdapter( this, R.layout.adapter_view_layout, students1, true); listView1.setAdapter(test1); search.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { (MainActivity.this).test1.getFilter().filter(s); } @Override public void afterTextChanged(Editable s) { } }); if(username.equals("admin") && password.equals("admin")){ Log.d(TAG, "onCreate: Started."); ListView listView = (ListView) findViewById(R.id.li_view); ArrayList<PersonInfo> students = new ArrayList<>(); students.add(new PersonInfo(android.R.drawable.btn_star, "Amaizing", "03/27/1998")); students.add(new PersonInfo(android.R.drawable.btn_star, "Jamaica", "03/27/1998")); students.add(new PersonInfo(android.R.drawable.btn_star, "But", "03/27/1998")); students.add(new PersonInfo(android.R.drawable.btn_star, "Carmen", "03/27/1998")); test1 = new StudentsListAdapter( this, R.layout.adapter_view_layout, students, true); listView.setAdapter(test1); search.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { (MainActivity.this).test1.getFilter().filter(s.toString()); test1.notifyDataSetChanged(); } @Override public void afterTextChanged(Editable s) { } }); } else if (username.equals("user") && password.equals("user")) { ListView listView = (ListView) findViewById(R.id.li_view); ArrayList<PersonInfo> students = new ArrayList<>(); students.add(new PersonInfo(android.R.drawable.btn_star, "AJ", "03/27/1998")); test1 = new StudentsListAdapter( this, R.layout.adapter_view_layout, students,false); listView.setAdapter(test1); } } }
Qu'est-ce que je fais mal? Toute aide sera fortement appréciée. Merci!
3 Réponses :
J'ai donc vérifié et ce que vous devez faire est d'ajouter un getter dans le StudentsListAdapter
test1 = new StudentsListAdapter( this, R.layout.adapter, students1, true); listView1.setAdapter(test1); search.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { for(PersonInfo person: test1.getPersons()) { if(person.getName().startsWith(s.toString())) { Toast.makeText(MainActivity.this, "ITEM FOUND" + person.getName(), Toast.LENGTH_SHORT).show(); } } } @Override public void afterTextChanged(Editable s) { } });
puis dans votre MainActivity, vous pouvez obtenir la liste et trouver l'élément nécessaire. J'ai fait la recherche et s'il est trouvé, il affiche Toast pour le moment, mais vous pouvez l'ajuster à votre guise. Vous n'avez pas besoin de l'écouteur de texte dans l'adaptateur.
List<PersonInfo> getPersons() { return persons; }
Bonjour, j'ai essayé d'utiliser ce code mais je ne parviens toujours pas à recevoir les détails des articles, vous pouvez jeter un œil ici . Merci!
@FearLessAZ Mon code ne fournit pas de solution complète. Mais à l'intérieur de l'instruction if, vous pouvez obtenir l'élément trouvé, puis effectuer vos actions avec :) Parce que la vérification de votre application ne fonctionnait pas du tout, j'ai donc créé ce code.
Cela ne fonctionnait pas car vous n'avez pas remplacé getFilter (). Vous devez remplacer le getFilter () dans StudentsListAdapter. Veuillez consulter le code ci-dessous.
@Override public int getCount() { return listFiltered.size(); } @Override public PersonInfo getItem(int position) { return listFiltered.get(position); }
Et remplacez également getCount () et getItem ()
List<PersonInfo> listFiltered = new ArrayList<PersonInfo>(); public StudentsListAdapter( Context context, int resource, List<PersonInfo> _persons, boolean _isAadmin) { //... this.listFiltered= _persons; } @Override public Filter getFilter() { return new Filter() { @Override protected FilterResults performFiltering(CharSequence c) { FilterResults results = new FilterResults(); if (c.length() == 0) { results.count = persons.size(); results.values = persons; } else { List<PersonInfo> resultsData = new ArrayList<>(); // This is just for your reference please get the data accordingly for (PersonInfo s : persons) if (s.getName().contains(c)) resultsData.add(s); results.count = resultsData.size(); results.values = resultsData; } return results; } @Override protected void publishResults(CharSequence c, FilterResults results) { listFiltered = (ArrayList<PersonInfo>) results.values; notifyDataSetChanged(); } }; }
Salut, vous avez raison, je n'ai pas écrasé le getFilter () dans StudentsListAdapter j'ai ajouté le code que vous avez mentionné mais j'ai des erreurs. Pourriez-vous s'il vous plaît jeter un oeil ici sur les erreurs que j'ai reçues. Merci!
Merci d'avoir mis à jour la réponse, mais j'ai toujours des problèmes sur la variable listFiletered et sur pour (String s: list) ici < / a> vérifiez-le s'il vous plaît, merci!
Mec, vous n'avez pas ajouté la variable "listFiltered" comme variable globale. Regardez la première ligne du code. Et aussi sur quel élément de l'objet PersonInfo vous souhaitez rechercher. C'est juste un échantillon que je vous ai donné. Veuillez publier votre objet PersonInfo également si vous ne pouvez pas le comprendre, je peux vous aider.
Salut @ PrashanthVerma, merci d'avoir répondu j'ai ajouté "listFiltered" comme variable globale, je veux juste rechercher le nom de la personne dans mon objet PersonInfo, mon objet PersonInfo déjà posté ici, mais j'ai essayé de changer le code où vous avez mentionné " obtenir les données en conséquence " ici mais j'ai toujours des erreurs dans l'instruction if et sur getItem () . Merci!
Merci d'avoir mis à jour le code mais en conséquence lors du débogage lorsque j'écris disons "Jamaïque", cela me donne le nom de la personne "Test". Voici les résultats Résultat de débogage , Résultat de la barre de recherche . Pourquoi cela arrive-t-il ? Merci encore!
Veuillez mettre le code ci-dessous dans votre méthode getfilter ()
Filter myFilter = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults filterResults = new FilterResults(); ArrayList<PersonInfo> tempList=new ArrayList<PersonInfo>(); // Add the filter code here if(constraint != null && persons!=null) { int length= persons.size(); int i=0; while(i<length){ PersonInfo item= persons.get(i); //do whatever you wanna do here //adding result set output array String name = item.getName(); if(name.toLowerCase().contains(constraint.toString())) { tempList.add(item); } i++; } //following two lines is very important //as publish result can only take FilterResults users filterResults.values = tempList; filterResults.count = tempList.size(); } return filterResults; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence contraint, FilterResults results) { persons = (ArrayList<PersonsInfo>) results.values; if (results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } };
Salut @Sandeep dhiman, j'ai essayé votre code mais je me demande toujours ce que devrait être la déclaration if .. Merci!
@FearLessAZ veuillez supprimer cette instruction if et essayez, cela fonctionnera
Bonjour @ Sandeepdhiman, j'ai supprimé l'instruction if si vous pouviez consulter les résultats de débogage , Il renvoie la bonne longueur et le bon seq, mais lorsque je recherche une personne, cela ressemble toujours à ceci a >, où "Jamaïque" l'utilisateur que je recherche déjà existe . Merci pour votre réponse en cherchant à vous entendre, nous sommes très proches de résoudre ce problème.
J'ai essayé le code que vous avez mis à jour, mais maintenant l'application cesse de fonctionner lorsque je tape quelque chose dans la barre de recherche et j'ai vérifié le résultat du débogage que l'instruction if ne renvoie rien. Veuillez jeter un œil ici Merci!
déboguez votre code puis ce que vous passez dans la méthode de filtrage dans la méthode Ontextchanged
voici le résultat de onTextChanged, et j'applique celui-ci myFilter () au lieu de getFilter ( ): (MainActivity.this) .test1.myFilter.filter (s);
Veuillez remplir ici le code de l'adaptateur que vous utilisez
désolé je n'ai pas compris la qualité ce que tu veux dire.
Veuillez indiquer ici le code complet de votre adaptateur que vous utilisez
J'ai mis à jour le code StudentListAdapter dans mon message ci-dessus, merci de le vérifier.
pourquoi ne remplacez-vous pas la méthode getFilter () dans votre adaptateur
Comme ça @Override public Filter getFilter () {return new Filter () {}; }
J'ai remplacé la méthode getFilter () et l'application n'arrête pas de fonctionner. ici est le résultat du débogage.
vous vérifiez pourquoi votre application plante?
J'ai vérifié le logcat et il plante dans cette ligne PersonInfo p = persons.get (position); here est le résultat, sachant que cela fonctionnait avant d'ajouter la méthode de remplacement getFilter ().
J'ai débogué mon code, il ne renvoie pas la position des éléments, mais comme je vous l'ai dit lorsque j'ai supprimé le remplacement de getFilter (), il renvoie la position sans aucune erreur. C'est étrange..
Vous n'avez pas surchargé la méthode getFilter () dans la classe d'adaptateur
où est votre code de filtre dans la classe d'adaptateur.?
Salut @AtifAbbAsi, j'ai manqué d'ajouter le code de filtre et j'essaye de l'ajouter dans ma classe d'adaptateur.
Si vous êtes toujours bloqué, essayez de supprimer tout le code de filtre de l'adaptateur. Ensuite, dans la classe PersonInfo , remplacez la méthode
toString ()
pour renvoyer le nom. J'espère que ça t'as aidé!Pour utiliser un filtre personnalisé, il doit y avoir 2 listes pour les données. L'un est une liste non filtrée / backup / all_data qui contient toutes les données. L'autre est la liste filtrée / de travail / de données qui est le résultat à afficher sur l'interface utilisateur. Mon blog sur listview peut vous aider: programandroidlistview.blogspot.com