Using an EditText to search through a ListView - android

I'm trying to search through a ListView With the use of a TextView, after writing the code, it was Logging out what I did, but not filtering the List I want it to filter. Here is my code:
public class LabDetailActivity extends ActionBarActivity {
private LabAdapter labListAdapter;
private List<LabItem> labItem;
private TextView searchText;
private SearchView mSearchView;
private ListView list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.assigned_lab_fragments);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Labs");
searchText = (TextView) findViewById(R.id.labText);
list = (ListView) findViewById(android.R.id.list);
labItem = new ArrayList<LabItem>();
labListAdapter = new LabAdapter(this, labItem);
list.setAdapter(labListAdapter);
list.setTextFilterEnabled(true);
list.setOnItemClickListener(new ListItemClickListener());
searchText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
/*labListAdapter.getFilter().filter(charSequence.toString());
list.setAdapter(labListAdapter);*/
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
int textLength = charSequence.length();
List<LabItem> labItemss = new ArrayList<LabItem>();
for (LabItem ll : labItem){
if(textLength <= ll.getName().length()){
if (ll.getName().toLowerCase().contains(charSequence.toString().toLowerCase())){
labItemss.add(ll);
}
}
}
Log.d("SIZE OF SEARCH", String.valueOf(labItemss.size()));
labListAdapter = new LabAdapter(LabDetailActivity.this, labItemss);
list.setAdapter(labListAdapter);
}
#Override
public void afterTextChanged(Editable editable) {
/*Log.d("NEW TAGS", "*** Search value changed: " + editable.toString());
if (editable.toString().length() >= 3)
labListAdapter.getFilter().filter(editable.toString());*/
//labListAdapter.getFilter().filter(editable.toString());
//labListAdapter.notifyDataSetChanged();
}
});
}
private class ListItemClickListener implements ListView.OnItemClickListener{
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
}
}
private void RetrieveData(){
Uri uri2 = Uri.parse("content://" + getString(R.string.LEONE_AUTHORITY) + "/olabs");
Log.d("URL PRINT", uri2.toString());
final Cursor cursor = getContentResolver().query(uri2, null, null, null, "_id");
Log.d("CURSOR DATA:", cursor.toString());
JSONArray array = new JSONArray();
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
JSONObject object = new JSONObject();
try {
object.put("lab_number", cursor.getString(cursor.getColumnIndex("lab_case_number")));
object.put("lab_name", cursor.getString(cursor.getColumnIndex("lab_case_name")));
array.put(object);
Log.d("ARRAY", String.valueOf(array.length()));
} catch (JSONException e) {
e.printStackTrace();
}
}
parseJsonLabs(array);
cursor.close();
}
}
private void parseJsonLabs(JSONArray array){
Log.d("CASESARRAY", array.toString());
try {
labItem.clear();
for (int i = 0; i < array.length(); i++) {
JSONObject cases = (JSONObject) array.get(i);
LabItem items = new LabItem();
items.setName(cases.getString("lab_number"));
items.setCase(cases.getString("lab_name"));
labItem.add(items);
}
labListAdapter.notifyDataSetChanged();
} catch (JSONException e) {
// TODO: handle exception
Log.e("ARRAYTEST", "ERROR:", e);
}
}
#Override
protected void onResume() {
super.onResume();
RetrieveData();
}
}
Then, the Adapter code is here
Adapter
public class LabAdapter extends BaseAdapter implements Filterable{
private Activity activity;
private LayoutInflater inflater;
private List<LabItem> labItem;
private TextView labName, labCase;
public LabAdapter(Activity activity, List<LabItem> labItem){
this.activity = activity;
this.labItem = labItem;
}
#Override
public int getCount() {
return labItem.size();
}
#Override
public Object getItem(int position) {
return labItem.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
if (inflater == null)
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.custom_lab_activity_list, null);
labName = (TextView) convertView.findViewById(R.id.custom_lab_name);
labCase = (TextView) convertView.findViewById(R.id.custom_lab_case);
LabItem labs = labItem.get(position);
labName.setText(labs.getName());
labCase.setText(labs.getCase());
return convertView;
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
Log.d("SEARCHTEXT2", "**** PERFORM FILTERING for: " + charSequence);
charSequence = charSequence.toString().toLowerCase();
FilterResults filts = new FilterResults();
if (charSequence == null || charSequence.length() == 0){
filts.values = labItem;
filts.count = labItem.size();
} else {
// We perform filtering operation
List<LabItem> labrs = new ArrayList<LabItem>();
for (LabItem l : labrs){
if (l.getName().startsWith(charSequence.toString()) || l.getCase().startsWith(charSequence.toString()))
labItem.add(l);
}
filts.values = labItem;
filts.count = labItem.size();
//filts.count = labItem.size();
}
return filts;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
// Now we have to inform the adapter about the new list filtered
Log.d("SEARCHTEXT1", "**** PUBLISHING RESULTS for: " + charSequence);
if (filterResults.count == 0)
notifyDataSetInvalidated();
else {
labItem = (List<LabItem>) filterResults.values;
notifyDataSetChanged();
}
}
};
}
public void notifyDataSetChanged(){
super.notifyDataSetChanged();
}
}
And the Item class is here
Item Class
public class LabItem {
String labCase, labName;
public LabItem() {
}
public LabItem(String labCase, String labName){
super();
this.labCase = labCase;
this.labName = labName;
}
public String getName(){
return labName;
}
public void setName(String name){
this.labName = name;
}
public String getCase(){
return labCase;
}
public void setCase(String cases){
this.labCase = cases;
}
}
I don't know if I'm not updating the ListView very well or something. When I type a i see the count, but If I add another letter. The LIST would be gone. Any help would be appreciated. Thanks in advance.

