AutoSearchTextView not show data first time - java

I am implementing autosearchTextView and I am getting data from web service.The API get hit when char value is 3. I refer this link https://github.com/kyasar/markod/blob/master/app/src/main/java/com/dopamin/markod/adapter/ProductSearchAdapter.java. and this is also
http://makovkastar.github.io/blog/2014/04/12/android-autocompletetextview-with-suggestions-from-a-web-service/
When I enter 3 char the publishResults() method trigger and so getting no drop down. I debugged and I found web service get called and but before it This publishResults() method triggered. I have to spend a lot of time to do in R&D. Please Help me out.
mMutualFundAdapter = new PrimaryContractAdapter(CreateNoteActivityNew.this); primary_atv.setThreshold(3);//will start working from 3 character
//setting the adapter data into the AutoCompleteTextView
primary_atv.setAdapter(mMutualFundAdapter);
primary_atv.setLoadingIndicator(
(android.widget.ProgressBar) findViewById(R.id.pb_loading_indicator));
primary_atv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
PrimaryContract primaryContract = (PrimaryContract) adapterView.getItemAtPosition(position);
primary_atv.setText(primaryContract.getContract());
}
});
Adapter -
public PrimarySearchAdapter(Context context, ArrayList<PrimaryContract> resultList) {
mContext = context;
this.resultList = resultList;
}
#Override
public int getCount() {
return resultList.size();
}
#Override
public PrimaryContract getItem(int index) {
return resultList.get(index);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.drop_down_layout, parent, false);
}
((TextView) convertView.findViewById(R.id.heading)).setText(getItem(position).getText());
return convertView;
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint != null) {
findData(mContext, constraint.toString());
if (contractArrayList != null && contractArrayList.size()>0) {
// Assign the data to the FilterResults
filterResults.values = contractArrayList;
filterResults.count = contractArrayList.size();
}
}
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
resultList = ( ArrayList<PrimaryContract>) results.values;
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}};
return filter;
}
private void findData(Context context, String bookTitle) {
// this finddata() for getting response from REST API using retrofit
contractArrayList = new ArrayList<>();
String url = "http://se.com/publisher_api/primaryContracts?keyword=";
url = url + bookTitle;
ApiRequestResponse apiRequestResponse = new ApiRequestResponse();
final OnResponseReceiveEvent onResponseReceiveEvent = new OnResponseReceiveEvent() {
#Override
public void getSuccess(Object obj) {
if (obj != null) {
createNoteModel = (CreateNoteModel) obj;
if (createNoteModel.getPrimaryContracts() != null && createNoteModel.getPrimaryContracts().size()>0){
if (contractArrayList != null) {
contractArrayList.clear();
contractArrayList = createNoteModel.getPrimaryContracts();
}
}
}
notifyDataSetChanged();
}
// I have followed as I given two links
#Override
public Object getFailure() {
return null;
}
};
apiRequestResponse.getDropDownData(onResponseReceiveEvent, url);
}
}

Related

After filtering the list, if want to check original list returns wrong list size

