How to create search functionality in listview [duplicate] - android

This question already has answers here:
unable to search using custom Array Adapter in Android?
(2 answers)
Closed 10 years ago.
I want to create search functionality in listview,i have a small doubt that using arraylist can we perform search functionality.Here i ahve attached the code..where the
Totalarraylist is the arraylist and from that arraylist i am passing the data to Question adapter class
code,,
searchbox.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
If so then what to add here for search functionality...
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
adapterfirst = new Questionadapter(MainActivity.this,Totalarraylist);
listviewfirst = (ListView) findViewById(R.id.listquestion);
listviewfirst.setAdapter(adapterfirst);
}
public class Questionadapter extends BaseAdapter {
private ArrayList<HashMap<String, Object>> data;
public LayoutInflater inflater;
Context context;
public Questionadapter(Context context, ArrayList<HashMap<String,Object>> Totalarraylists) {
// TODO Auto-generated constructor stub
data=Totalarraylists;
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
System.out.println("data="+data);
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
//
}
}
could anybody help me to do this..

add a filter to your ListAdapter, and on onTextChanged apply the filter to listadapter

Try this, Compare your array list with your string you will get answer
public class MainActivity extends Activity {
ArrayList<String> list = new ArrayList<String>();
private EditText searchEdt;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// making it full screen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_ugsimply_beta);
list.add("Android");
list.add("Android1");
list.add("blackberry");
list.add("samsung");
list.add("LG");
searchEdt = (EditText) findViewById(R.id.searchEdt);
searchEdt.addTextChangedListener(new TextWatcher() {
private int textlength;
private ArrayList<String> arrayList_sort = new ArrayList<String>();
public void afterTextChanged(Editable s) {
// Abstract Method of TextWatcher Interface.
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// Abstract Method of TextWatcher Interface.
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
textlength = searchEdt.getText().length();
if (arrayList_sort != null)
arrayList_sort.clear();
for (int i = 0; i < list.size(); i++) {
if (textlength <= list.get(i).toString().length()) {
if (searchEdt
.getText()
.toString()
.equalsIgnoreCase(
(String) list.get(i).toString()
.subSequence(0, textlength))) {
arrayList_sort.add(list.get(i));
Log.d("TAG", "log" + arrayList_sort.size());
}
}
}
}
});
}
}

Related

implement search function to listview in fragments