Few Logical Mistakes : I got here this code working at my end
public LabAdapter(Activity activity, List<LabItem> labItem){
this.activity = activity;
this.labItem = labItem;
}
#Override
public int getCount() {
return labItem.size();
}
#Override
public LabItem getItem(int position) { //instead of Object make it Labitem
return labItem.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
if (inflater == null)
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.activity_stack, null);
labName = (TextView) convertView.findViewById(R.id.textView1);
labCase = (TextView) convertView.findViewById(R.id.textView2);
LabItem labs = labItem.get(position);
labName.setText(labs.getName());
labCase.setText(labs.getCase());
return convertView;
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
Log.d("SEARCHTEXT2", "**** PERFORM FILTERING for: " + charSequence);
charSequence = charSequence.toString().toLowerCase();
FilterResults filts = new FilterResults();
if (charSequence == null || charSequence.length() == 0){
filts.values = labItem;
filts.count = labItem.size();
} else {
// We perform filtering operation
List<LabItem> labrs = new ArrayList<LabItem>();
for (LabItem l : labItem){ //you are going to search in labItem that contains the data and not the empty list labrs
if (l.getName().startsWith(charSequence.toString()) || l.getCase().startsWith(charSequence.toString())){
Log.e("(l.getName().startsWith(charSequence.toString())","" + charSequence);
labrs.add(l); // add to the new list**
}
}
filts.values = labrs; //set values to the new list**
filts.count = labrs.size();
//filts.count = labItem.size();
}
return filts;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
// Now we have to inform the adapter about the new list filtered
Log.d("SEARCHTEXT1", "**** PUBLISHING RESULTS for: " + charSequence);
List<LabItem> filtered = (List<LabItem>) filterResults.values;
labItem = filtered; // set the new data as you want with the new set you've received.**
notifyDataSetChanged();
}
};
}
public void notifyDataSetInvalidated()
{
super.notifyDataSetInvalidated();
}
then in your LabDetailActivity.class change it as
searchText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
labListAdapter.getFilter().filter(charSequence.toString());
Log.d("NEW TAGS", "*** Search value changed: " + labListAdapter.getCount());
list.invalidate();
labListAdapter.notifyDataSetChanged();
list.setAdapter(labListAdapter);
}
Edit:
P.S. This code is still not perfect as after clearing the text it
doesn't sets the list back. I leave it to you. Hope this solves your
problem you've been facing.
Let me know if it works.

Related

ArrayAdapter Custom filter not working

