I have created a list view with multiple items in row. I have also created a search box above. I want to implement search functionality on the basis of particular fields of the list. How can I achieve this? Any help will be appreciated.
This article explains how to search for Item in a ListView. First, you will create an XML file and use an EditText and ListView. The EditText is used to search for an item and the ListView is used to show the list of items. Now you will create a Java file and write code to show an item in a ListView.
Add the Search View to the App Bar To add a SearchView widget to the app bar, create a file named res/menu/options_menu. xml in your project and add the following code to the file. This code defines how to create the search item, such as the icon to use and the title of the item.
Android ListView is a view which groups several items and display them in vertical scrollable list. The list items are automatically inserted to the list using an Adapter that pulls content from a source such as an array or database.
What is custom listview? Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml.
You have to use model, listview, and customadapter with filtering for this. I have created a demo for this.
Suppose you have a model named Product, and you are displaying its content in a custom listview where name and price are displayed in a textview. I mean in a custom row having two textviews, and you want to filter the list by one of the field of custom row. Here I have filtered with "name"
Screenshots:
Initial
Filtered
Source code
public class Product { public String name; public Integer price; public Product(String name, Integer price) { super(); this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } }
public class MainActivity extends Activity { private LinearLayout llContainer; private EditText etSearch; private ListView lvProducts; private ArrayList<Product> mProductArrayList = new ArrayList<Product>(); private MyAdapter adapter1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initialize(); // Add Text Change Listener to EditText etSearch.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { // Call back the Adapter with current character to Filter adapter1.getFilter().filter(s.toString()); } @Override public void beforeTextChanged(CharSequence s, int start, int count,int after) { } @Override public void afterTextChanged(Editable s) { } }); } private void initialize() { etSearch = (EditText) findViewById(R.id.etSearch); lvProducts = (ListView)findViewById(R.id.lvOS); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); mProductArrayList.add(new Product("a", 100)); mProductArrayList.add(new Product("b", 200)); mProductArrayList.add(new Product("c", 300)); mProductArrayList.add(new Product("d", 400)); mProductArrayList.add(new Product("e", 500)); mProductArrayList.add(new Product("f", 600)); mProductArrayList.add(new Product("g", 700)); mProductArrayList.add(new Product("h", 800)); mProductArrayList.add(new Product("i", 900)); mProductArrayList.add(new Product("j", 1000)); mProductArrayList.add(new Product("k", 1100)); mProductArrayList.add(new Product("l", 1200)); mProductArrayList.add(new Product("m", 1000)); mProductArrayList.add(new Product("n", 1300)); mProductArrayList.add(new Product("o", 1400)); mProductArrayList.add(new Product("p", 1500)); adapter1 = new MyAdapter(MainActivity.this, mProductArrayList); lvProducts.setAdapter(adapter1); } // Adapter Class public class MyAdapter extends BaseAdapter implements Filterable { private ArrayList<Product> mOriginalValues; // Original Values private ArrayList<Product> mDisplayedValues; // Values to be displayed LayoutInflater inflater; public MyAdapter(Context context, ArrayList<Product> mProductArrayList) { this.mOriginalValues = mProductArrayList; this.mDisplayedValues = mProductArrayList; inflater = LayoutInflater.from(context); } @Override public int getCount() { return mDisplayedValues.size(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } private class ViewHolder { LinearLayout llContainer; TextView tvName,tvPrice; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = inflater.inflate(R.layout.row, null); holder.llContainer = (LinearLayout)convertView.findViewById(R.id.llContainer); holder.tvName = (TextView) convertView.findViewById(R.id.tvName); holder.tvPrice = (TextView) convertView.findViewById(R.id.tvPrice); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.tvName.setText(mDisplayedValues.get(position).name); holder.tvPrice.setText(mDisplayedValues.get(position).price+""); holder.llContainer.setOnClickListener(new OnClickListener() { public void onClick(View v) { Toast.makeText(MainActivity.this, mDisplayedValues.get(position).name, Toast.LENGTH_SHORT).show(); } }); return convertView; } @Override public Filter getFilter() { Filter filter = new Filter() { @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence constraint,FilterResults results) { mDisplayedValues = (ArrayList<Product>) results.values; // has the filtered values notifyDataSetChanged(); // notifies the data with new filtered values } @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); // Holds the results of a filtering operation in values ArrayList<Product> FilteredArrList = new ArrayList<Product>(); if (mOriginalValues == null) { mOriginalValues = new ArrayList<Product>(mDisplayedValues); // saves the original data in mOriginalValues } /******** * * If constraint(CharSequence that is received) is null returns the mOriginalValues(Original) values * else does the Filtering and returns FilteredArrList(Filtered) * ********/ if (constraint == null || constraint.length() == 0) { // set the Original result to return results.count = mOriginalValues.size(); results.values = mOriginalValues; } else { constraint = constraint.toString().toLowerCase(); for (int i = 0; i < mOriginalValues.size(); i++) { String data = mOriginalValues.get(i).name; if (data.toLowerCase().startsWith(constraint.toString())) { FilteredArrList.add(new Product(mOriginalValues.get(i).name,mOriginalValues.get(i).price)); } } // set the Filtered result to return results.count = FilteredArrList.size(); results.values = FilteredArrList; } return results; } }; return filter; } } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <EditText android:id="@+id/etSearch" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <ListView android:id="@+id/lvProducts" android:layout_width="fill_parent" android:layout_height="wrap_content" ></ListView> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/llContainer" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <TextView android:id="@+id/tvName" android:layout_width="0dp" android:layout_height="wrap_content" android:singleLine="true" android:layout_weight="1" /> <TextView android:id="@+id/tvPrice" android:layout_width="0dp" android:layout_height="wrap_content" android:singleLine="true" android:layout_weight="1" /> </LinearLayout>
Implement filterable in your customadapter class.
public class MainActivity extends AppCompatActivity { String names[] = {"Apple","Banana","Kiwi","Oranges","Watermelon"}; String emails[] = {"This is apple","This is banana","This is kiwi","This is oranges","This is watermelon"}; int images[] = {R.drawable.apple,R.drawable.banana,R.drawable.kiwi,R.drawable.oranges,R.drawable.watermelon}; List<ItemsModel> itemsModelList = new ArrayList<>(); ListView listView; CustomAdapter customAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = findViewById(R.id.listview); for(int i = 0;i < names.length;i++){ ItemsModel itemsModel = new ItemsModel(names[i],emails[i],images[i]); itemsModelList.add(itemsModel); } customAdapter = new CustomAdapter(itemsModelList,this); listView.setAdapter(customAdapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.search_menu,menu); MenuItem menuItem = menu.findItem(R.id.searchView); SearchView searchView = (SearchView) menuItem.getActionView(); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { return false; } @Override public boolean onQueryTextChange(String newText) { Log.e("Main"," data search"+newText); customAdapter.getFilter().filter(newText); return true; } }); return true; } @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { int id = item.getItemId(); if(id == R.id.searchView){ return true; } return super.onOptionsItemSelected(item); } 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; } }
}
full tutorial can be found here: listview with search and onItemClickListner
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With