I'm setting some values taken from a database i created into a listview. The listview is populated correctly.Now i want to implement a search function to my listview. How can i do this? I've already created search bar layout.I've referred to many tutorials but could not get it done.
My class
public class StockWatchView extends Fragment {
private ListView mListView;
private LazyListViewAdapter mAdapter;
private EditText search;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.stock_watchlist_view, container, false);
mListView = (ListView) view.findViewById(R.id.listview);
search = (EditText) view.findViewById(R.id.search);
Toast.makeText(StockWatchView.this.getActivity(), "Do Background Service", Toast.LENGTH_LONG).show();
DBHandler dbHandler = new DBHandler(StockWatchView.this.getActivity(), null, null, 0);
ArrayList<BaseElement> items = dbHandler.getAllPric();
if (items.size() != 0) {
mAdapter = new LazyListViewAdapter(items, StockWatchView.this.getActivity(), ListElement.PRICE_LIST.getPosition());
mListView.setAdapter(mAdapter);
Toast.makeText(this.getActivity(), "Toast " + dbHandler.getLastUpdateTime(), Toast.LENGTH_LONG).show();
} else {
//new BackgroundService().execute();
}
search.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}
// TODO Auto-generated method stub
});
return view;
}
}
You will have to declare a text watcher like::
TextWatcher mSearchTw = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
#Override
public void afterTextChanged(Editable editable) {
//put length after which this would be called
if (editable.length() > 2) {
//here you search in db
// or the stuff you want to do in view
}
}
}
` editText.addTextChangedListener(mSearchTw);
Make the items ArrayList as public .
Then fetch the required data(search result as type ArrayList<BaseElement>) by querying the database as like you did dbHandler.getAllPric(); in OnTextChanged() method by passing the editable text as parameter.
In the query you are going to use "like" phrase to get appropriate data.
For example,
items = dbHandler.getSearchResult(editableText);//editableText as String
after do adapter.notifyDataSetChanged();
Hope this approach will help you.

How to filter in Custom ListView with BaseAdapter

I can't seem to find how to make my custom getFilter() work.
My CustomAdapter extends BaseAdapter and as I have already understood it doesn't implements filtering so I need to do that by myself. I tried it in various ways but unsuccessfully.
Q1: What is the method working? (How do I implement filtering correctly?)
Q2: How do I change my CustomAdapter(!) so that filtering is an automatic feature?
Please, do not ignore!
Thanks a lot in advance!
Here's a piece of code:
Main.java
// import ....
public class MainActivity extends Activity {
ListView lv;
Context context;
EditText et;
CustomAdapter adapter;
View v;
public int [] Images= {R.drawable.1,R.drawable.2,R.drawable.3,R.drawable.4};
public String [] NameList={"item1","item2","item3","item4"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context=this;
lv=(ListView) findViewById(R.id.listView);
adapter = new CustomAdapter(this, fruitNameList,fruitImages);
lv.setAdapter(adapter);
et = (EditText)findViewById(R.id.editText);
/**
* Enabling Search Filter
* */
et.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
MainActivity.this.adapter.getFilter().filter(cs); // !!!!getFilter() is not found I tried to write methods on my own but nothing worked
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
}// end of onCreate
public void onClick (View v) {
switch (v.getId()) {
case R.id.search:
et.setVisibility(v.VISIBLE);
et.setHint("Search names...");
break;
}
}
public void SearchFilterEnable() {
/**
* Enabling Search Filter
* */
et.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
MainActivity.this.adapter.getFilter().filter(cs);
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
}
}
CustomAdapter.java
//import...
public class CustomAdapter extends BaseAdapter implements Filterable{
String [] result;
Context context;
int [] imageId;
private static LayoutInflater inflater=null;
public CustomAdapter(MainActivity mainActivity, String[] NameList, int[] Images) {
result=NameList;
context=mainActivity;
imageId=Images;
inflater = ( LayoutInflater )context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return result.length;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
public class Holder
{
TextView tv;
ImageView img;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
Holder holder=new Holder();
View v;
v = inflater.inflate(R.layout.name_list, null);
holder.tv=(TextView) v.findViewById(R.id.textView1);
holder.img=(ImageView) v.findViewById(R.id.imageView1);
holder.tv.setText('\t'+result[position]);
holder.img.setImageResource(imageId[position]);
v.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "You Clicked " + result[position], Toast.LENGTH_LONG).show();
}
});
return v;
}
}
One way would be to change the underlying data of the adapter (aka filter the data) and then call notifyDataSetChanged(); on the adapter. If you do so, your ListView will be informed that the dataset has been changed and will update its content.
You should store two Lists of your data in the adapter, one list with the original data and one list with the filtered data. The adapter itself operates on the filtered List and whenever you call your filter method, it just copies the data from your orginal list into the filtered list (based on your filter criteria).
private List<String> originalData;
private List<String> filteredData;
public void filter(String prefix) {
filteredData = new ArrayList<>();
for(String data : originalData) {
if(data.startsWith(prefix)) filteredData.add(data);
}
notifyDataSetChanged();
}

How can i implement search facility In custom list adapter using edit text

Here is my Custom list adapter how can i implement search facility In custom list adapter using edit text. I tried many ways to implement search facilty
public class ListAdapter extends BaseAdapter {
public ArrayList<Users> listDataContainers = new ArrayList<>();
ListAdapter(ArrayList<Users> listDataContainers) {
this.listDataContainers = listDataContainers;
}
#Override
public int getCount() {
return listDataContainers.size();
}
#Override
public User getItem(int arg0) {
return listDataContainers.get(arg0);
}
#Override
public long getItemId(int arg0) {
return arg0;
}
#Override
public View getView(int pos, View arg1, ViewGroup arg2) {
if (arg1 == null) {
LayoutInflater inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
arg1 = inflater.inflate(R.layout.listitem_layout, arg2, false);
}
TextView pa_name = (TextView) arg1.findViewById(R.id.textName);
TextView pa_date = (TextView) arg1.findViewById(R.id.textRoom);
Patient item = listDataContainers.get(pos);
pa_name.setText(item.name);
pa_date.setText(item.adm_date);
if (pos % 2 == 0)
arg1.setBackgroundResource(R.drawable.listview_selector_white);
else
arg1.setBackgroundResource(R.drawable.listview_selector_grey);
return arg1;
}
}
Or you can use a TextWatcher:
When an object of a type is attached to an Editable, its methods will be called when the text is changed.
searchField = (EditText) findViewById(R.id.search);
searchField.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
String text = searchField.getText().toString().toLowerCase(Locale.getDefault());
adapter.filter(text);
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
});
Now, the EditText will capture user input and pass it to the filter function of your custom adapter class.
In your custom adapter's constructor, you need to initialize a second list, to keep track of the currently desired / searched items:
public class ListAdapter extends BaseAdapter {
public ArrayList<Users> listDataContainers = new ArrayList<>();
private ArrayList<Users> usersFilteredList;
ListAdapter(ArrayList<Users> listDataContainers) {
this.listDataContainers = listDataContainers;
this.usersFilteredList = new ArrayList<Users>();
this.usersFilteredList.addAll(listDataContainers);
}
Add the filter function to your Adapter class and don't forget to call notifyDataSetChanged to update the UI.
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
listDataContainers.clear();
if (charText.length() == 0) {
listDataContainers.addAll(usersFilteredList);
} else {
for (Users user : usersFilteredList) {
if (user.getName().toLowerCase(Locale.getDefault())
.contains(charText)) {
listDataContainers.add(user);
}
}
}
notifyDataSetChanged();
}
Also, take a look at some other Q&A's on the same topic:
How to use the TextWatcher class in Android?
You need to use OnQueryTextListener, consider searchView to be the edit text:
searchView.setOnQueryTextListener(textChangeListener);
SearchView.OnQueryTextListener textChangeListener = new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextChange(String newText){
if (TextUtils.isEmpty(newText)){
searchView.clearFocus();
//Search logic when edit text is empty
}
else {
//Search logic when edit text is not empty
}
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
return true;
}
};
try this it helps you.
use textwatcher for your edittext as below:
// In your main activity
et_Search = (EditText)findViewById(R.id.et_Search);
et_SearchBar.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count)
{
try
{
try{
(listDatacontainers).getFilter().filter(s.toString());
}
catch(Exception e)
{
Log.i("error at ListAdapter", e.toString());
}
}
catch (Exception e)
{
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s)
{
}
});
create method getfilter() in your adapter source file

Filtered Listview returns original position

I'm filtering a listview that it's working properly. But when I click in an item of the filtered listview, it gives me the name of the item in the original position.
Example:
Items: A, B, C , D, E.
If I filter C, it returns only 1 item (C) but it shows A because it is position 0.
I have been looking for information but none of the similar questions helped me.
This is my code:
final FilteredListviewAdapter adapter = new FilteredListviewAdapter(AddAgentProfile.this, android.R.layout.simple_list_item_1, arraymls);
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
addProfile.setMLSId(mlslist.get(position).getId());
// THIS IS THE LINE THAT GIVES ME THE WRONG RESULT!!!
textmls.setText(mlslist.get(position).getName());
mls.setText("");
dialog.dismiss();
}
});
list.setAdapter(adapter);
final EditText filter = (EditText) inflated.findViewById(R.id.et_filter);
filter.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
adapter.getFilter().filter(s);
adapter.notifyDataSetChanged();
}
});
And FIlteredListViewAdapter:
public class FilteredListviewAdapter extends ArrayAdapter<String> {
ArrayList<String> list;
public FilteredListviewAdapter(Context context, int layout, ArrayList<String> array) {
super(context, layout, array);
list = array;
}
#Override
public String getItem(int position) {
return super.getItem(position);
}
}
What I'm doing wrong?
I have finally found the solution.
The code of the Adapter is ok as I wrote it.
The only lines I have changed are in the OnItemClickListener, so now the code is like this:
final FilteredListviewAdapter adapter = new FilteredListviewAdapter(AddAgentProfile.this, android.R.layout.simple_list_item_1, arraymls);
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
addProfile.setMLSId(mlslist.get(arraymls.indexOf(adapter.getItem(position))).getId());
textmls.setText(adapter.getItem(position));
mls.setText("");
dialog.dismiss();
}
});
list.setAdapter(adapter);
Now I call the function adapter.getItem instead of list.get
getItem should return the item inside the dataset at position:
#Override
public String getItem(int position) {
return list.get(position);
}

filtering a list with base adapter

I have a ListView with a BaseAdapter , I want to make a filter after the filed tipdoc,and my code doesn't work ,I mean nothing is heapen when start to write in the EditText and I can't find why,This is my code:
listView = (ListView) findViewById(android.R.id.list);
adapter = new ImageAndTextAdapter(Documente.this, R.layout.list_row,nume,tipdoc,formatdoc);
listView.setAdapter(adapter);
edt = (EditText) findViewById(R.id.search_box);
edt.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
ArrayList<String> nume_sort = new ArrayList<String>();
ArrayList<String> tipdoc_sort = new ArrayList<String>();
ArrayList<String> formatdoc_sort = new ArrayList<String>();
int textlength = edt.getText().length();
nume_sort.clear();
tipdoc_sort.clear();
formatdoc_sort.clear();
for (int i = 0; i < tipdoc.size(); i++)
{
if (textlength <= tipdoc.get(i).length())
{
if (edt.getText().toString().equalsIgnoreCase((String) tipdoc.get(i).subSequence(0, textlength)))
{
tipdoc_sort.add(tipdoc.get(i));
}
}
}
listView.setAdapter(new ImageAndTextAdapter
(Documente.this, R.layout.list_row,nume_sort,tipdoc_sort,formatdoc_sort));
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
}
private class ImageAndTextAdapter extends BaseAdapter{
private Context adContext;
public int getCount() {
return nume.size();
}
public ImageAndTextAdapter(Context context,int layout,ArrayList<String> nume,ArrayList<String> tipdoc,ArrayList<String> formatdoc)
{
super();
this.adContext = context;
}
public View getView(int pos, View inView, ViewGroup parent){
View v = inView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater)adContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.list_row, null);
}
String num = String.format(nume.get(pos));
((TextView)v.findViewById(R.id.Nume)).setText(num);
String tdoc = String.format(tipdoc.get(pos));
((TextView)v.findViewById(R.id.TDoc)).setText(tdoc);
if (formatdoc.get(pos).equals("doc")){
((ImageView)v.findViewById(R.id.list_image)).setImageResource(R.drawable.doc);
}
else if (formatdoc.get(pos).equals(".xlsx") || formatdoc.get(pos).equals("xls")) ((ImageView)v.findViewById(R.id.list_image)).setImageResource(R.drawable.xls);
else ((ImageView)v.findViewById(R.id.list_image)).setImageResource(R.drawable.pdf);
return v;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}
you have to change the value of nume var,because in your code its the same
try this code...
et.addTextChangedListener(new TextWatcher()
{
public void afterTextChanged(Editable s)
{
// Abstract Method of TextWatcher Interface.
}
public void beforeTextChanged(CharSequence s,
int start, int count, int after)
{
// Abstract Method of TextWatcher Interface.
}
public void onTextChanged(CharSequence s,int start, int before, int count)
{
textlength = et.getText().length();
array_sort.clear();
for (int i = 0; i < listview_array_location.length; i++)
{
if (textlength <= listview_array_location[i].length())
{
if(et.getText().toString().equalsIgnoreCase((String)listview_array_location[i].subSequence(0,textlength)))
{
array_sort.add(listview_array[i]);
}
}
}
AppendList(array_sort);
}
});
}
public void AppendList(ArrayList<String> str)
{
listview_arr = new String[str.size()];
listview_arr = str.toArray(listview_arr);
setListAdapter(new bsAdapter(this));
}
public class bsAdapter extends BaseAdapter
{
Activity cntx;
public bsAdapter(Activity context)
{
// TODO Auto-generated constructor stub
this.cntx=context;
}
public int getCount()
{
// TODO Auto-generated method stub
return listview_arr.length;
}
public Object getItem(int position)
{
// TODO Auto-generated method stub
return listview_arr[position];
}
public long getItemId(int position)
{
// TODO Auto-generated method stub
return listview_array.length;
}
public View getView(final int position, View convertView, ViewGroup parent)
{
View row=null;
LayoutInflater inflater=cntx.getLayoutInflater();
row=inflater.inflate(R.layout.search_list_item, null);
TextView tv=(TextView)row.findViewById(R.id.title);
tv.setText(listview_arr[position]);
return row;
}
}

Categories

Resources