I'm trying to filter a listview with arrayadapter. The arraydapter parameter is a String[][]. The problem is that anything happens. I must override the Filter interface? In that case plase, can someone provide some hints?
Every position of the array I'm trying to filter is like
galleryValues[0][0] -> "tiulo"
[0][1] -> "desc"
[0][2] -> "etc"
I tryied to filter it:
lstContinente = (ListView)findViewById(R.id.list);
lstContinente.setTextFilterEnabled(true);
adapter = new PortaitArrayAdapter(cx,galleryValues);
lstContinente.setAdapter(adapter);
ed_busqueda.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s.toString());
adapter.notifyDataSetChanged();
}
});
The adapter code:
public class PortaitArrayAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[][] values;
private List<Imagen> imagenes = null;
private LayoutInflater mInflater;
public ImageLoader imageLoader;
public PortaitArrayAdapter(Context context, String[][] values) {
super(context, R.layout.gallery_row);
this.context = context;
this.values = values;
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imagenes = new ArrayList<Imagen>();
for (int i = 0; i < 20; i++) imagenes.add(new Imagen());
Bitmap def = BitmapFactory.decodeResource(this.context.getResources(),R.drawable.ic_launcher);
imageLoader=new ImageLoader(this.context,def, imagenes);
}
#Override
public int getCount (){
return this.values.length;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.gallery_row, parent, false);
holder.txtTitulo = (TextView) convertView.findViewById(R.id.txt_gallery_titulo);
holder.txtDesc = (TextView) convertView.findViewById(R.id.txt_gallery_desc);
holder.txtFecha = (TextView) convertView.findViewById(R.id.txt_gallery_fecha);
holder.txtEst = (TextView) convertView.findViewById(R.id.txt_gallery_est);
holder.imageView = (ImageView)convertView.findViewById(R.id.lst_img_gallery);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
/*LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.gallery_row, parent, false);*/
//ImageView imageView = (ImageView) rowView.findViewById(R.id.icon);
Bitmap bmp;
Log.v("Position --> ",String.valueOf(position));
try {
byte b[] = imagenes.get(position).getImageData();
if (b != null) {
bmp = BitmapFactory.decodeByteArray(b, 0, b.length);
if (bmp != null) holder.imageView.setImageBitmap(bmp);
} else {
String urlBase = galleryValues[position][0].substring(0, galleryValues[position][0].lastIndexOf("/")+1);
String urlToEncode = galleryValues[position][0].substring(galleryValues[position][0].lastIndexOf("/")+1, galleryValues[position][0].length());
urlToEncode = URLEncoder.encode(urlToEncode,"UTF-8");
String url = urlBase.concat(urlToEncode);
url = url.replace("+", "%20");
Log.v("UrlFinal --> ",url);
imageLoader.DisplayImage(String.valueOf(position),url,act,holder.imageView, position,null);
}
} catch (Exception e) {
Log.e(this.getClass().getName(),"Exception en pos = " + position + " error:" + e.getMessage());
e.printStackTrace();
}
holder.txtTitulo.setText(galleryValues[position][1] + ", " + galleryValues[position][2]);
String[] dates = galleryValues[position][4].split("/");
String date = dates [1] + "/" + dates[0] + "/" + dates[2];
Date d1 = new Date(date);
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
holder.txtDesc.setText(galleryValues[position][3]);
holder.txtFecha.setText(df.format(d1));
holder.txtEst.setText(getText(R.string.num_fotos_gallery) + galleryValues[position][5] + " - " + getText(R.string.num_videos_gallery) + galleryValues[position][6] + " - " + getText(R.string.num_exp_gallery) + galleryValues[position][7]);
return convertView;
}
}
private static class ViewHolder {
TextView txtTitulo;
TextView txtDesc;
TextView txtFecha;
TextView txtEst;
ImageView imageView;
}
Convert your String array to ArrayList and pass it to Adapter and use below code or change below code with your String[].
You need to implement Filterable to your Adapter class and Override getFilter()
Checkout this complete example for filtering custom Adapter.
public class ListFilterActivity extends ListActivity {
private List<String> list = new ArrayList<String>();
List<String> mOriginalValues;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final MyAdapter adapter = new MyAdapter(this, getModel());
setListAdapter(adapter);
EditText filterEditText = (EditText) findViewById(R.id.filterText);
// Add Text Change Listener to EditText
filterEditText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Call back the Adapter with current character to Filter
adapter.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
private List<String> getModel() {
list.add("Linux");
list.add("Windows7");
list.add("Suse");
list.add("Eclipse");
list.add("Ubuntu");
list.add("Solaris");
list.add("Android");
list.add("iPhone");
list.add("Windows XP");
return list;
}
}
// Adapter Class
public class MyAdapter extends BaseAdapter implements Filterable {
List<String> arrayList;
List<String> mOriginalValues; // Original Values
LayoutInflater inflater;
public MyAdapter(Context context, List<String> arrayList) {
this.arrayList = arrayList;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView textView;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.row, null);
holder.textView = (TextView) convertView
.findViewById(R.id.textview);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(arrayList.get(position));
return convertView;
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,FilterResults results) {
arrayList = (List<String>) 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
List<String> FilteredArrList = new ArrayList<String>();
if (mOriginalValues == null) {
mOriginalValues = new ArrayList<String>(arrayList); // 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);
if (data.toLowerCase().startsWith(constraint.toString())) {
FilteredArrList.add(data);
}
}
// set the Filtered result to return
results.count = FilteredArrList.size();
results.values = FilteredArrList;
}
return results;
}
};
return filter;
}
}
Here I mention the code of how We can filter the listView Data using custom Adapter
Its really help you
ListViewAdapter.java
public class ListViewAdapter extends BaseAdapter {
// Declare Variables
Context mContext;
LayoutInflater inflater;
public List<AllFoodItem> allFoodItemlist;
public ArrayList<AllFoodItem> arraylist;
public ListViewAdapter(Context context, List<AllFoodItem> allFoodItemlist) {
mContext = context;
this.allFoodItemlist = allFoodItemlist;
inflater = LayoutInflater.from(mContext);
this.arraylist = new ArrayList<AllFoodItem>();
this.arraylist.addAll(allFoodItemlist);
}
#Override
public int getCount() {
return allFoodItemlist.size();
}
#Override
public AllFoodItem getItem(int position) {
return allFoodItemlist.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public class Holder {
TextView foodname, quantity, calorie;
}
public View getView(final int position, View view, ViewGroup parent) {
Holder holder = new Holder();
view = inflater.inflate(R.layout.program_list, null);
// Locate the TextViews in listview_item.xml
holder.foodname = (TextView) view.findViewById(R.id.textView1);
// Set the results into TextViews holder.foodname.setText(allFoodItemlist.get(position).getName().toString());
return view;
}
// Filter Class
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
allFoodItemlist.clear();
if (charText.length() == 0) {
allFoodItemlist.addAll(arraylist);
} else {
for (AllFoodItem wp : arraylist) {
if (wp.getName().toLowerCase(Locale.getDefault()).contains(charText)) {
allFoodItemlist.add(wp);
}
}
}
notifyDataSetChanged();
}
}
MainActivity.java
use the ListViewAdapter class apply filter on EditText by using filter() method
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
foodname = (inputSearch.getText().toString()).trim();
// filter the data of edit Text using filter method in ListViewAdapter
String text = inputSearch.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 afterTextChanged(Editable arg0) {
userGet();
// TODO Auto-generated method stub
}
});
Related
I am using a custom adapter with a search filter in a fragment, however the results don't get filtered on a search, I debugged and stepped through my code and find that it is saying that the args.listenere = null!. What does this mean and how do I correct it? My code is below:
---------Custom Adapter -------
public class SalesPartAdapter extends BaseAdapter implements Filterable {
private ArrayList<SalesPartItem> listData;
private ArrayList<SalesPartItem> filteredData;
private SalesPartFilter filter;
private Context _context;
private LayoutInflater layoutInflater;
public SalesPartAdapter(Context context, ArrayList<SalesPartItem> listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(context);
_context = context;
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
//set background colour
if (convertView == null) {
//set up holder
convertView = layoutInflater.inflate(R.layout.salespart_item, null);
holder = new ViewHolder();
holder.salesPartCodeView = (TextView) convertView.findViewById(R.id.salesPartCode);
holder.salesPartDescView = (TextView) convertView.findViewById(R.id.salesPartDescription);
holder.salesPartColourBar= (ImageView) convertView.findViewById(R.id.colourBar);
convertView.setTag(holder);
} else {
//use existing holder
holder = (ViewHolder) convertView.getTag();
}
SalesPartItem salespartView = (SalesPartItem) listData.get(position);
holder.salesPartCodeView.setText(salespartView.SalesPartCode);
holder.salesPartDescView.setText(salespartView.SalesPartDescription);
holder.salesPartColourBar.setBackgroundColor(Color.parseColor(salespartView.Colour));//String.valueOf(salespartView.Colour);
return convertView;
}
/********* holder Class to contain previously inflated xml file elements *********/
static class ViewHolder {
TextView salesPartCodeView;
TextView salesPartDescView;
ImageView salesPartColourBar;
}
public Filter getFilter() {
if (filter == null){
filter = new SalesPartFilter();
}
return filter;
}
ArrayList<SalesPartItem> filteredItems;
ArrayList<Integer>countFilteredItems;
private class SalesPartFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
constraint = constraint.toString().toLowerCase();
FilterResults result = new FilterResults();
if(constraint != null && constraint.toString().length() > 0)
{
filteredItems = new ArrayList<SalesPartItem>();
// countFilteredItems = new ArrayList<Integer>();
for(int i = 0, l = listData.size(); i < l; i++)
{
SalesPartItem salesPartItem = listData.get(i);
if(salesPartItem.SalesPartDescription.toString().toLowerCase().contains(constraint))
filteredItems.add(salesPartItem);
// countFilteredItems.add(i);
}
result.count = filteredItems.size();
result.values = filteredItems;
}
else
{
synchronized(this)
{
result.values = listData;
result.count = listData.size();
}
}
return result;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// notifyDataSetChanged();
if (results.count > 0) {
listData =(ArrayList<SalesPartItem>)results.values;
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
}
----------------Fragment code that deals with the list view -------------------
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//USE SAMPLE ID TO GET SALES PARTS LIST FROM DATABASE
addSalesParts.setEnabled(false);
//ListViewModel (SalesPartId,salesPartName,NotUsed)
final int numberOfAddedSalesParts = 3;
SalesPartItem sp;
// fill with some dummy data for now.
for (long i = 1; i < numberOfAddedSalesParts; i++) {
sp = new SalesPartItem();
sp.SalesPartItemId = i;
sp.SalesPartCode = "LEU" + i;
if(i!=2){
sp.SalesPartDescription = "Sales Part " + i;
}
else{
sp.SalesPartDescription = "TSalZes Part " + i;
}
sp.Colour = "#cccccc";
salesPartListViewItems.add(sp);
}
// Start of Search filtering
mListView = (ListView) getActivity().findViewById(R.id.salespartsList);
//click on item - edit order
mListView.setTextFilterEnabled(true);
//display the list via our custom adapter
mListView.setAdapter(new SalesPartAdapter(getActivity(), salesPartListViewItems);
EditText searchField = (EditText) getActivity().findViewById(R.id.typeFindSalesPart);
searchField.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
//TODO Search Lists from Database and filter accordingly
SalesPartAdapter SA = new SalesPartAdapter(getActivity(), salesPartListViewItems);
SA.getFilter().filter(s.toString());
Toast.makeText(getActivity(), s, Toast.LENGTH_SHORT).show();
// salesPartListViewItems.contains(s);
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
I have now resolved this, the issue was that I was creating a new instance of the adapter in the text watcher. Once I set it to use the adapter that created the original list then it worked fine
In android How to use searchview in listview ?
Listview conatins imageview and multiple textviews
when I used to to type some text in search the list view want to display based on my search
How to perform this
Thanks in advance
Create a custom adapter like this
public class PlanetAdapter extends ArrayAdapter<Planet> implements Filterable {
private List<Planet> planetList;
private Context context;
private Filter planetFilter;
private List<Planet> origPlanetList;
public PlanetAdapter(List<Planet> planetList, Context ctx) {
super(ctx, R.layout.img_row_layout, planetList);
this.planetList = planetList;
this.context = ctx;
this.origPlanetList = planetList;
}
public int getCount() {
return planetList.size();
}
public Planet getItem(int position) {
return planetList.get(position);
}
public long getItemId(int position) {
return planetList.get(position).hashCode();
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
PlanetHolder holder = new PlanetHolder();
// First let's verify the convertView is not null
if (convertView == null) {
// This a new view we inflate the new layout
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.img_row_layout, null);
// Now we can fill the layout with the right values
TextView tv = (TextView) v.findViewById(R.id.name);
TextView distView = (TextView) v.findViewById(R.id.dist);
holder.planetNameView = tv;
holder.distView = distView;
v.setTag(holder);
}
else
holder = (PlanetHolder) v.getTag();
Planet p = planetList.get(position);
holder.planetNameView.setText(p.getName());
holder.distView.setText("" + p.getDistance());
return v;
}
public void resetData() {
planetList = origPlanetList;
}
/* *********************************
* We use the holder pattern
* It makes the view faster and avoid finding the component
* **********************************/
private static class PlanetHolder {
public TextView planetNameView;
public TextView distView;
}
/*
* We create our filter
*/
#Override
public Filter getFilter() {
if (planetFilter == null)
planetFilter = new PlanetFilter();
return planetFilter;
}
private class PlanetFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// We implement here the filter logic
if (constraint == null || constraint.length() == 0) {
// No filter implemented we return all the list
results.values = origPlanetList;
results.count = origPlanetList.size();
}
else {
// We perform filtering operation
List<Planet> nPlanetList = new ArrayList<Planet>();
for (Planet p : planetList) {
if (p.getName().toUpperCase().startsWith(constraint.toString().toUpperCase()))
nPlanetList.add(p);
}
results.values = nPlanetList;
results.count = nPlanetList.size();
}
return results;
}
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
// Now we have to inform the adapter about the new list filtered
if (results.count == 0)
notifyDataSetInvalidated();
else {
planetList = (List<Planet>) results.values;
notifyDataSetChanged();
}
}
}
}
Create POJO(getter setter class) for planets
then in your activity
// The data to show
List<Planet> planetsList = new ArrayList<Planet>();
PlanetAdapter aAdpt;
ListView lv = (ListView) findViewById(R.id.listView);
aAdpt = new PlanetAdapter(planetsList, this);
lv.setAdapter(aAdpt);
you can use like this for filtering
// TextFilter
lv.setTextFilterEnabled(true);
EditText editTxt = (EditText) findViewById(R.id.editTxt);
editTxt.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
System.out.println("Text ["+s+"] - Start ["+start+"] - Before ["+before+"] - Count ["+count+"]");
if (count < before) {
// We're deleting char so we need to reset the adapter data
aAdpt.resetData();
}
aAdpt.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
iam solved this problem , also using base adapter You can try this
public class SubjectsActivity extends Activity {
private ImageView imgNavBarSubjectBook;
private ArrayList<String> arrSubjectResponse;
private ArrayList<String> arrChapterName;
private ArrayList<String> arrFileUrl;
private ArrayList<String> arrFileSize;
private ListView listChapter;
private TextView subjectName;
private EditText edtSearch;
private int textlength = 0;
// Google Analytics starts from here
private EasyTracker easyTracker = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_subjects);
easyTracker = EasyTracker.getInstance(SubjectsActivity.this);
subjectName = (TextView) findViewById(R.id.txtSubjectName);
imgNavBarSubjectBook = (ImageView) findViewById(R.id.img_nav_bar_Subject_book);
arrSubjectResponse = new ArrayList<String>();
arrChapterName = new ArrayList<String>();
arrFileUrl = new ArrayList<String>();
arrFileSize = new ArrayList<String>();
imgNavBarSubjectBook.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
Typeface tf = Typeface.createFromAsset(getAssets(), "Georgia.ttf");
subjectName.setTypeface(tf, Typeface.BOLD);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
arrSubjectResponse = bundle
.getStringArrayList("arr_subject_response");
for (int i = 1; i < arrSubjectResponse.size(); i = i + 8) {
arrChapterName.add(arrSubjectResponse.get(i + 2));
arrFileUrl.add(arrSubjectResponse.get(i + 6));
arrFileSize.add(arrSubjectResponse.get(i + 5));
}
}
listChapter = (ListView) findViewById(R.id.listChapter);
subjectName.setText(CoursesAdapter.Subject_Name);
listChapter.setAdapter(new SubjectAdapter(SubjectsActivity.this,
arrChapterName, arrFileUrl, arrFileSize));
edtSearch = (EditText) findViewById(R.id.edtSearchSubjects);
edtSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
textlength = edtSearch.getText().length();
arrChapterName.clear();
arrFileUrl.clear();
for (int i = 1; i < arrSubjectResponse.size(); i = i + 8) {
String name = arrSubjectResponse.get(i + 2);
String searchtext = String.valueOf(s);// edtSearch.getText().toString();
if (textlength <= arrSubjectResponse.get(i + 2).length()) {
if (name.toLowerCase().indexOf
(searchtext.toLowerCase()) != -1) {
Log.d("",
"------------Entered add value to list-----");
arrChapterName.add(arrSubjectResponse.get(i + 2));
arrFileUrl.add(arrSubjectResponse.get(i + 6));
arrFileSize.add(arrSubjectResponse.get(i + 5));
}
}
}
listChapter.setAdapter(new SubjectAdapter(
SubjectsActivity.this, arrChapterName, arrFileUrl,
arrFileSize));
Log.d("", "Chapter------->" + arrChapterName);
Log.d("", "Fileurl---------->" + arrFileUrl);
}
#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
}
});
}
#Override
public void onStart() {
super.onStart();
EasyTracker.getInstance(this).activityStart(this);
}
#Override
public void onStop() {
super.onStop();
EasyTracker.getInstance(this).activityStop(this);
}
}
I have a Listview in my asynctask and i am setting the adapter. I should implement the autosearch complete feature. My codes works fine but the list is not filtered when i enter the text in editable textview.
#Override
protected void onPostExecute(ArrayList<RouteTrackerUser> result)
{
dialog.dismiss();
if(result!=null)
{
//System.out.println("User with result===>"+result);
/*for(RouteTrackerUser r :result ){
System.out.println("Contents===>"+r.getStoreid()+" "+r.getStorename()+" "+r.getStorecode()+" "+r.getStoreno()+" "+r.getVisitcount());}
*/ Intent intent=getIntent();
TextView username=(TextView)findViewById(R.id.usrname);
final String sname=intent.getExtras().getString("user_name");
username.setText("Welcome, "+sname);
userList = (ListView) findViewById(R.id.historylist);
userAdapter = new HistoryAdapter(History.this, R.layout.history_visits,R.id.vcount,result);
userList.setAdapter(userAdapter);
EditText inputSearch = (EditText) findViewById(R.id.autocomplete);
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
System.out.println("afafasdf"+cs);
History.this.userAdapter.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
}
});
}
and my customAdapter is as follows :
private static class ViewHolder {
public final TextView storename;
public final TextView storevisitcount;
public ViewHolder(TextView name, TextView count) {
this.storename = name;
this.storevisitcount = count;
}
}
public class HistoryAdapter extends ArrayAdapter<RouteTrackerUser>
{
Context context;
//EditText autocomplete;
public HistoryAdapter(Context context,int resource,int textViewResourceId,ArrayList<RouteTrackerUser> result) {
super(context,resource,textViewResourceId, result);
this.context=context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView name;
TextView vcount;
final RouteTrackerUser User = getItem(position);
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.history_visits, parent, false);
name = (TextView) convertView.findViewById(R.id.sname);
vcount = (TextView) convertView.findViewById(R.id.vcount);
convertView.setTag(new ViewHolder(name, vcount));
convertView.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
viewdata(User.getUsername(),User.getUid(),User.getStoreid(),User.getStorename(),User.getStorecode(),User.getStoreno(),User.getVisitcount());
}});
} else {
ViewHolder viewHolder = (ViewHolder) convertView.getTag();
name = viewHolder.storename;
vcount = viewHolder.storevisitcount;
}
name.setText(User.getStorename());
vcount.setText("Visit Count: "+User.getVisitcount());
return convertView;
}
}
Note: My main class name is History.java and Asynctask name is HistorySoapTask.
After searching few blogs and other posts i found the answer for my question. I made a mistake, i doesn't implement the Filter concept in my program and now it works fine. So to filter the list we should define the filter as below :
private class OrderAdapterFilter extends Filter
{
#Override
protected FilterResults performFiltering(CharSequence constraint) {
constraint = constraint.toString().toLowerCase();
FilterText = (String) constraint;
FilterResults result = new FilterResults();
if(constraint != null && constraint.toString().length() > 0)
{
ArrayList<RouteTrackerUser> filt = new ArrayList<RouteTrackerUser>();
ArrayList<RouteTrackerUser> lItems = new ArrayList<RouteTrackerUser>(fullitems);
for(int i = 0, l = lItems.size(); i < l; i++)
{
RouteTrackerUser m = lItems.get(i);
if(m.getStorename().toLowerCase().contains(constraint))
filt.add(m);
}
result.count = filt.size();
result.values = filt;
}
else
{
ArrayList<RouteTrackerUser> list = new ArrayList<RouteTrackerUser>(fullitems);
result.values = list;
result.count = list.size();
}
return result;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// NOTE: this function is *always* called from the UI thread.
filtered = (ArrayList<RouteTrackerUser>)results.values;
originalitems.clear();
for(int i = 0, l = filtered.size(); i < l; i++)
originalitems.add(filtered.get(i));
notifyDataSetChanged();
}
}
So I have a basic custom listview with an image and text for each list item and I was wondering how I would filter through the listview dynamically with an edittext box. I looked up how to do it but I'm stuck at one point where I'm not sure what to do.
My listview is populated from an sqlitedatabase where I have methods that retrieve all the images names, text and ids from the database and puts them into the listview. Here is my code so far where I'm not quite sure what I should be doing in the publishResult() method
public class MainActivity extends Activity {
ListView data;
EditText inputSearch;
ArrayList<String> names, images, ids;
ArrayAdapter<String> adapter;
MyDatabase helper;
ImageView sprite;
TextView name, id;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
data = (ListView) findViewById(R.id.listView1);
helper = new MyDatabase(this);
helper.openDataBase();
names = helper.getNameList();
images = helper.getImageList();
ids = helper.getIdList();
adapter = new MyArrayAdapter(this);
data.setAdapter(adapter);
inputSearch = (EditText) findViewById(R.id.edit_search);
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
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
}
});
}
private class MyArrayAdapter extends ArrayAdapter<String>{
public MyArrayAdapter(Context c) {
super(c, R.layout.item_view,names);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (convertView == null){
row = getLayoutInflater().inflate(R.layout.item_view, parent,false);
}
sprite = (ImageView) row.findViewById(R.id.sprite);
name = (TextView) row.findViewById(R.id.name);
id = (TextView) row.findViewById(R.id.ids);
name.setText(names.get(position).toString());
int resID = getResources().getIdentifier(images.get(position),"drawable", getPackageName());
sprite.setImageResource(resID);
id.setText(ids.get(position).toString());
return row;
}
#Override
public Filter getFilter() {
// TODO Auto-generated method stub
return new Filter(){
#Override
protected FilterResults performFiltering(CharSequence input) {
FilterResults results = new FilterResults();
int originalLength = names.size();
if (input == null || input.length() == 0){
results.values = names;
results.count = originalLength;
} else {
ArrayList<String> newList = new ArrayList<String>();
for (int i = 0; i < originalLength; i++){
String str = names.get(i);
if (str.toLowerCase(Locale.getDefault()).contains(input))
newList.add(str);
results.values = newList;
results.count = newList.size();
}
}
return results;
}
#Override
protected void publishResults(CharSequence charSequence,
FilterResults results) {
//Not sure what to do here
notifyDataSetChanged();
}
};
}
}
Try this , I think it help you.
#Override
protected void publishResults(CharSequence charSequence,
FilterResults results) {
if(results.count==0)
{
notifyDataSetInvalidated();
}else
{
names=(ArrayList<String> names)results.values;
notifyDataSetChanged();
}
}
Thanks
Should be pretty simple at that point...
Edit:
public class FakeAdapter extends ArrayAdapter<Model> {
public class Model {
String my_string;
int resource_id;
}
private Activity activity;
/* ArrayList to hold the original values before filtering. */
private ArrayList<Model> original_list;
/* Current Data Filter */
private Filter filter;
public RelationshipsAdapter(Activity activity, int resource,
ArrayList<Model> objects) {
super(activity, resource, objects);
this.activity = activity;
this.original_list = objects;
}
/**
* Viewholder pattern to minimize findViewById calls.
*/
private static class ViewHolder {
TextView name;
ImageView image;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Model currentmodel = getItem(position);
View rowView = null;
if(convertView == null){
rowView = activity.getLayoutInflater().inflate(R.layout.my_item, parent, false);
final ViewHolder holder = new ViewHolder();
holder.name = (TextView) rowView.findViewById(R.id.item_text);
holder.image = (ImageView) rowView.findViewById(R.id.item_image);
rowView.setTag(holder);
} else {
rowView = convertView;
}
ViewHolder holder = (ViewHolder) rowView.getTag();
holder.name.setText(currentmodel.my_string);
holder.friendship.setImageResource(currentmodel.resource_id);
return rowView;
};
/**
* Returns a filter to the calling activity to filter the underlying data set by name.
*/
#Override
public Filter getFilter(){
if(filter == null){
filter = new ModelFilter();
}
return filter;
}
/** Custom Filter implementation used to filter names alphabetically on a provided prefix. */
private class ModelFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence search) {
FilterResults filter_results = new FilterResults();
String prefix = search.toString();
/* If the search is empty, display the original dataset. */
if(UserInputValidation.checkText(prefix).equals(StatusCode.NULL_INPUT)){
filter_results.values = original_list;
filter_results.count = original_list.size();
} else {
//make a copy of the original items and use that array list
final ArrayList<RelationshipModel> results = new ArrayList<RelationshipModel>(original_list);
final ArrayList<RelationshipModel> results_holder = new ArrayList<RelationshipModel>();
int count = results.size();
for(int i = 0; i < count; i++){
final RelationshipModel model = results.get(i);
final String name = (model.first_name + " " + model.last_name).toLowerCase(Locale.US);
if(name.contains(prefix))
results_holder.add(model);
}
filter_results.values = results_holder;
filter_results.count = results_holder.size();
}
return filter_results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
clear();
addAll((ArrayList<RelationshipModel>) results.values);
}
}
}
I have a custom ArrayAdaptor.
While add in getFilter features, I realise the filter item is getting lesser for my next search.
Even I delete the text inside the EditText, it only remain my last search record.
prodlistrowadapter.java
public prodlistrowAdapter(Context context, int layoutResourceId,
ArrayList<clsProducts> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.itemsdata = data;
//Log.e("context", String.valueOf(data.size()));
uploadedimgpath = context.getString(R.string.uploadedimgpath);
//this.original = new ArrayList<clsProducts> data;
originalItems = data;
}
static class ListHolder {
ImageView imgIcon;
TextView txtTitle;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
final clsProducts prod = getItem(position);
final ListHolder holder = new ListHolder();
try {
// if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
// LayoutInflater inflater = LayoutInflater.from(context);
row = inflater.inflate(layoutResourceId, parent, false);
holder.imgIcon = (ImageView) row
.findViewById(R.id.rowProdImageView);
holder.txtTitle = (TextView) row.findViewById(R.id.rowProdTextView);
// row.setTag(holder);
// } else {
// holder = (ListHolder) row.getTag();
// }
// clsProducts prod = items.get(position);
// holder.imgIcon.setImageResource(R.drawable.a1326965813select);
Drawable image = ImageOperations(context, uploadedimgpath
+ prod.image, "image.jpg");
holder.imgIcon.setImageDrawable(image);
holder.txtTitle.setText(prod.prod_name);
row.setFocusable(false);
row.setTag(prod.server_id);
// row.setClickable(true);
row.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
Intent packlistIntent = new Intent(v.getContext(),
catelist.class);
packlistIntent.putExtra("prodidselected",
String.valueOf(v.getTag()));
v.getContext().startActivity(packlistIntent);
} catch (Exception e) {
// Log.e("Exception - prodlistrowadapter",
// e.toString());
}
}
});
} catch (Exception ex) {
// Log.e("prodlistrowadap", ex.toString());
}
return row;
}
#Override
public void add(clsProducts item) {
itemsdata.add(item);
}
public Filter getFilter() {
if (filter == null)
filter = new PkmnNameFilter();
return filter;
}
#Override
public int getCount() {
synchronized (mLock) {
return itemsdata.size();
}
}
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
String prefix = constraint.toString().toLowerCase();
if (prefix == null || prefix.length() == 0) {
synchronized (mLock) {
results.values = itemsdata;
results.count = itemsdata.size();
}
} else {
synchronized (mLock) {
//Log.e("second",prefix);
final ArrayList<clsProducts> localItems = new ArrayList<clsProducts>();
final ArrayList<clsProducts> filteredItems = new ArrayList<clsProducts>();
localItems.addAll(itemsdata);
final int count = localItems.size();
for (int i = 0; i < count; i++) {
final clsProducts pkmn = localItems.get(i);
final String value = pkmn.getprodname().toLowerCase();
if (value.startsWith(prefix)) {
filteredItems.add(pkmn);
}
}
results.values = filteredItems;
results.count = filteredItems.size();
}
}
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
synchronized (mLock) {
final ArrayList<clsProducts> localItems = (ArrayList<clsProducts>) results.values;
notifyDataSetChanged();
clear();
for (clsProducts gi : localItems) {
add(gi);
}
}
}
}
catelist.java
List<clsProducts> prodList = cls.prodGetList(strSql);
ArrayList<clsProducts> proddata = (ArrayList<clsProducts>) prodList;
final prodlistrowAdapter adapter = new prodlistrowAdapter(this, R.layout.prodlistrow, proddata);
listView1 = (ListView) findViewById(R.id.lvCateList);
listView1.setTextFilterEnabled(true);
listView1.setAdapter(adapter);
EditText etinputSearch = (EditText)findViewById(R.id.etinputSearch);
etinputSearch.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
adapter.getFilter().filter(arg0);
//adapter.notifyDataSetChanged();
}
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}
public void afterTextChanged(Editable text) {
}
});
you need to create a setfilterfunction instead of calling the getFilter.filter(arg0).
public void SetFilter(CharSequence arg0)
{
// clean old filter and set new filter params
}