【问题标题】:Filter a ListView with custom adapter and custom row in a fragment使用片段中的自定义适配器和自定义行过滤 ListView
【发布时间】:2017-08-17 22:29:33
【问题描述】:

我在片段中有一个带有自定义适配器的 ListView。一切正常,但现在我正在尝试实现一种在输入 EditText 时过滤列表的方法(我尝试过 SearchView 但它也不起作用)。每行有两个 EditText 和一个 ImageView。

OnCreateView:

lst=(ListView)rootView.findViewById(R.id.lst);
lst.setTextFilterEnabled(true);
mainAd = new mArrayAdapter(getActivity(),R.layout.row,downList); //it's more complicated than this but normally the ListView is populated correctly
lst.setAdapter(mainAd);
lst.setTextFilterEnabled(true);
edit = (EditText) rootView.findViewById(R.id.txtexample);
edit.addTextChangedListener(new TextWatcher() {
    @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            mainAd.getFilter().filter(charSequence.toString());
        }

        @Override
        public void afterTextChanged(Editable editable) {

        }
});
return rootView;

mArrayAdapter:

private class mArrayAdapter extends ArrayAdapter<Exhibition> implements Filterable{

    Context context;
    int layoutResourceId;
    ArrayList<Exhibition> list;
    ValueFilter valueFilter;
    ArrayList<Exhibition> filterList;

    mArrayAdapter(Context context, int layoutResourceId, ArrayList<Exhibition>  data){
        super(context, layoutResourceId, data);
        this.context=context;
        this.layoutResourceId=layoutResourceId;
        this.list=data;
        this.filterList =data;
    }

    @Override
    @NonNull
    public View getView(int position, View convertView, @NonNull ViewGroup parent) {
        View row;
        Exhibition ex;
        if(convertView==null){
            row= getActivity().getLayoutInflater().inflate(R.layout.row,parent,false);
        }
        else row = convertView;
        TextView ttl = (TextView)row.findViewById(R.id.title);
        TextView descr = (TextView)row.findViewById(R.id.descr);
        ImageView header = (ImageView)row.findViewById(R.id.hd);

        ex = downList.get(position);

        ttl.setText(ex.name);
        descr.setText(ex.description);

        byte[] decoded = Base64.decode(ex.image,Base64.DEFAULT);
        Bitmap decodedBitmap = BitmapFactory.decodeByteArray(decoded,0,decoded.length);
        header.setImageBitmap(decodedBitmap);
        return row;

    }

    @Override
    public Filter getFilter() {
        if (valueFilter == null) {
            valueFilter = new ValueFilter();
        }
        return valueFilter;
    }

    private class ValueFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            String filtString = constraint.toString().toLowerCase();
            FilterResults results = new FilterResults();
            if(constraint == null || constraint.length() == 0){
                results.values = filterList;
                results.count = filterList.size();
            }
            else {

                List<Exhibition> nExhList = new ArrayList<>();

                for(Exhibition e : list){
                    if (e.getName().toLowerCase().startsWith(constraint.toString().toLowerCase())){
                        nExhList.add(e);
                    }
                }

                results.values= nExhList;
                results.count=nExhList.size();

            }
            return results;

        }

        @Override
        protected void publishResults(CharSequence constraint,
                                      FilterResults results) {
            if(results.count==0){
                notifyDataSetInvalidated();
            }
            else{
                list = (ArrayList<Exhibition>)results.values;
                notifyDataSetChanged();
            }
        }

    }

}

我不知道为什么它不起作用。提前致谢。

【问题讨论】:

    标签: java android listview android-fragments android-filterable


    【解决方案1】:

    我解决了我的问题。

    我添加了我为使其正常工作所做的更改,但是,如果您有同样的问题,请注意THIS 链接有一个示例,我使用 EditText 和 SearchView 正确过滤 ListView。

    首先,在edit.addTextChangedListener:

    edit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    
            }
    
            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                if (i2 < i1) {
                    mainAd.resetData();  //if I delete characters I would like to show the original list
                }
                mainAd.getFilter().filter(charSequence.toString());
            }
    
            @Override
            public void afterTextChanged(Editable editable) {
    
            }
        });
    

    其次,我在mArrayAdapter 中检查了正确的变量(例如,我在getView() 中调用了原始的ArrayList)并添加了三个所需的方法:

    @Override
    public int getCount(){
        return list.size();
    }
    
    @Override
    public Exhibition getItem (int pos){
        return list.get(pos);
    }
    
    void resetData() {
        list = originalList;
    }
    

    (我把filterList的名字改成了originalList

    ValueFilter 如下:

    private class ValueFilter extends Filter {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();
                if(constraint == null || constraint.length() == 0){
                    results.values = originalList;
                    results.count = originalList.size();
                }
                else {
    
                    List<Exhibition> nExhList = new ArrayList<>();
    
                    for(Exhibition e : list){
                        if (e.getName().toUpperCase().startsWith(constraint.toString().toUpperCase())){
                            nExhList.add(e);
                        }
                    }
    
                    results.values= nExhList;
                    results.count=nExhList.size();
                }
                return results;
            }
    
            @Override
            protected void publishResults(CharSequence constraint,
                                          FilterResults results) {
                if(results.count==0){
                    notifyDataSetInvalidated();
                }
                else{
                    list = (ArrayList<Exhibition>)results.values;
                    notifyDataSetChanged();
                }
            }
    
        } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-14
      • 2018-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多