Searching doesn't work in ArrayAdapter and Lis

2019-09-17 08:32发布

问题:

Unfortunately I couldn't implement a search functionality in a ListView inside an ArrayAdapter. Here is a part of my MainActivity:

    public class MainPageActivity extends ActionBarActivity implements View.OnClickListener {

        private static String TAG = "MainPageActivity";
        private ListView lv_medicines;
        private MedicineAdapter medicineAdapter;
        private JSONParser jsonParser;
        private List<Medicine> medicines;
        private EditText inputSearch;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main_page);

            init();

            inputSearch.addTextChangedListener(new TextWatcher() {

                @Override
                public void afterTextChanged(Editable arg0) {
                }

                @Override
                public void beforeTextChanged(CharSequence arg0, int arg1,
                                              int arg2, int arg3) {
                }

                @Override
                public void onTextChanged(CharSequence cs, int arg1, int arg2,
                                          int arg3) {
                    MainPageActivity.this.medicineAdapter.getFilter().filter(cs);
                }
            });

           /*...*/
        private void init() {
            lv_medicines = (ListView) findViewById(R.id.lv_medicines);
            lv_medicines.setTextFilterEnabled(true);
            inputSearch = (EditText) findViewById(R.id.inputSearch);


            medicineAdapter = new MedicineAdapter(getApplicationContext(), hatoanyagok);
            lv_medicines.setAdapter(medicineAdapter);
        }

        /*...*/

    }

And here is my ArrayAdapter:

public class MedicineAdapter extends ArrayAdapter<String> implements Filterable{

    private final Context context;
    private List<String> elements;
    private List<String> filteredData;

    public MedicineAdapter(Context context, List<String> elements) {
        super(context, R.layout.row_item, elements);
        this.context = context;
        this.elements = elements;
        this.filteredData = elements;
    }

    public String getItem(int pos) {
        return filteredData.get(pos);
    }

    public int getCount() {
        return filteredData.size();
    }

    public long getItemId(int position) {
        return position;
    }

    public void deleteRow(String element) {
        if (filteredData.contains(element)) {
            filteredData.remove(element);
        }
    }

    public List<String> getObjects() {
        return filteredData;
    }

    public void setObjects(List<String> objects) {
        this.elements = elements;
    }

    public List<String> getValues() {
        return filteredData;
    }

    private static class ViewHolder {
        TextView tv_medicine_name;
    }

    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder viewHolder;

        if (convertView == null) {
            viewHolder = new ViewHolder();
            LayoutInflater inflater = LayoutInflater.from(getContext());
            convertView = inflater.inflate(R.layout.row_item, parent, false);
            viewHolder.tv_medicine_name = (TextView) convertView.findViewById(R.id.tv_medicine_name);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.tv_medicine_name.setText(filteredData.get(position));


        return convertView;
    }

    public void filter(String charText) {
        charText = charText.toLowerCase(Locale.getDefault());
        filteredData.clear();
        if (charText.length() == 0) {
            filteredData.addAll(elements);
        }
        else
        {
            for (String s : elements)
            {
                if (s.toLowerCase(Locale.getDefault()).contains(charText))
                {
                    filteredData.add(s);
                }
            }
        }
        notifyDataSetChanged();
    }

    public void notifyDataSetChanged() {
        super.notifyDataSetChanged();
    }
}

What would be the problem? Thanks in advance for the answers!

回答1:

You need to make one more class which extends Filter

public class filter_here extends Filter{

private List<String> Original_Names;
private MedicineAdapter medicineAdapter;

public filter_here(List<String> Original_Names, MedicineAdapter ma){
    this.Original_Names = Original_Names;
    medicineAdapter = ma;
}

@Override
protected FilterResults performFiltering(CharSequence constraint) {
    // TODO Auto-generated method stub

    FilterResults Result = new FilterResults();
    // if constraint is empty return the original names
    if(constraint.length() == 0 ){
        Result.values = Original_Names;
        Result.count = Original_Names.size();
        return Result;
    }

    ArrayList<String> Filtered_Names = new ArrayList<String>();
    String filterString = constraint.toString().toLowerCase();
    String filterableString;

    for(int i = 0; i<Original_Names.size(); i++){
        filterableString = Original_Names.get(i);
        if(filterableString.toLowerCase().contains(filterString)){
            Filtered_Names.add(filterableString);
        }
    }
    Result.values = Filtered_Names;
    Result.count = Filtered_Names.size();

    return Result;
}

@Override
protected void publishResults(CharSequence constraint,FilterResults results) {
    // TODO Auto-generated method stub
    medicineAdapter.setObjects((ArrayList<String>) results.values);
    medicineAdapter.notifyDataSetChanged();
}

}

In your adapter make object of filter_here class and add this line to your adapter's constructor

filterObj = new filter_here(elements, this);

Also change this method of your adapter class

public void setObjects(List<String> objects) {
    this.filteredData = objects;
}

Add this method to your adapter

@Override
public Filter getFilter() {
    // TODO Auto-generated method stub
    return filterObj;
}

You dont need filter method in your adapter. Keep everything else as it is.