简体   繁体   English

使用自定义适配器和片段中的自定义行过滤ListView

[英]Filter a ListView with custom adapter and custom row in a fragment

I have a ListView with a custom adapter in a fragment. 我在片段中有一个带有自定义适配器的ListView。 Everything works fine but now I'm trying to implement a way for filtering the list when typing in an EditText (I've tried a SearchView but it did not work either). 一切正常,但现在我试图实现一种在输入EditText时过滤列表的方法(我尝试过使用SearchView,但它也不起作用)。 Each row has two EditTexts and a ImageView. 每行有两个EditTexts和一个ImageView。

In OnCreateView : 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;

The mArrayAdapter : 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();
            }
        }

    }

}

I don't know why it's not working. 我不知道为什么它不起作用。 Thanks in advance. 提前致谢。

I solved my problem. 我解决了我的问题。

I add the changes I did for make it works but, if you have the same problem, note that at THIS link there is an example I made to filter correctly a ListView with an EditText and a SearchView. 我添加了为使它起作用而进行的更改,但是,如果您有同样的问题,请注意,在链接处,有一个示例可以正确过滤具有EditText和SearchView的ListView。

For first, in edit.addTextChangedListener : 首先,在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) {

        }
    });

For second, in the mArrayAdapter I checked the right variables (for example, I was calling the original ArrayList in getView() ) and I add three methods that are needed: 第二,在mArrayAdapter我检查了正确的变量(例如,我在getView()调用了原始的ArrayList),然后添加了所需的三个方法:

@Override
public int getCount(){
    return list.size();
}

@Override
public Exhibition getItem (int pos){
    return list.get(pos);
}

void resetData() {
    list = originalList;
}

(I changed the name of filterList in originalList ) (我在originalList更改了filterList的名称)

The ValueFilter is the following: 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();
            }
        }

    } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM