【问题标题】:how to filter list items while using base adapter in android?在android中使用基本适配器时如何过滤列表项?
【发布时间】:2012-01-13 00:35:23
【问题描述】:

我一直在搜索很多关于通过编辑文本在列表视图中搜索项目的信息,尽管我发现了许多与我的问题类似的问题,但是在任何使用光标适配器的地方,直接从数据库中获取过滤结果或某个数组列表是用过。

就我而言,我一直在使用几个数组来使用基本适配器为我的列表视图传递文本。因为我以前从未做过这样的事情,所以我无法理解文本观察器的使用。

我调试了代码,发现没有调用发布结果方法,这可能是列表视图无法获取新值的原因。 我是否必须再次调用 listviewadaptercontacts 类,并在 text changed 方法中使用 names 数组中的刷新值。

请帮忙。

public class AllContactsActivity extends ListActivity implements
android.view.View.OnClickListener, OnItemClickListener {

    ListView lv;
    ListViewAdapterContacts lva;
    String[] names, phones, ids, types;


    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        LayoutParams params = new RelativeLayout.LayoutParams(
            LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        LinearLayout mainLayout = new LinearLayout(this);
        mainLayout.setOrientation(LinearLayout.VERTICAL);
        LayoutInflater layoutInflater = getLayoutInflater();
        mainLayout.addView(layoutInflater.inflate(R.layout.allcontacts, null));
        mainLayout.addView(layoutInflater.inflate(R.layout.allbuttons, null));
        this.addContentView(mainLayout, params);

        configureBottomMenu();
        getContacts();

        lv = new ListView(getApplicationContext());
        lv = (ListView) findViewById(android.R.id.list);
        lva = new ListViewAdapterContacts(this, names, types, phones, ids); //passing arrays to class
        lv.setAdapter(lva);
        et = (EditText) findViewById(R.id.searchcontact);
        et.addTextChangedListener(new TextWatcher() {

            public void onTextChanged(CharSequence s, int start, int before, int count) { // TODO Auto-generated method stub
                lva.getFilter().filter(s);

                lva.notifyDataSetInvalidated();
                lva.notifyDataSetChanged();
                lv.setAdapter(lva);
            }

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

                // TODO Auto-generated method stub

            }

            public void afterTextChanged(Editable s) {
                // TODO Auto-generated   method stub
            }
        });

        //some code
    }
}

public class ListViewAdapterContacts extends BaseAdapter implements Filterable {

    private ArrayFilter mFilter;
    private ArrayList < String > mOriginalValues;
    private final Object mLock = new Object();
    private List < String > mObjects;
    List list;

    Activity context;
    String[] names;
    String[] types;
    String[] numbers;
    String[] ids;
    public ListViewAdapterContacts(Activity context, String[] names, String[] types, String[] numbers, String[] ids) {
        // TODO Auto-generated constructor stub

        this.context = context;
        this.names = names;
        this.types = types;
        this.numbers = numbers;
        this.ids = ids;
        Object[] array = names;
        list = Arrays.asList(array);
    }



    public int getCount() {
        // TODO Auto-generated method stub 
        if (names == null) {
            return 0;
        } else {
            return names.length;
        }
    }

    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return null;
    }

    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }

    public class viewHolder {
        TextView top;
        TextView bottom;
        TextView downside;
        TextView base;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        viewHolder holder;
        if (convertView == null) {

            LayoutInflater inflator = context.getLayoutInflater();
            convertView = inflator.inflate(R.layout.textviewonly, null);

            holder = new viewHolder();
            holder.top = (TextView) convertView.findViewById(R.id.toptext);
            holder.bottom = (TextView) convertView.findViewById(R.id.bottomtext);
            holder.downside = (TextView) convertView.findViewById(R.id.lowest);
            holder.base = (TextView) convertView.findViewById(R.id.baseid);
            convertView.setTag(holder);
        } else {
            holder = (viewHolder) convertView.getTag();
        }
        holder.top.setText(names[position]);
        holder.bottom.setText(types[position]);
        holder.downside.setText(numbers[position]);
        holder.base.setText(ids[position]);
        return convertView;
    }

    public Filter getFilter() {
        // TODO Auto-generated method stub
        if (mFilter == null) {
            mFilter = new ArrayFilter();
        }
        return mFilter;
    }

    private class ArrayFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence prefix) {
            FilterResults results = new FilterResults();

            if (mOriginalValues == null) {
                synchronized(mLock) {
                    //mOriginalValues = new ArrayList<String>(mObjects);

                    mOriginalValues = new ArrayList < String > (list);
                }
            }

            if (prefix == null || prefix.length() == 0) {
                synchronized(mLock) {
                    ArrayList < String > list = new ArrayList < String > (mOriginalValues);
                    results.values = list;
                    results.count = list.size();
                }
            } else {
                String prefixString = prefix.toString().toLowerCase();

                final ArrayList < String > values = mOriginalValues;
                final int count = values.size();

                final ArrayList < String > newValues = new ArrayList < String > (count);

                for (int i = 0; i < count; i++) {
                    final String value = values.get(i);
                    final String valueText = value.toString().toLowerCase();

                    // First match against the whole, non-splitted value
                    if (valueText.startsWith(prefixString)) {
                        newValues.add(value);
                    } else {
                        final String[] words = valueText.split(" ");
                        final int wordCount = words.length;

                        for (int k = 0; k < wordCount; k++) {
                            if (words[k].startsWith(prefixString)) {
                                newValues.add(value);
                                break;
                            }
                        }
                    }
                }

                results.values = newValues;
                results.count = newValues.size();
            }

            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            //noinspection unchecked
            mObjects = (List < String > ) results.values;
            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    }
}

【问题讨论】:

  • 为什么不创建一个实体类 Contract 并使用 List 而不是使用 String[] 名称、电话、ids、类型,这样更容易过滤数据。
  • 但重点仍然相同。即使我使用实体类如何进行过滤
  • 迭代List,检查是否有合约满足contract.name.equals(NAME)等条件,将符合条件的放入一个新的List中,然后将新的List放入Adapter的构造函数
  • 这意味着我必须遍历列表中的每个元素。如果我有 200 个联系人怎么办,我认为在这种情况下,对于编辑文本的每个字符,过滤器方法将查找该字符串/我的联系人列表中的角色。你不认为它会影响演出吗?
  • 如果有200个联系人,我认为不会影响性能,反正你可以试一试。

标签: android listview filtering baseadapter


【解决方案1】:

在这段代码中:

et.addTextChangedListener(new TextWatcher() {

    public void onTextChanged(CharSequence s, int start, int before, int count) { // TODO Auto-generated method stub
        lva.getFilter().filter(s);

        lva.notifyDataSetInvalidated();
        lva.notifyDataSetChanged();
        lv.setAdapter(lva);
    }

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

      // TODO Auto-generated method stub

    }

    public void afterTextChanged(Editable s) {

        // TODO Auto-generated  method stub      
    }
});

ontextChanged() 方法中只使用:

lva.getFilter().filter(s);

【讨论】:

    猜你喜欢
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多