I have a list of merchants, I am applying filter to it to search by address or a name, filter works fine. it gives proper list of filtered results. But if I again empty the edit text I should see the original list, but I see different count than the original.
Example, in list I have 7 merchants, I do filter it and it shows two filtered merchants in the list, and now if I empty the edit text I see only 5 merchants , unable to see the original list of 7 merchants.
Adapter:
public class SearchedMerchantsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
static final int LOAD_MERCHANTS = 0;
private Context context;
public ArrayList<Merchants> list;
public ArrayList<Merchants> baselist = new ArrayList<>();
public SearchedMerchantsAdapter(Context context, ArrayList<Merchants> list) {
this.context = context;
this.list = list;
this.baselist = list;
}
#Override
public int getItemViewType(int position) {
Object obj = list.get(position);
if (obj instanceof Merchants) return LOAD_MERCHANTS;
return super.getItemViewType(position);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int viewType = holder.getItemViewType();
switch (viewType) {
case LOAD_MERCHANTS:
LoadSearchedMerchants loadSearchedMerchants = (LoadSearchedMerchants) holder;
retriveAllMerchants(loadSearchedMerchants, position);
break;
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
switch (viewType) {
case LOAD_MERCHANTS:
View v_image_msg = inflater.inflate(R.layout.search_merchant_layout, parent, false);
viewHolder = new LoadSearchedMerchants(v_image_msg);
break;
}
return viewHolder;
}
#Override
public int getItemCount() {
return list.size();
}
public void retriveAllMerchants(final LoadSearchedMerchants holder, int position) {
final Merchants data = (Merchants) list.get(position);
holder.tv_kiarana_name.setText(data.getKirana_name());
holder.tv_address.setText(data.getMerchant_address());
holder.lay_row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(context, MerchantProfileActivity.class);
i.putExtra("cont_name",data.getMerchant_name());
i.putExtra("kirana_name",data.getKirana_name());
i.putExtra("email_id",data.getEmail_id());
i.putExtra("phone_no",data.getPhone());
i.putExtra("address",data.getMerchant_address());
context.startActivity(i);
}
});
holder.btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final SessionData sessionData;
final String sessionUserId,access_token;
sessionData=new SessionData(context);
sessionUserId = sessionData.getString("user_id","-1");
access_token = sessionData.getString("api_key", "-1");
new SendRequestAsyncTask(context).execute(sessionUserId,access_token,data.getMerchant_id().toString());
}
});
}
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final ArrayList<Merchants> results = new ArrayList<>();
if (constraint != null) {
if (baselist != null && baselist.size() > 0) {
for (final Merchants g : baselist) {
if (g.getKirana_name()
.contains(constraint.toString()) || g.getMerchant_address().contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
list = (ArrayList<Merchants>) results.values;
notifyDataSetChanged();
}
};
}
}
What can be the reason for this? Thank you..
Create this method in adapter:
public Item getItemAtPosition(int position)
{
return list.get(position);
}
Now, when click action occurs just call this method:
adapter.getItemAtPosition(position).getMerchant_name()
Can you try this ?
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final ArrayList<Merchants> results = new ArrayList<>();
if (charSequence != null && charSequence.length() > 0) {
if (baselist != null && baselist.size() > 0) {
for (final Merchants g : baselist) {
if (g.getKirana_name()
.contains(constraint.toString()) || g.getMerchant_address().contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
oReturn.count = results.size();
}
else
{
oReturn.values = baselist;
oReturn.count = baselist.size();
}
return oReturn;
}
Update
Create one Method in Adapter.. Comment out getFilter() and interface Filterable
public void filterData(String compareString)
{
list.clear();
if (baselist != null && baselist.size() > 0) {
for (final Merchants g : baselist) {
if (g.getKirana_name()
.contains(compareString) || g.getMerchant_address().contains(compareString))
list.add(g);
}
}
notifyDataSetChanged();
}
And Last call this Method From your edittext change listener
like adapter.filterData("StringwhichisChangedFromEdittext")
Hope this help.
Return the entire list if user enters nothing
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final ArrayList<Merchants> results = new ArrayList<>();
if(TextUtils.isEmpty(constraint)){
oReturn.values = baselist==null?new ArrayList() : baselist ;
return oReturn.values ;
}
if (constraint != null) {
if (baselist != null && baselist.size() > 0) {
for (final Merchants g : baselist) {
if (g.getKirana_name()
.contains(constraint.toString()) || g.getMerchant_address().contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
list = (ArrayList<Merchants>) results.values;
notifyDataSetChanged();
}
};
}

Search View isnt searching my gridview

Everything in the code below works except the when you try and search for a value, the application just doesnt respond to when you type letters into the searchview which should be filtering the gridview.
Cheers, Kripzy
Main Activity:
String[] Champions = {"Aatrox", "Ahri", "Akali"};
int[] Champimgs = {R.drawable.aatrox_square_0, R.drawable.ahri_square_0, R.drawable.akali_square_0};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gv = (GridView) findViewById(R.id.gridView);
sv = (SearchView) findViewById(R.id.searchView);
final Adapter adapter=new Adapter(this,this.getChampions());
gv.setAdapter(adapter);
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String arg0) {
return false;
}
#Override
public boolean onQueryTextChange(String query) {
adapter.getFilter().filter(query);
return false;
}
});
}
private ArrayList<Champions> getChampions()
{
ArrayList<Champions> champions = new ArrayList<Champions>();
Champions p;
for (int i = 0; i < Champions.length; i++)
{
p = new Champions(Champions[i], Champimgs[i]);
champions.add(p);
}
return champions;
}
}
Champions
public Champions(String Champion, int Champimg) {
this.Champimg=Champimg;
this.Champion=Champion;}
public String getChampion() {
return Champion;
}
public int getChampimg() {
return Champimg;
}
public void setChampion(String champion) {
Champion = champion;
}
public void setChampimg(int champimg) {
Champimg = champimg;
}
}
Adapter
public Adapter(Context ctx, ArrayList<Champions> Champion){
this.c=ctx;
this.Champion=Champion;
this.filterlist=Champion;
}
#Override
public int getCount() {
return Champion.size();
}
#Override
public Object getItem(int position) {
return Champion.get(position);
}
#Override
public long getItemId(int position) {
return Champion.indexOf(getItem(position));
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.model, null);
}
TextView nameTxt = (TextView) convertView.findViewById(R.id.textView);
ImageView img = (ImageView) convertView.findViewById(R.id.imageView);
nameTxt.setText(Champion.get(position).getChampion());
img.setImageResource(Champion.get(position).getChampimg());
return convertView;
}
#Override
public Filter getFilter() {
if (filter == null)
{
filter=new CustomFiler();
}
return filter;
}
class CustomFiler extends Filter
{
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results=new FilterResults();
if (constraint != null && constraint.length() > 0)
{
constraint=constraint.toString().toUpperCase();
ArrayList<Champions> filters = new ArrayList<Champions>();
for(int i = 0;i<filterlist.size();i++){
if (filterlist.get(i).getChampion().toUpperCase().contains(constraint));
{
Champions p= new Champions (filterlist.get(i).getChampion(),filterlist.get(i).getChampimg());
filters.add(p);
}
}
results.count=filters.size();
results.values=filters;
}else{
results.count=filterlist.size();
results.values=filterlist;
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
Champion = (ArrayList<Champions>) results.values;
notifyDataSetChanged();
}
}
}
you have a little bug in this line:
if (filterlist.get(i).getChampion().toUpperCase().contains(constraint));
the bug is ; symbol in the end of if statement. It makes code below if run each time, therefore filter doesn't work. Just remove ; symbol after if statement

