1
votes

Comment réparer la fonctionnalité de la barre de recherche dans une vue de liste?

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!


5 commentaires

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


3 Réponses :


0
votes

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;
}


2 commentaires

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.



0
votes

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();
    }
  };
}


5 commentaires

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!



0
votes

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();
      }  
  }
 };


16 commentaires

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 , 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..