【问题标题】:Android Filter ListView by BaseAdapter基于 BaseAdapter 的 Android 过滤器 ListView
【发布时间】:2014-12-03 13:11:50
【问题描述】:

我正在尝试通过以下代码编写简单的过滤 ListView。但这不能正常工作

在这段代码中,我使用ContactListStructure 类结构作为:

public class ContactListStructure implements Serializable {
    public Long     id;
    public String   name;
    public String   mobile;
    public Bitmap   photo;
    public Boolean  checked;
    ...
}

我将这个类填充为带有电话联系人的 ArrayList。填写后我将此列表设置为 ListView 没有任何问题,然后我尝试通过以下方式填充此列表:

/* private ArrayList<ContactListStructure>  contact_item; */

contactsAdapter = new ContactsAdapter ( G.contact_item , ActivityContactList.this);
lstContent.setAdapter ( contactsAdapter );

search_contacts.addTextChangedListener(new TextWatcher() {
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        contactsAdapter.getFilter().filter(s.toString());
    }

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

    @Override
    public void afterTextChanged(Editable s) {
    }
});

发布更新 search_contactsEditText 并且在输入该 ListView 后不要过滤并且不要进行任何更改。我的基础适配器:

public class ContactsAdapter extends BaseAdapter  implements Filterable {
    private Context mCtx=null;
    private ArrayList<ContactListStructure> mData=null;
    private ArrayList<ContactListStructure> arraylist;
    private List<ContactListStructure> worldpopulationlist = null;

    private ItemFilter mFilter = new ItemFilter();
    static int i=0;
    public ContactsAdapter (ArrayList<ContactListStructure> contact_item, Context ctx) {
        mData=contact_item;
        mCtx=ctx;
        this.worldpopulationlist = contact_item;
    }

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

    @Override
    public ContactListStructure getItem(int position) {
            return worldpopulationlist.get(position);
    }

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

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

        if(convertView==null) {
            LayoutInflater inflator=((Activity)mCtx).getLayoutInflater();
            convertView=inflator.inflate(R.layout.send_sms,null);

        }
        CheckBox  chk_name_mobile   = (CheckBox)convertView.findViewById(R.id.chk_name_mobile);
        ImageView photo             = (ImageView)convertView.findViewById(R.id.photo);

        String name=mData.get(position).name;
        chk_name_mobile.setText(name);
        if( mData.get(position).photo == null )
            photo.setImageDrawable( G.context.getResources().getDrawable(R.drawable.user) );
        else
            photo.setImageBitmap(mData.get(position).photo);
        return convertView;
    }

    @Override
    public Filter getFilter () {
        return mFilter;
    }

    private class ItemFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            String filterString = constraint.toString();
            FilterResults results = new FilterResults();

            final ArrayList<ContactListStructure> list = mData;

            int count = list.size();
            final ArrayList<ContactListStructure> nlist = new ArrayList<ContactListStructure>(count);

            String filterableString ;

            for (ContactListStructure wp : worldpopulationlist)
            {
                if (wp.getName().contains(filterString))
                {
                    //Log.e ("wp: ", String.valueOf ( wp ) );
                    ContactListStructure item = new ContactListStructure();
                    item.id = wp.id;
                    item.name = wp.name;
                    item.mobile = wp.mobile;
                    item.photo = wp.photo;
                    nlist.add(item);
                }
            }

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

            return results;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            arraylist = (ArrayList<ContactListStructure>) results.values;
            notifyDataSetChanged();
        }
    }
}

更新帖子:

在 cmets 获得帮助后,我的 notifyDataSetChanged 无法正常工作。输入编辑文本后,可以找到但列表视图不刷新。

【问题讨论】:

  • 我在这里看不到任何问号...
  • @pskink 帖子更新了这个 Q 标记 search_contacts 是一个 EditText 并且在输入该 ListView 之后不要过滤并且不要进行任何更改。
  • 在 performFiltering/publishResults 中添加一些 Log.d,你看到了什么?
  • @pskink 帖子已通过调试更新。 quastion 的结尾已更新
  • publishResults 中的 CharSequence 约束是什么? “一个”?

标签: android android-adapter


【解决方案1】:

您可以在此处尝试关注此问题:ListView is blank while using getFilter function

它能够根据 ListView 中的选择进行过滤。

【讨论】:

    【解决方案2】:

    我认为您忘记将结果返回的数据添加到您的mData

        protected void publishResults(CharSequence constraint, FilterResults results) {
            arraylist = (ArrayList<ContactListStructure>) results.values;
            mData.clear();
            for(int i = 0, i < arraylist.size(); i++)
               mData.add(arraylist.get(i));
            notifyDataSetChanged();
        }
    }
    

    【讨论】:

    • 我已将您粘贴的代码更新为正确的代码。谢谢。现在我有时会收到此错误:The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread.
    • @andbee 尝试调试您的代码并查看过滤时是否发生错误。有可能因为其他代码而发生错误。确保只在 UI 线程上调用 notifyDataSetChanged()
    猜你喜欢
    • 2011-10-17
    • 2012-09-04
    • 2013-03-28
    • 1970-01-01
    • 2012-01-24
    • 2012-06-01
    • 2012-09-09
    • 2013-01-15
    • 2013-02-10
    相关资源
    最近更新 更多