Refresh data in custom adapter created for AutoCompleteTextView

I created custom adapter by extending BaseAdapter and implementing Filterable interface. This adapter is used for suggest phone number to user when they type a contact number or contact person name.ArrayList<String> data contain those data with the pattern of "person name:number" which are extracted from phone.
It's working find except for one issue. If I search for contacts start with letter "A" it's show the data correctly. If I delete that and type "B" again it shows both contacts start with "A" and "B". I know that I have to clear ArrayList<String> matchedResults(Check the code) in some method before add new data but when I did that It gave me an empty ArrayList. In which method at which point I should do that or is there a different solution for this ?
here's the code
public class AutoCompleteAdapter extends BaseAdapter implements Filterable {
private Context context;
private ArrayList<String> data;
private ArrayList<String> matchedResults = new ArrayList<String>();
public AutoCompleteAdapter(Context context, ArrayList<String> namesAndNumbers) {
this.context = context;
this.data = namesAndNumbers;
}
#Override
public int getCount() {
return matchedResults.size();
}
#Override
public String getItem(int position) {
return matchedResults.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.custom_layout, parent, false);
TextView nameTextView = (TextView) view.findViewById(R.id.name);
TextView numberTextView = (TextView) view.findViewById(R.id.number);
String[] split = matchedResults.get(position).split(":");
nameTextView.setText(split[0]);
numberTextView.setText(split[1]);
return view;
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if(constraint != null || constraint.length() != 0) {
for (String loop:data) {
int charSequenceSize = constraint.length();
if(onlyText(constraint.toString()) && !matchedResults.contains(loop)){
String[] split = loop.split(":");
String substring = split[0].substring(0, charSequenceSize);
if (substring.equalsIgnoreCase(constraint.toString())){
matchedResults.add(loop);
}
}else if(onlyNumbers(constraint.toString())){
String[] split = loop.split(":");
String substring = split[1].substring(0, charSequenceSize);
if (substring.equals(constraint.toString()) && !matchedResults.contains(loop) ){
matchedResults.add(loop);
}
}
}
}
results.values = matchedResults;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
results.values = matchedResults;
notifyDataSetChanged();
}
};
}
public boolean onlyText(String text) {
boolean result = false;
if (Pattern.matches("[a-zA-Z ]+", text) && text.length() >= 1) {
result = true;
}
return result;
}
public boolean onlyNumbers(String text) {
boolean result = false;
if (Pattern.matches("[0-9+]+", text) && text.length() >= 1) {
result = true;
}
return result;
}
}
update your filter to this
#Override
public Filter getFilter() {
return nameFilter;
}
Filter nameFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint != null) {
matchedResults.clear();
for (String item : data) {
if (item.toLowerCase().startsWith(constraint.toString().toLowerCase())) {
matchedResults.add(item);
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = matchedResults;
filterResults.count = matchedResults.size();
return filterResults;
} else {
return new FilterResults();
}
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
ArrayList<String> filteredList = (ArrayList<String>) results.values;
if (results != null && results.count > 0) {
data.clear();
for (String c : filteredList) {
data.add(c);
}
notifyDataSetChanged();
}
}
};
So your entire code it be like this :
public class AutoCompleteAdapter extends BaseAdapter implements Filterable {
private Context context;
private ArrayList<String> data;
private ArrayList<String> matchedResults = new ArrayList<String>();
public AutoCompleteAdapter(Context context, ArrayList<String> namesAndNumbers) {
this.context = context;
this.data = namesAndNumbers;
}
#Override
public int getCount() {
return matchedResults.size();
}
#Override
public String getItem(int position) {
return matchedResults.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.custom_layout, parent, false);
TextView nameTextView = (TextView) view.findViewById(R.id.name);
TextView numberTextView = (TextView) view.findViewById(R.id.number);
String[] split = matchedResults.get(position).split(":");
nameTextView.setText(split[0]);
numberTextView.setText(split[1]);
return view;
}
#Override
public Filter getFilter() {
return nameFilter;
}
Filter nameFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint != null) {
matchedResults.clear();
for (String item : data) {
if (item.toLowerCase().startsWith(constraint.toString().toLowerCase())) {
matchedResults.add(item);
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = matchedResults;
filterResults.count = matchedResults.size();
return filterResults;
} else {
return new FilterResults();
}
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
ArrayList<String> filteredList = (ArrayList<String>) results.values;
if (results != null && results.count > 0) {
data.clear();
for (String c : filteredList) {
data.add(c);
}
notifyDataSetChanged();
}
}
};
public boolean onlyText(String text) {
boolean result = false;
if (Pattern.matches("[a-zA-Z ]+", text) && text.length() >= 1) {
result = true;
}
return result;
}
public boolean onlyNumbers(String text) {
boolean result = false;
if (Pattern.matches("[0-9+]+", text) && text.length() >= 1) {
result = true;
}
return result;
}
}
I hope to be helpful for you .

