Custom Listview Adapter with filter Android

后端 未结 10 695
北荒
北荒 2020-11-22 06:07

Please am trying to implement a filter on my listview. But whenever the text change, the list disappears.Please Help Here are my codes. The adapter class.

p         


        
相关标签:
10条回答
  • 2020-11-22 06:42

    First you create the EditText in the xml file and assign an id, eg con_pag_etPesquisa. After that, we will create two lists, where one is the list view and the other to receive the same content but will remain as a backup. Before moving objects to lists first initializes Them the below:

    //Declaring
    
    public EditText etPesquisa;
    
    public ContasPagarAdapter adapterNormal;
    
    public List<ContasPagar> lstBkp;
    
    public List<ContasPagar> lstCp;
    
    //Within the onCreate method, type the following:
    
    etPesquisa = (EditText) findViewById(R.id.con_pag_etPesquisa);
    
    etPesquisa.addTextChangedListener(new TextWatcher(){
    
        @Override
        public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3){
            filter(String.valueOf(cs));
        }
        @Override
        public void beforeTextChanged(CharSequence cs, int arg1, int arg2, int arg3){
    
        // TODO Auto-generated method stub
        }
        @Override
        public void afterTextChanged(Editable e){
    
        }
    
    });
    
    //Before moving objects to lists first initializes them as below:
    
    lstCp = new ArrayList<ContasPagar>();
    
    lstBkp = new ArrayList<ContasPagar>();
    
    
    //When you add objects to the main list, repeat the procedure also for bkp list, as follows:
    
    lstCp.add(cp);
    
    lstBkp.add(cp);
    
    
    //Now initializes the adapter and let the listener, as follows:
    
    adapterNormal = new ContasPagarAdapter(ContasPagarActivity.this, lstCp);
    
    lvContasPagar.setAdapter(adapterNormal);
                        lvContasPagar.setOnItemClickListener(verificaClickItemContasPagar(lstCp));
    
    
    //Now create the methods inside actito filter the text entered by the user, as follows:
    
    public void filter(String charText){
    
        charText = charText.toLowerCase();
    
        lstCp.clear();
    
        if (charText.length() == 0){
    
            lstCp.addAll(lstBkp);
    
            appendAddItem(lstBkp);
    
        } 
    
        else {
    
            for (int i = 0; i < lstBkp.size(); i++){
    
                if((lstBkp.get(i).getNome_lancamento() + " - " + String.valueOf(lstBkp.get(i).getCodigo())).toLowerCase().contains(charText)){
    
                    lstCp.add(lstBkp.get(i));
    
                }
    
            }
    
            appendAddItem(lstCp);
        }
    }
    
    private void appendAddItem(final List<ContasPagar> novaLista){
        runOnUiThread(new Runnable(){
    
            @Override
                public void run(){
                    adapterNormal.notifyDataSetChanged();               
                }
            });
        }
    
    0 讨论(0)
  • 2020-11-22 06:44

    Just an update.

    If the ticked answer is working fine for you but it shows nothing when the search text is empty. Here is the solution:

    private class ItemFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            
            String filterString = constraint.toString().toLowerCase();
            
            FilterResults results = new FilterResults();
    
            if(constraint.length() == 0)
            {
                results.count = originalData.size();
                results.values = originalData;
            }else {
    
            
            final List<String> list = originalData;
    
            int count = list.size();
            final ArrayList<String> nlist = new ArrayList<String>(count);
    
            String filterableString ;
            
            for (int i = 0; i < count; i++) {
                filterableString = list.get(i);
                if (filterableString.toLowerCase().contains(filterString)) {
                    nlist.add(filterableString);
                }
            }
            
            results.values = nlist;
            results.count = nlist.size();
         }
            return results;
        }
    
        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            filteredData = (ArrayList<String>) results.values;
            notifyDataSetChanged();
          }
    
       }
    

    For any query comment below

    0 讨论(0)
  • 2020-11-22 06:46

    please check below code it will help you

    DrawerActivity.userListview
                .setOnItemClickListener(new OnItemClickListener() {
    
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view,
                            int position, long id) {
    
                        int pos = position;
                        Intent intent = new Intent(getContext(),
                                UserDetail.class);
                        intent.putExtra("model", list.get(position));
                        context.startActivity(intent);
                    }
                });
        return convertView;
    }
    
    @Override
    public android.widget.Filter getFilter() {
    
        return new android.widget.Filter() {
    
            @Override
            protected void publishResults(CharSequence constraint,
                    FilterResults results) {
    
                ArrayList<UserListModel> updatelist = (ArrayList<UserListModel>) results.values;
                UserListCustomAdaptor newadaptor = new UserListCustomAdaptor(
                        getContext(), getCount(), updatelist);
    
                if (results.equals(constraint)) {
                    updatelist.add(modelobj);
                }
                if (results.count > 0) {
                    notifyDataSetChanged();
                } else {
    
                    notifyDataSetInvalidated();
                }
            }
    
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
    
                FilterResults filterResults = new FilterResults();
                list = new ArrayList<UserListModel>();
    
                if (constraint != null && DrawerActivity.userlist != null) {
    
                    constraint = constraint.toString().toLowerCase();
                    int length = DrawerActivity.userlist.size();
                    int i = 0;
                    while (i < length) {
    
                        UserListModel modelobj = DrawerActivity.userlist.get(i);
                        String data = modelobj.getFirstName() + " "
                                + modelobj.getLastName();
                        if (data.toLowerCase().contains(constraint.toString())) {
                            list.add(modelobj);
                        }
    
                        i++;
                    }
                    filterResults.values = list;
                    filterResults.count = list.size();
                }
                return filterResults;
            }
        };
    }
    
    @Override
    public int getCount() {
        return list.size();
    }
    
    @Override
    public UserListModel getItem(int position) {
    
        return list.get(position);
    }
    
    0 讨论(0)
  • 2020-11-22 06:46

    You can implement search filter in listview by two ways. 1. using searchview 2. using edittext.

    1. If yo want to use searchview then read here : searchview filter.

    2. If you want to use edittext, read below.

    I have taken reference from : listview search filter android

    Code snippets to make filter with edittext.

    First create model class MovieNames.java:

    public class MovieNames {
        private String movieName;
    
        public MovieNames(String movieName) {
            this.movieName = movieName;
        }
    
        public String getMovieName() {
            return this.movieName;
        }
    
    }
    

    Create listview_item.xml file :

         <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="10dp">
    
    
        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    
    </RelativeLayout>
    

    Make ListViewAdapter.java class :

        import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.TextView;
    
    import java.util.ArrayList;
    import java.util.Locale;
    
    public class ListViewAdapter extends BaseAdapter {
    
        // Declare Variables
    
        Context mContext;
        LayoutInflater inflater;
        private ArrayList<MovieNames> arraylist;
    
        public ListViewAdapter(Context context, ArrayList<MovieNames> arraylist) {
            mContext = context;
            inflater = LayoutInflater.from(mContext);
            this.arraylist = arraylist;
    
        }
    
        public class ViewHolder {
            TextView name;
        }
    
        @Override
        public int getCount() {
            return arraylist.size();
        }
    
        @Override
        public MovieNames getItem(int position) {
            return arraylist.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        public View getView(final int position, View view, ViewGroup parent) {
            final ViewHolder holder;
            if (view == null) {
                holder = new ViewHolder();
                view = inflater.inflate(R.layout.listview_item, null);
                // Locate the TextViews in listview_item.xml
                holder.name = (TextView) view.findViewById(R.id.name);
                view.setTag(holder);
            } else {
                holder = (ViewHolder) view.getTag();
            }
            // Set the results into TextViews
            holder.name.setText(arraylist.get(position).getMovieName());
            return view;
        }
    
    
    } 
    

    Prepare activity_main.xml file :

        <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.example.parsaniahardik.searchedit.MainActivity"
        android:orientation="vertical">
    
    
        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/editText"
            android:layout_alignParentTop="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:hint="enter query"
            android:singleLine="true">
    
    
            <requestFocus/>
        </EditText>
    
        <ListView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/listView"
            android:divider="#694fea"
            android:dividerHeight="1dp" />
    
    
    </LinearLayout>
    

    Finally make MainActivity.java class :

        import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.text.Editable;
    import android.text.TextWatcher;
    import android.util.Log;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.EditText;
    import android.widget.ListView;
    import android.widget.SearchView;
    import android.widget.Toast;
    
    import java.util.ArrayList;
    
    public class MainActivity extends AppCompatActivity {
    
        private EditText etsearch;
        private ListView list;
        private ListViewAdapter adapter;
        private String[] moviewList;
        public static ArrayList<MovieNames> movieNamesArrayList;
        public static ArrayList<MovieNames> array_sort;
        int textlength = 0;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // Generate sample data
    
            moviewList = new String[]{"Xmen", "Titanic", "Captain America",
                    "Iron man", "Rocky", "Transporter", "Lord of the rings", "The jungle book",
                    "Tarzan","Cars","Shreck"};
    
            list = (ListView) findViewById(R.id.listView);
    
            movieNamesArrayList = new ArrayList<>();
            array_sort = new ArrayList<>();
    
            for (int i = 0; i < moviewList.length; i++) {
                MovieNames movieNames = new MovieNames(moviewList[i]);
                // Binds all strings into an array
                movieNamesArrayList.add(movieNames);
                array_sort.add(movieNames);
            }
    
            adapter = new ListViewAdapter(this,movieNamesArrayList);
            list.setAdapter(adapter);
    
    
            etsearch = (EditText) findViewById(R.id.editText);
    
            list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Toast.makeText(MainActivity.this, array_sort.get(position).getMovieName(), Toast.LENGTH_SHORT).show();
                }
            });
    
            etsearch.addTextChangedListener(new TextWatcher() {
    
    
                public void afterTextChanged(Editable s) {
                }
    
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                }
    
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    textlength = etsearch.getText().length();
                    array_sort.clear();
                    for (int i = 0; i < movieNamesArrayList.size(); i++) {
                        if (textlength <= movieNamesArrayList.get(i).getMovieName().length()) {
                            Log.d("ertyyy",movieNamesArrayList.get(i).getMovieName().toLowerCase().trim());
                            if (movieNamesArrayList.get(i).getMovieName().toLowerCase().trim().contains(
                                    etsearch.getText().toString().toLowerCase().trim())) {
                                array_sort.add(movieNamesArrayList.get(i));
                            }
                        }
                    }
                        adapter = new ListViewAdapter(MainActivity.this, array_sort);
                        list.setAdapter(adapter);
    
                }
            });
    
        }
    }
    
    0 讨论(0)
  • 2020-11-22 06:57

    In your CustomAdapter class implement filterable.

     public class CustomAdapter extends BaseAdapter implements Filterable {
    
        private List<ItemsModel> itemsModelsl;
        private List<ItemsModel> itemsModelListFiltered;
        private Context context;
    
        public CustomAdapter(List<ItemsModel> itemsModelsl, Context context) {
            this.itemsModelsl = itemsModelsl;
            this.itemsModelListFiltered = itemsModelsl;
            this.context = context;
        }
    
    
    
        @Override
        public int getCount() {
            return itemsModelListFiltered.size();
        }
    
        @Override
        public Object getItem(int position) {
            return itemsModelListFiltered.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            View view = getLayoutInflater().inflate(R.layout.row_items,null);
    
    
            TextView names = view.findViewById(R.id.name);
            TextView emails = view.findViewById(R.id.email);
            ImageView imageView = view.findViewById(R.id.images);
    
            names.setText(itemsModelListFiltered.get(position).getName());
            emails.setText(itemsModelListFiltered.get(position).getEmail());
            imageView.setImageResource(itemsModelListFiltered.get(position).getImages());
    
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.e("main activity","item clicked");
                    startActivity(new Intent(MainActivity.this,ItemsPreviewActivity.class).putExtra("items",itemsModelListFiltered.get(position)));
    
                }
            });
    
            return view;
        }
    
    
    
        @Override
        public Filter getFilter() {
            Filter filter = new Filter() {
                @Override
                protected FilterResults performFiltering(CharSequence constraint) {
    
                    FilterResults filterResults = new FilterResults();
                    if(constraint == null || constraint.length() == 0){
                        filterResults.count = itemsModelsl.size();
                        filterResults.values = itemsModelsl;
    
                    }else{
                        List<ItemsModel> resultsModel = new ArrayList<>();
                        String searchStr = constraint.toString().toLowerCase();
    
                        for(ItemsModel itemsModel:itemsModelsl){
                            if(itemsModel.getName().contains(searchStr) || itemsModel.getEmail().contains(searchStr)){
                                resultsModel.add(itemsModel);
    
                            }
                             filterResults.count = resultsModel.size();
                                filterResults.values = resultsModel;
                        }
    
    
                    }
    
                    return filterResults;
                }
    
                @Override
                protected void publishResults(CharSequence constraint, FilterResults results) {
    
                    itemsModelListFiltered = (List<ItemsModel>) results.values;
                    notifyDataSetChanged();
    
                }
            };
            return filter;
        }
    }
    

    }

    You can get the whole tutorial here: ListView With Search/Filter and OnItemClickListener

    Github Source Code

    0 讨论(0)
  • 2020-11-22 06:57

    If you want to achieve filtering with custom model class in kotlin then you can implement below code.

    Step 1: Add SearchView in your xml file and then in your activity or fragment implement SearchView.OnQueryTextListener

    class SearchActivity : AppCompatActivity(),SearchView.OnQueryTextListener {
    
    
        lateinit var sectionModelArrayList: ArrayList<CategorySectionModel>
        lateinit var filteredArrayList: ArrayList<CategorySectionModel>
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_category_updated)
            searchView.setOnQueryTextListener(this)
        }
    
    
        //Called this method with you own data to populate the recycler view.
        private fun parseJson() {
            rv_category_list.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
            adapter = CategoryLabelAdapter(sectionModelArrayList, this)
            rv_category_list.adapter = adapter
        }
    
        override fun onQueryTextSubmit(query: String?): Boolean {
            return false
        }
    
        override fun onQueryTextChange(newText: String?): Boolean {
            adapter.filter!!.filter(newText.toString())
            return false
        }
    

    My model class CategorySectionModel looks like

    class CategorySectionModel(val categoryLabel: String, val categoryItemList: ArrayList<CategoryItem>)
    

    Now we have to work on adapter class and there you need to implement Filterable interface and override getFilter() method like below

    class CategoryLabelAdapter(internal var data: ArrayList<CategorySectionModel>?, internal var activity: Context) : RecyclerView.Adapter<CategoryLabelAdapter.ViewHolder>(), Filterable {
        val originalList = data
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            val v = LayoutInflater.from(parent.context).inflate(R.layout.item_category_name, parent, false)
            return ViewHolder(v)
        }
    
        override fun getItemCount(): Int {
            return data!!.size
        }
    
        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            data?.get(position)?.let { holder.bindItem(it) }
        }
    
    
        class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
            @SuppressLint("SetTextI18n")
            fun bindItem(data: CategorySectionModel) {
                itemView.tv_category_name.text = data.categoryLabel
            }
        }
    
        override fun getFilter(): Filter? {
            return object : Filter() {
                override fun performFiltering(constraint: CharSequence): FilterResults {
                    val results = FilterResults()
                    if (constraint.isEmpty()) {
                        //no filter implemented we return full list
                        results.values = data
                        results.count = data!!.size
                    } else {
                        //Here we perform filtering operation
                        val list: ArrayList<CategorySectionModel> = ArrayList()
                        for (p in data!!) {
                            if (p.categoryLabel.toUpperCase().startsWith(constraint.toString().toUpperCase())) list.add(p)
                        }
                        results.values = list
                        results.count = list.size
                    }
                    return results
                }
    
                override fun publishResults(constraint: CharSequence, results: FilterResults) {
                    // Now we have to inform the adapter about the new list filtered
                    if (results.count == 0 || constraint == "") {
                        data = originalList
                        notifyDataSetChanged()
                    } else {
                        data = results.values as ArrayList<CategorySectionModel>?
                        notifyDataSetChanged()
                    }
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题