I have a problem with my custom filter. I make it, and it works well. When I debug code, it filtrates array well, but I have a problem in void publishResults(). I don't know what is a problem, anyone helps?
public class KatalogAdapter extends ArrayAdapter<Katalog> implements Filterable {
List<Katalog> object;
int num = 0;
public KatalogAdapter(#NonNull Context context, #LayoutRes int resource, #NonNull List<Katalog> objects) {
super(context, resource, objects);
object = objects;
}
public void setObject(List<Katalog> kat){
this.object = kat;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View v = convertView;
if(v==null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.katalozi_item, null);
}
Katalog katalog = object.get(position);
ImageView katalogImage = (ImageView) v.findViewById(R.id.katalogImage);
TextView katalogProizvodjac = (TextView) v.findViewById(R.id.katalogProizvodjac);
TextView katalogVaziDo = (TextView) v.findViewById(R.id.katalogVaziDo);
TextView idKataloga = (TextView) v.findViewById(R.id.idKataloga);
String src = katalog.getImageSRC();
Picasso.with(getContext()).load(src).into(katalogImage);
/*Glide.with(getContext()).load(src).thumbnail(Glide.with(getContext()).load(R.drawable.loading_icon))
.fitCenter()
.crossFade().into(katalogImage); */
// katalogImage.setImageBitmap(bitmap);
katalogProizvodjac.setText(katalog.getKatalogProizvodjac());
String doe = katalog.getKatalogVaziDo();
char lastChar = doe.charAt(doe.length() - 1);
if(lastChar=='1'){
katalogVaziDo.setText("Važi još "+ doe +" dan");
}
if(doe.equals("0")){
katalogVaziDo.setText("Važi još danas");
}
if(lastChar!='1' && !doe.equals("0")){
katalogVaziDo.setText("Važi još "+katalog.getKatalogVaziDo() + " dana");
}
// katalogVaziDo.setText("Važi do: "+katalog.getKatalogVaziDo());
idKataloga.setText(String.valueOf(katalog.getIdKataloga()));
return v;
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<Katalog> tempList=new ArrayList<Katalog>();
//constraint is the result from text you want to filter against.
//objects is your data set you will filter from
if(constraint != null && object!=null) {
int length=object.size();
int i=0;
while(i<length){
Katalog item=object.get(i);
if(item.getKatalogProizvodjac().toLowerCase(Locale.getDefault()).contains(constraint.toString().toLowerCase())){
tempList.add(item);
}
i++;
}
//following two lines is very important
//as publish result can only take FilterResults objects
filterResults.values = tempList;
filterResults.count = tempList.size();
}
return filterResults;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// object = (ArrayList<Katalog>) results.values;
setObject((List<Katalog>) results.values);
num = results.count;
notifyDataSetChanged();
}
};
}
}
I was looking for an answer, and I found that in that function I need to put in array my data. I did it, but still not work.
i am provide recyler view adapter with filter for contact details and you can change code your need according.
public class InviteContactAdapter extends RecyclerView.Adapter<InviteContactAdapter.ItemViewHolder> implements Filterable {
private List<UserContact> mContactList = new ArrayList<>();
private List<UserContact> mContectFilter = new ArrayList<>();
private Context mContext;
private CustomFilter mFilter;
public List<String> mEmailList = new ArrayList<>();
public InviteContactAdapter(Context context, List<UserContact> mContactList) {
mContext = context;
this.mContactList = mContactList;
this.mContectFilter = mContactList;
mFilter = new CustomFilter();
}
public onItemClickListener onItemClickListener;
public void setOnItemClickListener(InviteContactAdapter.onItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.invite_contact_row_layout, viewGroup, false);
return new ItemViewHolder(view);
}
public interface onItemClickListener {
void onClick(UserContact contact);
}
#Override
public Filter getFilter() {
return mFilter;
}
#Override
public void onBindViewHolder(final ItemViewHolder itemViewHolder, int i) {
final UserContact contact = mContectFilter.get(i);
itemViewHolder.mTvUserNane.setText(contact.getUserName().trim());
itemViewHolder.mTvUserEmail.setText(contact.getUserEmail().trim());
if (contact.isSelect())
itemViewHolder.mIvSelect.setImageResource(R.drawable.check_contect);
else
itemViewHolder.mIvSelect.setImageResource(R.drawable.un_check_contact);
itemViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (contact.isSelect()) {
contact.setSelect(false);
itemViewHolder.mIvSelect.setImageResource(R.drawable.un_check_contact);
} else {
contact.setSelect(true);
itemViewHolder.mIvSelect.setImageResource(R.drawable.check_contect);
}
}
});
}
#Override
public int getItemCount() {
return mContectFilter.size();
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
private TextView mTvUserNane, mTvUserEmail;
private ImageView mIvSelect;
public ItemViewHolder(View itemView) {
super(itemView);
mTvUserEmail = itemView.findViewById(R.id.icrlTvUserEmail);
mTvUserNane = itemView.findViewById(R.id.icrlTvUserName);
mIvSelect = itemView.findViewById(R.id.icrlIvSelect);
}
}
public List<String> getEmail() {
mEmailList.clear();
for (UserContact contact : mContectFilter) {
if (contact.isSelect()) {
mEmailList.add(contact.getUserEmail());
}
}
return mEmailList;
}
/**
* this class for filter data.
*/
class CustomFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults results = new FilterResults();
if (charSequence != null && charSequence.length() > 0) {
ArrayList<UserContact> filters = new ArrayList<>();
charSequence = charSequence.toString().toUpperCase();
for (int i = 0; i < mContactList.size(); i++) {
if (mContactList.get(i).getUserName().toUpperCase().contains(charSequence) || mContactList.get(i).getUserEmail().toUpperCase().contains(charSequence)) {
UserContact contact = new UserContact();
contact.setUserName(mContactList.get(i).getUserName());
contact.setUserEmail(mContactList.get(i).getUserEmail());
filters.add(contact);
}
}
results.count = filters.size();
results.values = filters;
} else {
results.count = mContactList.size();
results.values = mContactList;
}
return results;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mContectFilter = (ArrayList<UserContact>) filterResults.values;
notifyDataSetChanged();
}
}
}
and call into activity in edittext box for filter record like below ..
filter the data
Note: make sure your adapter object not null
/**
* this method filter data.
*/
private void sortData(View root) {
mEtSearchData = (EditText) root.findViewById(R.id.icffEtSearch);
mEtSearchData.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (inviteContactAdapter != null) {
inviteContactAdapter.getFilter().filter(s);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
My problem was that in some line I hade gridView.setAdapter(null).
However, I had one more problem, in gridView I had 5 elements, after filtering, I had one item filled with real data and 4 more empty items.. So, I changed getView function..
If someone need it, here it is:
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View v = convertView;
if(v==null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.katalozi_item, null);
}
if(objectfilt.size()>position){
Katalog katalog = objectfilt.get(position);
ImageView katalogImage = (ImageView) v.findViewById(R.id.katalogImage);
TextView katalogProizvodjac = (TextView) v.findViewById(R.id.katalogProizvodjac);
TextView katalogVaziDo = (TextView) v.findViewById(R.id.katalogVaziDo);
TextView idKataloga = (TextView) v.findViewById(R.id.idKataloga);
String src = katalog.getImageSRC();
Picasso.with(getContext()).load(src).into(katalogImage);
/*Glide.with(getContext()).load(src).thumbnail(Glide.with(getContext()).load(R.drawable.loading_icon))
.fitCenter()
.crossFade().into(katalogImage); */
// katalogImage.setImageBitmap(bitmap);
katalogProizvodjac.setText(katalog.getKatalogProizvodjac());
String doe = katalog.getKatalogVaziDo();
char lastChar = doe.charAt(doe.length() - 1);
if(lastChar=='1'){
katalogVaziDo.setText("Važi još "+ doe +" dan");
}
if(doe.equals("0")){
katalogVaziDo.setText("Važi još danas");
}
if(lastChar!='1' && !doe.equals("0")){
katalogVaziDo.setText("Važi još "+katalog.getKatalogVaziDo() + " dana");
}
// katalogVaziDo.setText("Važi do: "+katalog.getKatalogVaziDo());
idKataloga.setText(String.valueOf(katalog.getIdKataloga()));
return v;
}
else {
v.setVisibility(View.GONE);
return v;
}
So, elements from ListArray objectfilt are added, and when int position become bigger than number of ListView elements, then just hide that views.

search filter in listview returns wrong value on item click

I have a listview getting filtered by an edit text on top.However when i click on the item searched i get the result of another item being selected. there r also some data stored in my array which is not visible on listview , is also returning wrong data.
On searching C you get the result filtered as C.But clicking on it results is like the position does not change for the other data but uses the original ArrayList adapter position.
Any help will be appreciated.
My items:
public class Leave_master_items {
public String leave_id;
public String leave_Name;
public String is_hourly;
public Leave_master_items(String leave_Name) {
this.leave_Name = leave_Name;
}
public String getLeave_id() {
return leave_id;
}
public void setLeave_id(String leave_id) {
this.leave_id = leave_id;
}
public String getLeave_Name() {
return leave_Name;
}
public void setLeave_Name(String leave_Name) {
this.leave_Name = leave_Name;
}
public String getIs_hourly() {
return is_hourly;
}
public void setIs_hourly(String is_hourly) {
this.is_hourly = is_hourly;
}
}
My Adapter:
public class Leave_name_adapter extends BaseAdapter implements Filterable{
ArrayList<Leave_master_items> cm = new ArrayList<>();
Context context;
ArrayList<Leave_master_items> mStringFilterList;
ValueFilter valueFilter;
#Override
public Filter getFilter() {
if (valueFilter == null) {
valueFilter = new ValueFilter();
}
return valueFilter;
// return null;
}
static class ListViewHolder {
TextView leaveType;
}
public Leave_name_adapter(ArrayList<Leave_master_items> cm, Context context) {
this.cm = cm;
this.context = context;
mStringFilterList = cm;
}
#Override
public int getCount() {
return cm.size();
}
#Override
public Object getItem(int position) {
return cm.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ListViewHolder viewHolder;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.leaves_listview, parent, false);
viewHolder = new ListViewHolder();
viewHolder.leaveType = (TextView) row.findViewById(R.id.leavestype);
row.setTag(viewHolder);
} else {
viewHolder = (ListViewHolder) row.getTag();
}
Leave_master_items l = (Leave_master_items) getItem(position);
viewHolder.leaveType.setText(l.getLeave_Name());
return row;
}
private class ValueFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// cm.clear();
if (constraint != null && constraint.length() > 0) {
ArrayList<Leave_master_items> filterList = new ArrayList<Leave_master_items>();
for (int i = 0; i < mStringFilterList.size(); i++) {
if ((mStringFilterList.get(i).getLeave_Name().toUpperCase())
.contains(constraint.toString().toUpperCase())) {
Leave_master_items country = new Leave_master_items(mStringFilterList.get(i).getLeave_Name());
filterList.add(country);
}
}
results.count = filterList.size();
results.values = filterList;
} else {
results.count = mStringFilterList.size();
results.values = mStringFilterList;
}
return results;
}
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
cm = (ArrayList<Leave_master_items>) results.values;
notifyDataSetChanged();
}
}
}
My activity:
leave_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new Leave_list().execute();
a.setVisibility(View.INVISIBLE);
b.setVisibility(View.VISIBLE);
v.setBackgroundResource(R.drawable.date_button_bg);
date.setBackgroundResource(R.drawable.leave_button_bg);
leave_btn.setTextColor(Color.parseColor("#293038"));
date.setTextColor(Color.parseColor("#F8F8F8"));
search_leave.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
Leave_application.this.leave_name_adapter.getFilter().filter(arg0);
}
#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 Leave_list extends AsyncTask<String, Void, Boolean> {
protected void onPreExecute() {
leave_master_itemses.clear();
}
#Override
protected void onPostExecute(final Boolean success) {
leave_name_adapter=new Leave_name_adapter(leave_master_itemses,getApplicationContext());
listview_leave.setAdapter(leave_name_adapter);
listview_leave.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Object a = parent.getAdapter().getItem(position);
String b = (String) parent.getItemAtPosition(position);
Leave_master_items leave_master_items=leave_master_itemses.get(position);
selectedFromList=leave_master_items.getLeave_id();
Log.d("Yourtag", selectedFromList);
// Log.d("Clicked item field", " "+ item.getColum(your colum index));
}
});
}
protected Boolean doInBackground(final String... args) {
try {
Login_json_parser jParser = new Login_json_parser();
String s = session.isWEBURL()+"?Function=" + session.isKEY_USERNAME() + "&Emp=" + session.iskey_emp_id();
Log.d("s", s);
JSONObject json1 = jParser.getJSONFromUrl(s);
Log.d("Inputfdfdtsale Stream", "json1");
try {
JSONObject object = (JSONObject) new JSONTokener(json1.toString()).nextValue();
Leave = object.getString("Leave");
Log.d("ew", Leave);
JSONArray jsonArray = new JSONArray(Leave);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = new JSONObject();
jsonObject=jsonArray.getJSONObject(i);
Leave_master_items leave_master_items = new Leave_master_items(null);
leave_master_items.setIs_hourly(jsonObject.getString("is_hourly"));
leave_master_items.setLeave_id(jsonObject.getString("leave_id"));
leave_master_items.setLeave_Name(jsonObject.getString("leave_Name"));
leave_master_itemses.add(leave_master_items);
}
}
catch(JSONException e){
e.printStackTrace();
}
}
catch (Exception e1) {
e1.printStackTrace();
}
return null;
}
}
You have to ask the adapter to get the right object.
Instead of
Leave_master_items leave_master_items = leave_master_itemses.get(position);
try
Leave_master_items leave_master_items = listview_leave.getAdapter().getItem(position);
UPDATE
When you filter you don't have to create a new object with the same content. Just use the object which already exist.
Instead of
Leave_master_items country = new Leave_master_items(mStringFilterList.get(i).getLeave_Name());
filterList.add(country);
Do
filterList.add(mStringFilterList.get(i));
UPDATE2
Don't return 0 in getItemId()
#Override
public long getItemId(int position) {
return position;
}
The problem here is as soon as you start searching something in edittext, your list content changes and you might be using the old list to get the item.
Create a setter in your adapter class for the list you just got after filtering and use that list in your onItemCLick to fetch the position you want to fetch.