Getting wrong position after filter listview

My question is when i filter listview with baseadapter than i got perfect result but after click on this item,i can't get related values of that item but i get wrong position item so notifydatasetchenged not work.
'public ConsultationAdpater(Context context, ArrayList<Doctor> doctors) {
this.context = context;
this.doctorList = doctors;
this.mStringFilterList = doctors;
getFilter();
imageLoader = ImageLoader.getInstance();
this.inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// set options for image display
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.activity_indicator)
.showImageForEmptyUri(R.drawable.image_not_available)
.showImageOnFail(R.drawable.image_not_available)
.resetViewBeforeLoading(true).cacheInMemory(true)
.cacheOnDisk(true).considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565).build();
}
#Override
public int getCount() {
return doctorList.size();
}
#Override
public Object getItem(int position) {
return doctorList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.row_consult, parent, false);
holder = new ViewHolder();
holder.image = (ImageView) convertView
.findViewById(R.id.img_row_const);
holder.txtName = (TextView) convertView
.findViewById(R.id.tDtNm_row_const);
holder.txtSpeciality = (TextView) convertView
.findViewById(R.id.tDtPt_row_const);
holder.txtPrice = (TextView) convertView
.findViewById(R.id.tDtPr_row_const);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Doctor doctor = doctorList.get(position);
holder.txtName.setText(doctor.base_user.first_name);
holder.txtSpeciality.setText(doctor.specialization);
holder.txtPrice.setText(doctor.cost_per_minute + "$/min");
if (images[position] == null) {
holder.image.setImageResource(R.drawable.image_not_available);
} else {
imageLoader.displayImage(
"http://37.252.121.94/" + images[position], holder.image,
options);
}
return convertView;
}
public void switchDoctorList(ArrayList<Doctor> doctors, String[] images) {
this.doctorList = doctors;
this.mStringFilterList = doctors;
this.images = images;
this.notifyDataSetChanged();
}
public void switchDoctorList(ArrayList<Doctor> doctors) {
this.doctorList = doctors;
this.mStringFilterList = doctors;
this.notifyDataSetChanged();
}
private static class ViewHolder {
ImageView image;
TextView txtName;
TextView txtSpeciality;
TextView txtPrice;
}
#Override
public Filter getFilter() {
if (valueFilter == null) {
valueFilter = new ValueFilter();
}
return valueFilter;
}
private class ValueFilter extends Filter {
// Invoked in a worker thread to filter the data according to the
// constraint.
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
ArrayList<Doctor> filterList = new ArrayList<Doctor>();
for (int i = 0; i < mStringFilterList.size(); i++) {
if ((mStringFilterList.get(i).specialization.toUpperCase())
.contains(constraint.toString().toUpperCase())) {
filterList.add(mStringFilterList.get(i));
}
}
results.count = filterList.size();
results.values = filterList;
} else {
results.count = mStringFilterList.size();
results.values = mStringFilterList;
}
return results;
}
// Invoked in the UI thread to publish the filtering results in the user
// interface.
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
doctorList = (ArrayList<Doctor>) results.values;
notifyDataSetChanged();
}
}
}'
This worked for me
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
//abrirActividadDetallada(position, id);
Object MyObject=(Object) parent.getAdapter().getItem(position);
CustomMethod(MyObject);
}
});
the ideology of filtering in adapters works by replacing the original data list int he adapter with the filtered list. The performFiltering method will tell you what elements in the data list match your filter. But not this list makes the primary data list for your adapter instead of the original data list. So you shoudl keep 2 lists in your adapter.
The original unfiltered list. for reference
The second list which feeds data to the adapter. getView and getItems etc. methods should use this list.
When you do performFiltering use the original unfiltered list to extract matching data elements and save in the second list. That way you will never go wrong.
Sample Example adapter for reference
public class CompanyQuotesResultAdapter extends BaseAdapter{
//original data populated from DB or web service.
private ArrayList<MyDataVO> originalData;
//the data list which the adapter uses for its work
private ArrayList<MyDataVO> data;
private LayoutInflater inflater = null;
private Fragment parentFragment;
private Filter dataFilter;
private int quoteGreenColor = -1;
public CompanyQuotesResultAdapter(Fragment parentFragment){
//set values here
}
public ArrayList<MyDataVO> getData() {
return new ArrayList<MyDataVO>(this.data);
}
public ArrayList<MyDataVO> getOriginalData() {
return new ArrayList<MyDataVO>(this.originalData);
}
public void addDataVOsWithoutNotification(List<MyDataVO> dataVOs){
this.data.addAll(dataVOs);
this.originalData.addAll(dataVOs);
}
public void setData(List<MyDataVO> data) {
this.data = new ArrayList<MyDataVO>(data);
this.originalData = new ArrayList<MyDataVO>(data);
this.notifyDataSetChanged();
}
public boolean isEmpty() {
return this.data.isEmpty();
}
public void clearAll(){
this.originalData.clear();
this.data.clear();
this.notifyDataSetChanged();
}
public void clearAllWithoutNotification(){
this.data.clear();
this.originalData.clear();
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public Filter getFilter(){
return dataFilter;
}
//Filtering class
private class ArrayFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence prefix) {
FilterResults results = new FilterResults();
if (prefix == null || prefix.length() == 0) {
ArrayList<MyDataVO> list = new ArrayList<MyDataVO>(originalData);
results.values = list;
results.count = list.size();
} else {
String prefixString = prefix.toString().toLowerCase(Locale.ENGLISH);
ArrayList<MyDataVO> values = new ArrayList<MyDataVO>(originalData);
final int count = values.size();
final ArrayList<MyDataVO> newValues = new ArrayList<MyDataVO>();
for (int i = 0; i < count; i++) {
final MyDataVO resultRowVO = values.get(i);
final String valueText = resultRowVO.getCompanyName().toLowerCase(Locale.ENGLISH);
// First match against the whole, non-splitted value
if (valueText.contains(prefixString)) {
newValues.add(resultRowVO);
}else{
final String codeValueText = resultRowVO.getCompanyCode().toLowerCase(Locale.ENGLISH);
if (codeValueText.contains(prefixString)) {
newValues.add(resultRowVO);
}
}
}
results.values = newValues;
results.count = newValues.size();
}
return results;
}
protected void publishResults(CharSequence constraint, FilterResults results) {
data = (ArrayList<MyDataVO>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}

ListView after filtration should be empty, when I add non-existing string

I have got an Activity with the list and EditText beneath it, Edit Text is for entering a string so that list will consists that string.
ListView based on BaseAdapter, contains elements of type F.
public class lstAdaptF extends BaseAdapter implements Filterable {
Context ctx;
LayoutInflater lInflater;
ArrayList<F> objectsF;
ArrayList<F> origobjectsF;
...
private Filter FirmaBBFilter;
lstAdaptF(Context context, ArrayList<F> f) {
ctx = context;
objectsF = f;
origobjectsF = f;
lInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
...
#Override
public Filter getFilter() {
if (FFilter == null)
FFilter = new FFilter();
return FFilter;
}
...
private class FFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
//get all inital list
results.values = origobjectsF;
results.count = origobjectsF.size();
Log.d("lstAdaptF","empty filter");
} else {
// We perform filtering operation
ArrayList<F> nF = new ArrayList<F>();
for (F p : origobjectsF) {
if (p.getName().toUpperCase().contains(constraint.toString().toUpperCase())){
nF.add(p);
}
}
results.values = nF;
results.count = nF.size();
}
return results;
}
Everithing works fine, for example list contains strings
Awork
Aworth
winter
I enter 'w': Awork, Aworth, winter
I enter 'wo': Awork, Aworth
I enter 'woo': Awork, Aworth - the list still the same, when it should be empty!
How could I manage this situation? Thank you.
UPD:
#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 {
objectsF = (ArrayList<F>) results.values;
notifyDataSetChanged();
}
}
UPD2:
#Override
public Object getItem(int position) {
return objectsF.get(position);
}
#Override
public int getCount() {
return objectsF.size();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
FHolder holder = new FHolder();
if (view == null) {
view = lInflater.inflate(R.layout.itemf, parent, false);
TextView tvAF = (TextView) view.findViewById(R.id.tvA);
...
holder.tvAF = tvAF;
...
view.setTag(holder);
}
else
holder = (FHolder) view.getTag();
F p = getF(position);
holder.tvAF.setText(p.a + "");
..
return view;
}
It looks like something wrong with notifyDataSetInvalidated(). Try to remove this if-else:
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// Now we have to inform the adapter about the new list filtered
objectsF = (ArrayList<F>) results.values;
notifyDataSetChanged();
}

Categories