为了账号安全,请及时绑定邮箱和手机立即绑定

使用自定义(对象)适配器过滤ListView

使用自定义(对象)适配器过滤ListView

陪伴而非守候 2019-10-09 15:05:43
我正在尝试对使用自定义对象适配器的ListView进行过滤,但是找不到任何有用的示例。包含的代码非常简化,因此请记住,我不能使用常规的ArrayAdapter。我在ListView上方有一个EditText,当用户在EditText小部件中输入文本时,我想用EditText中编写的文本过滤ListView。我们欢迎所有的建议!这是活动类的代码段:public class management_objects extends Activity {private static List<User> UserList;private EfficientAdapter adapter = null;private ListView objectListView = null;private EditText SearchText = null;private static class EfficientAdapter extends BaseAdapter implements Filterable{    private LayoutInflater mInflater;       public EfficientAdapter(Context context) {        mInflater = LayoutInflater.from(context);    }    public int getCount() {        return UserList.size();    }    public Object getItem(int position) {        return position;    }    public long getItemId(int position) {        return position;    }    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder holder;         if (convertView == null) {             convertView = mInflater.inflate(R.layout.imagelayout_2lines, null);            holder = new ViewHolder();            holder.text = (TextView) convertView.findViewById(R.id.managementObjectText);            holder.subtext = (TextView) convertView.findViewById(R.id.managementObjectSubText);            holder.icon = (ImageView) convertView.findViewById(R.id.managementObjectIcon);            convertView.setTag(holder);        }        else {            holder = (ViewHolder) convertView.getTag();        }        holder.text.setText(UserList.get(position).getFirstName());        holder.subtext.setText(UserList.get(position).getLastName());        holder.icon.setImageResource(R.drawable.user);        return convertView;    }    static class ViewHolder {         TextView text;        TextView subtext;        ImageView icon;    }    @Override    public Filter getFilter() {        return null;    }}}
查看完整描述

3 回答

?
慕妹3242003

TA贡献1824条经验 获得超6个赞

您需要做一些事情:


1)在您的活动中,在EditText上注册一个包含用户输入值的文本更改侦听器:


mSearchValue.addTextChangedListener(searchTextWatcher);


2)创建您的searchTextWatcher并执行以下操作:


private TextWatcher searchTextWatcher = new TextWatcher() {

    @Override

        public void onTextChanged(CharSequence s, int start, int before, int count) {

            // ignore

        }


        @Override

        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            // ignore

        }


        @Override

        public void afterTextChanged(Editable s) {

            Log.d(Constants.TAG, "*** Search value changed: " + s.toString());

            adapter.getFilter().filter(s.toString());

        }

    };

3)在您的自定义适配器中覆盖getFilter(),并使其过滤结果并通知listview数据集已更改。


    @Override

    public Filter getFilter() {

        return new Filter() {

            @SuppressWarnings("unchecked")

            @Override

            protected void publishResults(CharSequence constraint, FilterResults results) {

                Log.d(Constants.TAG, "**** PUBLISHING RESULTS for: " + constraint);

                myData = (List<MyDataType>) results.values;

                MyCustomAdapter.this.notifyDataSetChanged();

            }


            @Override

            protected FilterResults performFiltering(CharSequence constraint) {

                Log.d(Constants.TAG, "**** PERFORM FILTERING for: " + constraint);

                List<MyDataType> filteredResults = getFilteredResults(constraint);


                FilterResults results = new FilterResults();

                results.values = filteredResults;


                return results;

            }

        };

    }


查看完整回答
反对 回复 2019-10-09
?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

这是一个有趣的例子


public Filter getFilter() {

    return new Filter() {


        @Override

        protected FilterResults performFiltering(CharSequence constraint) {

            final FilterResults oReturn = new FilterResults();

            final ArrayList<station> results = new ArrayList<station>();

            if (orig == null)

                orig = items;

            if (constraint != null) {

                if (orig != null && orig.size() > 0) {

                    for (final station g : orig) {

                        if (g.getName().toLowerCase()

                                .contains(constraint.toString()))

                            results.add(g);

                    }

                }

                oReturn.values = results;

            }

            return oReturn;

        }


        @SuppressWarnings("unchecked")

        @Override

        protected void publishResults(CharSequence constraint,

                FilterResults results) {

            items = (ArrayList<station>) results.values;

            notifyDataSetChanged();

        }

    };

}


public void notifyDataSetChanged() {

    super.notifyDataSetChanged();

    notifyChanged = true;

}


查看完整回答
反对 回复 2019-10-09
?
手掌心

TA贡献1942条经验 获得超3个赞

对于不需要Filterable界面的用户,有一个简单得多的解决方案。这也可以notifyDataSetChanged()正确处理其他解决方案失败的地方。请注意,您需要向中添加一个getArray()函数,该函数BaseAdapter仅返回传递给构造函数的数组对象。


public abstract class BaseFilterAdapter<T> extends BaseAdapter<T> {


    private List<T> original;

    private String lastFilter;


    public BaseFilterAdapter(Context context, List<T> array) {

        super(context, new LinkedList<T>());

        original = array;

        filter("");

    }


    protected abstract Boolean predicate(T element, String filter);


    public void filter(String filter) {

        lastFilter = filter;

        super.getArray().clear();

        for (T element : original)

            if (predicate(element, filter))

                super.getArray().add(element);

        super.notifyDataSetChanged();

    }


    @Override

    public List<T> getArray() {

        return original;

    }


    @Override

    public void notifyDataSetChanged() {

        filter(lastFilter);

    }

}


查看完整回答
反对 回复 2019-10-09
  • 3 回答
  • 0 关注
  • 391 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信