Android ListView does not refresh by Filter

In my application I have three fragment with ViewPager. one of this fragments i have simple Arraylist as ListView from phones contact list and i'm trying to filter that after typing into edittext.
but doesn't refresh until softkeyboard is visible and I must have to hide keyboard to refresh list view by filtered strings.
For example:
filter listview by "a":
adapter.getFilter().filter("a");
My adapter:
public class AdapterContacts extends BaseAdapter implements Filterable {
private LayoutInflater inflater;
private Context context;
private List<ContactLists> categoryArrayList;
private final ArrayList<ContactLists> originalList = new ArrayList<ContactLists>();
private NameFilter filter;
public AdapterContacts(ArrayList<ContactLists> array) {
categoryArrayList = array;
}
public AdapterContacts(Context context, List<ContactLists> array) {
this.context = context;
inflater = LayoutInflater.from(this.context);
categoryArrayList = array;
originalList.addAll(array);
}
#Override
public int getCount() {
return categoryArrayList.size();
}
#Override
public ContactLists getItem(int position) {
return categoryArrayList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder mViewHolder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.layout_contacts_list_item, null);
mViewHolder = new ViewHolder(convertView);
convertView.setTag(mViewHolder);
} else {
mViewHolder = (ViewHolder) convertView.getTag();
}
ContactLists item = getItem(position);
mViewHolder.fillItems(this, item, position);
return convertView;
}
private static class UI extends HelperUI {
public TextView tv_person_nickname_mobile_number;
public TextView btn_invite_message;
public ImageView img_contact_image;
public ImageView imgv_user_rank;
public TextView tv_contact_name;
public LinearLayout ll_root;
public UI(View view) {
parseUi(view);
}
}
private class ViewHolder {
private UI UI;
public ViewHolder(View view) {
UI = new UI(view);
}
public void fillItems(final AdapterContacts adapter, final ContactLists item, final int position) {
UI.tv_contact_name.setText(item.getContact_name());
if (item.getStatus() == 1) {
UI.btn_invite_message.setVisibility(View.GONE);
UI.imgv_user_rank.setVisibility(View.VISIBLE);
if (item.getRank() != null || !TextUtils.isEmpty(item.getRank())) {
//Picasso.with(G.context).load(item.getRank()).into(UI.imgv_user_rank);
}
UI.tv_person_nickname_mobile_number.setText(item.getNick_name());
//UI.ll_root.setBackgroundDrawable(G.context.getResources().getDrawable(R.drawable.selector_button_actions));
if (item.getContact_image() == null || TextUtils.isEmpty(item.getContact_image())) {
Bitmap bitmap = UC.getContactPhoto(item.getMobile_number(), G.context.getContentResolver());
if (bitmap != null) {
UI.img_contact_image.setImageBitmap(bitmap);
} else {
UI.img_contact_image.setImageDrawable(G.context.getResources().getDrawable(R.drawable.no_avatar));
}
} else {
// show user avatar from web
//Picasso.with(G.context).load(item.getContact_image()).into(UI.img_contact_image);
UI.img_contact_image.setImageBitmap(BitmapFactory.decodeFile(G.dir_image + "/" + item.getContact_image()));
}
} else {
// UI.ll_root.setBackgroundDrawable(G.context.getResources().getDrawable(R.drawable.selector_invite_actions));
UI.btn_invite_message.setVisibility(View.VISIBLE);
UI.imgv_user_rank.setVisibility(View.GONE);
UI.btn_invite_message.setText(UC.getString(R.string.invite_person));
UI.btn_invite_message.setBackgroundDrawable(G.context.getResources().getDrawable(R.drawable.shape_invite_button_default));
UI.tv_person_nickname_mobile_number.setText(item.getMobile_number());
Bitmap bitmap = UC.getContactPhoto(item.getMobile_number(), G.context.getContentResolver());
if (bitmap != null) {
UI.img_contact_image.setImageBitmap(bitmap);
} else {
UI.img_contact_image.setImageDrawable(G.context.getResources().getDrawable(R.drawable.no_avatar));
}
}
}
}
#Override
public Filter getFilter() {
if (filter == null) {
filter = new NameFilter();
}
return filter;
}
public class NameFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
String searchText = constraint.toString().toLowerCase();
ArrayList<ContactLists> newList = filterListBasedOnSearchText(searchText);
results.values = newList;
results.count = newList.size();
return results;
}
private ArrayList<ContactLists> filterListBasedOnSearchText(String constraint) {
ArrayList<ContactLists> newList = new ArrayList<ContactLists>();
int l = originalList.size();
for (int i = 0; i < l; i++) {
ContactLists nameList = originalList.get(i);
if (nameList.getContact_name().toString().contains(constraint)) {
newList.add(nameList);
}
}
return newList;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
categoryArrayList = (ArrayList<ContactLists>) results.values;
notifyDataSetChanged();
}
}
}
softkeyboard status status in Manifest for ActivityMain. this class have view pager with three fragment:
<activity android:name=".Activities.ActivityBootstrap" android:windowSoftInputMode="adjustPan" android:screenOrientation="portrait"/>
other way to do Filter in fragment without Adapter's ability
edt_sample.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
String text = edt_sample.getText().toString();
filter(text);
}
});
public void filter(String charText) {
drinks.clear();
if (charText.length() == 0) {
drinks.addAll(contact_list);
} else {
for (ContactLists wp : contact_list) {
if (wp.getContact_name().contains(charText)) {
drinks.add(wp);
}
}
}
contact_list.clear();
contact_list.addAll(drinks);
adapter.notifyDataSetChanged();
}
ListView succesful filtered by when i close or hide softkeyboard that refresh with nw items.
You're not making use of your adapter filter as I see from the code posted by you. I'll post here an example filter and how to call it (kept all your variable names to make it easier).
The 'NameFilter' class, inside your adapter class:
public class NameFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
String searchText = constraint.toString().toLowerCase();
ArrayList<ContactLists> newList = filterListBasedOnSearchText(searchText);
results.values = newList;
results.count = newList.size();
return results;
}
private ArrayList<ContactLists> filterListBasedOnSearchText(String constraint) {
ArrayList<ContactLists> newList = new ArrayList<ContactLists>();
int l = originalList.size();
for (int i = 0; i < l; i++) {
ContactLists nameList = originalList.get(i);
if (nameList.getContact_name().toString().contains(constraint)) {
newList.add(nameList);
}
}
return newList;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
categoryArrayList = (ArrayList<ContactLists>) results.values;
notifyDataSetChanged();
}
}
The 'TextWatcher' interface method implementation in your list fragment:
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void afterTextChanged(Editable s) {
String text = searchView.getText().toString();
NameFilter itemFilter = (NameFilter) adapter.getFilter();
itemFilter.filter(text);
}
Also, some observations:
if 'ContactLists' is a contact, name it 'Contact', to avoid confusion
I would use a 'SearchView', instead of an 'EditText'
I don't know how you get the contact list, but there's a guide about it here (if you didn't look at it already)
It is very simple to implement. Please follow these below steps:
Step 1:
Initialize Edittext:
editTextVideoFolderSearch = (EditText) rootView.findViewById(R.id.editTextVideoFolderSearch);
Step 2:
Add TextChangedListener on this edittext. like:
editTextVideoFolderSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence t, int start, int before,
int count) {
videoDetailBeansSearch.clear();
for (int i = 0; i < videoDetailBeans_total.size(); i++) {
if (videoDetailBeans_total.get(i).getAlbum().toLowerCase()
.contains(t)) {
videoDetailBeansSearch.add(videoDetailBeans_total.get(i));
}
}
if (videoDetailBeansSearch.size() > 0) {
video_folder_gridView.setAdapter(new AlbumGridAdapter(getActivity(), videoDetailBeansSearch));
} else {
video_folder_gridView.setAdapter(new AlbumGridAdapter(getActivity(), videoDetailBeansSearch));
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
Step 3: you have to make different beans for populating the adapter in list view:
private ArrayList<MediaDetailBean> videoDetailBeansSearch = new ArrayList<MediaDetailBean>();
private ArrayList<MediaDetailBean> videoDetailBeans_total = new ArrayList<MediaDetailBean>();
private ArrayList<MediaDetailBean> videoDetailBeans_delete = new ArrayList<MediaDetailBean>();
Step 4: Polulate the list at the time of Activity or fragment loaded:
public class GetVideoAsynctask extends AsyncTask<String, String,Object[]> {
ProgressDialog progressDialog ;
String response = "";
int offset, limit;
public GetVideoAsynctask(int offset1, int limit1) {
offset = offset1;
limit = limit1;
}
#Override
public void onPreExecute() {
progressDialog = ProgressDialog.show(getActivity(),"Loading...", "Please Wait");
}
#Override
public Object[] doInBackground(String... params) {
return AppParsing.getMediaDetails(getActivity(), AppPreferenceUtils.getChildUploadDeviceId(getActivity()),
AppPreferenceUtils.getChildRaId(getActivity()),"2", offset, limit,"3");
//// type=1 for image,2 for video,3 for audio
}
#SuppressWarnings("unchecked")
#Override
public void onPostExecute(Object[] result) {
progressDialog.cancel();
try
{
boolean status = (Boolean) result[0];
response = (String) result[1];
if(status)
{
videoDetailBeans = (ArrayList<MediaDetailBean>) result[2] ;
for (int i = 0; i < videoDetailBeans.size(); i++) {
videoDetailBeans_total.add(videoDetailBeans.get(i));
}
isCheck_video = new boolean[videoDetailBeans_total.size()];
for(int i=0;i<videoDetailBeans_total.size();i++)
{
if(!GRID_DATA.contains(videoDetailBeans_total.get(i).getAlbum()))
{
GRID_DATA.add(videoDetailBeans_total.get(i).getAlbum());
}
}
video_folder_gridView.setAdapter(new AlbumGridAdapter(getActivity(), videoDetailBeans_total));
//Toast.makeText(getActivity(), response, Toast.LENGTH_SHORT).show();
}
else
{
response = (String) result[1];
AppUtils.showDialog(getActivity(), response);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Step 5: Set the listview adapter like:
new GetVideoAsynctask(offset1, limit1).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
Step 6: Most important thinning is i am taking load more list view here:
com.costum.android.widget.LoadMoreListView) video_folder_gridView = (com.costum.android.widget.LoadMoreListView) rootView.findViewById(R.id.video_folder_gridView);
Step 7: In my xml i am declaring like this:
<com.costum.android.widget.LoadMoreListView
android:id="#+id/video_folder_gridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="90dp"
android:gravity="center"
android:horizontalSpacing="10dp"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp" />
Feel free if you have any query regarding this concept.
This is my implementation of Filter which filters while you type a single letter.This is the Activity implementation...
public class MessagesActivity extends Activity{
private ListView msgListView;
private EditText mSearchContent;
private MessagesAdapter msgAdapter;
public static ArrayList<MessagesBean> allMsgsList = new ArrayList<MessagesBean>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messages);
init();
msgAdapter = new MessagesAdapter(getApplicationContext(), allMsgsList, MessagesActivity.this);
msgListView.setAdapter(msgAdapter);
}
private void init() {
// TODO Auto-generated method stub
msgListView = (ListView) findViewById(R.id.messages_list);
msgListView.setOnScrollListener(this);
mSearchContent.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
public void afterTextChanged(Editable s) {
msgAdapter.getFilter().filter(s.toString());
}
});
}
This is the Adapter implementation
public class MessagesAdapter extends BaseAdapter implements Filterable {
private Context mcontext;
private ArrayList<MessagesBean> all_details, dup_all_details;
private LayoutInflater inflater;
private DisplayImageOptions options;
private CustomClickLisntener clickLisntener;
private MessagesBean mMessagesBean;
private ViewHolder selectedHolder;
private ListViewFilter listviewFilter;
// int pos = 0;
public MessagesAdapter(Context context, ArrayList<MessagesBean> all_list, CustomClickLisntener lisntener) {
mcontext = context;
all_details = all_list;
clickLisntener = lisntener;
inflater = (LayoutInflater) mcontext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
options = new DisplayImageOptions.Builder().cacheInMemory(true).cacheOnDisk(true).build();
dup_all_details = all_list;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return all_details.size();
}
#Override
public MessagesBean getItem(int position) {
// TODO Auto-generated method stub
return all_details.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
static class ViewHolder {
TextView user_name, msg_sub, msg_content, msg_time;
ImageView user_image;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewholder = null;
if (convertView == null) {
viewholder = new ViewHolder();
convertView = inflater.inflate(R.layout.row_item_inbox_msg, null);
viewholder.user_name = (TextView) convertView.findViewById(R.id.user_name);
viewholder.msg_time = (TextView) convertView.findViewById(R.id.msg_time);
viewholder.msg_sub = (TextView) convertView.findViewById(R.id.msg_subject);
viewholder.user_image = (ImageView) convertView.findViewById(R.id.user_image);
viewholder.msg_content = (TextView) convertView.findViewById(R.id.msg_content);
// viewholder.down_arrow.setTag(position);
convertView.setTag(viewholder);
} else {
viewholder = (ViewHolder) convertView.getTag();
}
mMessagesBean = all_details.get(position);
viewholder.user_name.setText(mMessagesBean.getFirstname().trim() + " " + mMessagesBean.getLastname());
viewholder.msg_time.setText(DateDifferent.getDateDifferance(mMessagesBean.getSentDate()));
viewholder.msg_sub.setText(mMessagesBean.getSubject());
viewholder.msg_content.setText(mMessagesBean.getMessage());
ImageLoader.getInstance().displayImage(mMessagesBean.getUserimage(), viewholder.user_image, options);
return convertView;
}
#Override
public Filter getFilter() {
// TODO Auto-generated method stub
if (listviewFilter == null) {
listviewFilter = new ListViewFilter();
}
return listviewFilter;
}
public class ListViewFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
// TODO Auto-generated method stub
constraint = constraint.toString();
ArrayList<MessagesBean> allitems = new ArrayList<MessagesBean>();
FilterResults filterresults = new FilterResults();
if (constraint != null && constraint.toString().length() > 0) {
for (int i = 0; i < dup_all_details.size(); i++) {
if (dup_all_details.get(i).getFirstname().contains(constraint)
|| dup_all_details.get(i).getLastname().contains(constraint)) {
allitems.add(dup_all_details.get(i));
}
}
filterresults.count = allitems.size();
filterresults.values = allitems;
} else {
System.out.println(" iam here..." + all_details.size());
synchronized (this) {
filterresults.count = allitems.size();
filterresults.values = allitems;
}
}
return filterresults;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// TODO Auto-generated method stub
all_details = (ArrayList<MessagesBean>) results.values;
MessagesActivity.allMsgsList = all_details;
MessagesAdapter.this.notifyDataSetChanged();
}
}
}
You can do it like:
public void filter(String charText) {
drinks.clear();
if (charText.length() == 0) {
drinks.addAll(contact_list);
} else {
for (ContactLists wp : contact_list) {
if (wp.getContact_name().contains(charText)) {
drinks.add(wp);
}
}
}
contact_list.clear();
contact_list.addAll(drinks);
adapter.notifyDataSetChanged(contact_list);
}
and in your adapter:
public void notifyDataSetChanged(List<ContactLists> items){
this.categoryArrayList = items;
super.notifyDataSetChanged();
}

Android Custom Adapter Filter not working

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

Android autocompletetextview to have two adapter for suggestion

I have a problem in making suggestion in AutoCompleteTextView in this pattern
[action actionFromContact] (these are 2 adapter) ex call michael (where "call" comes from action adapter , "michael" from actionFromContact adapter these following code does first it set adapter in AutoCompleteTextView to item and when text changes to call it reset to contact db from name so its like call michael ,
Problem item array is too big so I can't use replace thing , second replacing remove the first entry when second entry i.e name is been selected from drop down menu as its been replaced by space
private AutoCompleteTextView mEditText;
private TextWatcher mTextWatcher;
private ContactPickerAdapter contactPickerAdapter;
String item[] = { "Call", "Call back"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditText = (WithSomeOneAutoCompleteTextView) findViewById(R.id.editTextTest);
contactPickerAdapter = new ContactPickerAdapter(this,
android.R.layout.simple_dropdown_item_1line,
ContactQuery.getContacts(this, false));
mEditText.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line, item));
mTextWatcher = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
String t = s.toString().replace("call ",");
contactPickerAdapter.getFilter().filter(t);
if (s.toString().equalsIgnoreCase("call ")) {
Toast.makeText(MainActivity.this, "CALL",
Toast.LENGTH_SHORT).show();
mEditText.setAdapter(contactPickerAdapter);
}
if (s.toString().equalsIgnoreCase("Call back")) {
// t.replace("call back ", "");
// System.out.println("t is: " + t);
// contactPickerAdapter.getFilter().filter(t);
Toast.makeText(MainActivity.this, "Launch",
Toast.LENGTH_SHORT).show();
}
}
};
}
This is ContactPickerAdapter
public class ContactPickerAdapter extends ArrayAdapter<Contact> implements
Filterable {
private ArrayList<Contact> contactList, cloneContactList;
private LayoutInflater layoutInflater;
private Context mContext;
public ContactPickerAdapter(Context context, int textViewResourceId,
ArrayList<Contact> contactList) {
super(context, textViewResourceId);
this.contactList = contactList;
this.cloneContactList = (ArrayList<Contact>) this.contactList.clone();
layoutInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return contactList.size();
}
#Override
public Contact getItem(int position) {
return contactList.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(
R.layout.withsomeone_contact_list_item, null);
holder = new Holder();
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.phone = (TextView) convertView.findViewById(R.id.phone);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
Contact contact = getItem(position);
holder.name.setText(contact.contactName);
holder.phone.setText(contact.num);
return convertView;
}
#Override
public Filter getFilter() {
Filter contactFilter = new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
if (results.values != null) {
contactList = (ArrayList<Contact>) results.values;
notifyDataSetChanged();
}
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
// CharSequence t = "";
System.out.println("contraints is equal: " + constraint);
// if (constraint.toString().contains("call ")) {
// // constraint = "";
// System.out.println("contraints now: "
// + constraint.toString().replace("call ", ""));
// t = constraint.toString().replace("call ", "");
// }
// } else if
// (constraint.toString().equalsIgnoreCase("call back ")) {
// // constraint = "";
// System.out.println("contraints now: " + constraint);
// t = constraint.toString().replace("call back ", "");
//
// }
// System.out.println("clone is equal: " + t);
String sortValue = constraint == null ? "" : constraint
.toString().toLowerCase();
FilterResults filterResults = new FilterResults();
if (!TextUtils.isEmpty(sortValue.trim())) {
ArrayList<Contact> sortedContactList = new ArrayList<Contact>();
for (Contact contact : cloneContactList) {
if (contact.contactName.toLowerCase().contains(
sortValue)
|| contact.num.toLowerCase()
.contains(sortValue))
sortedContactList.add(contact);
}
filterResults.values = sortedContactList;
filterResults.count = sortedContactList.size();
}
return filterResults;
}
#Override
public CharSequence convertResultToString(Object resultValue) {
// need to save this to saved contact
return ((Contact) resultValue).contactName;
}
};
return contactFilter;
}
#SuppressWarnings("unchecked")
public void setContactList(ArrayList<Contact> contactList) {
// this isn't the efficient method
// need to improvise on this
this.contactList = contactList;
this.cloneContactList = (ArrayList<Contact>) this.contactList.clone();
notifyDataSetChanged();
}
public static class Holder {
public TextView phone, name;
}
Still a bit unclear what are you trying to achieve.
Anyway.
Well as a first step I would attach the TextWatcher to the mEditText
mEditText.addTextChangedListener(mTextWatcher);
Then I would remove
contactPickerAdapter.getFilter().filter(t);
see how it goes.
I suggest that you post the code of your contactPickerAdapter as well.

Categories

Resources