Listview过滤器返回已过滤的列表但不返回正确的数据。 Android的

时间:2014-10-07 09:06:14

标签: android listview filter

我设法创建了一个联系人列表选择器,纯粹基于我在一些教程上学到的内容。它很棒。它可以加载我手机上的联系人。我可以选择联系人(通过选中复选框)并在单击保存按钮时将其保存到数据库。 什么是缺失的过滤功能,我可以通过向下滚动列表来过滤联系人。我确实设法使过滤工作,但它显示错误的数据。

请查看此屏幕截图,这样您就不会对我想说的内容感到困惑。

four examples of the listview, filtered and unfiltered

我还不能发布图片。遗憾

图1 - 2显示了listview中的所有数据。 在图像3中,我试图过滤“y”,列表应该显示“yuli”,而是显示“Test1” 如果你可以在Logcat中看到,那里有“yuli”,所以它只意味着我的过滤器工作。进一步测试它。我尝试“堵塞”过滤器应该返回2个果酱,但是再次显示“Test1”和“jam”果酱显示,因为它是列表中的下一个,这就是他出现的原因。如果再次查看logcat,过滤器将返回“jam”和“jamjam”。

我检查了所有代码,如果我想到它,它应该工作。我不知道在哪里看。

请帮帮我。

这也是代码。

public class FragmentTab3 extends Fragment {

MyCustomAdapter dataAdapter = null;
Context context = getActivity();
Button myButton;
ListView listView;
EditText filterText = null;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance){
    View rootView = inflater.inflate(R.layout.fragmenttab3, container,false);               
    new LongOperation().execute();
    return rootView;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    myButton = (Button) getView().findViewById(R.id.findSelected);
    listView = (ListView) getView().findViewById(R.id.list);
    filterText = (EditText) getView().findViewById(R.id.searchBox);
    filterText.addTextChangedListener(filterTextWatcher);
    listView.setTextFilterEnabled(true);
    checkButtonClick();

}

//filter the items in the list
private TextWatcher filterTextWatcher = new TextWatcher() {

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        // TODO Auto-generated method stub
        Log.d("edit", "editting");
        if (dataAdapter != null) {
            dataAdapter.getFilter().filter(s);
        } else {
            Log.d("filter","no contact found");
        }
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {
        // TODO Auto-generated method stub

    }

    @Override
    public void afterTextChanged(Editable s) {
        // TODO Auto-generated method stub

    }
};

public class MyCustomAdapter extends ArrayAdapter<Phonebook> {

    private ArrayList<Phonebook> phonebookList;
    private Filter filter;
    ViewHolder holder = null;

    public MyCustomAdapter(Context context, int textViewResourceId,

    ArrayList<Phonebook> phonebookList) {
        super(context, textViewResourceId, phonebookList);
        this.phonebookList = new ArrayList<Phonebook>();
        this.phonebookList.addAll(phonebookList);
    }

    private class ViewHolder {
        TextView name, number;
        CheckBox selected;
        ImageView imgView;
    }

//to inflate the view
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        Log.v("ConvertView", String.valueOf(position));

        if (convertView == null) {

            LayoutInflater vi = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            convertView = vi.inflate(R.layout.blacklist_layout, null);

            holder = new ViewHolder();
            holder.name = (TextView) convertView.findViewById(R.id.tvName);
            holder.number = (TextView) convertView
                    .findViewById(R.id.tvNumber);
            holder.selected = (CheckBox) convertView
                    .findViewById(R.id.checkBox1);
            holder.imgView = (ImageView) convertView
                    .findViewById(R.id.imgView);

            convertView.setTag(holder);

            holder.selected.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    CheckBox cb = (CheckBox) v;
                    Phonebook _state = (Phonebook) cb.getTag();
                    _state.setChecked(cb.isChecked());
                }
            });

        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        Phonebook state = phonebookList.get(position);

        holder.name.setText(state.getName());
        holder.number.setText(state.getNumber());
        holder.selected.setChecked(state.isChecked());
        Log.v("getImgUri", "" + state.getImgUri());
        holder.imgView.setImageURI(state.getImgUri());
        if (holder.imgView.getDrawable() == null) {
            holder.imgView.setImageResource(R.drawable.ic_launcher);
        }
        holder.selected.setTag(state);
        return convertView;
    }
    //here jam
    @Override
    public Filter getFilter(){
        if (filter == null) 
            filter = new AppFilter<Phonebook>(phonebookList);
            return filter;
    }
    /**class for filtering in arraylist listview, objects need a valid toString()method     */
    private class AppFilter<T> extends Filter{
        private ArrayList<T> sourceObjects;

        //contains the original data
        public AppFilter(List<T> phonebookList){
            sourceObjects = new ArrayList<T>();
            synchronized (this){
                sourceObjects.addAll(phonebookList);
            }
        }

        @Override
        protected FilterResults performFiltering(CharSequence chars) {
            // TODO Auto-generated method stub
            String filterSeq = chars.toString().toLowerCase();
            FilterResults result = new FilterResults();
            if (filterSeq != null && filterSeq.length()>0){
                ArrayList<T> filter = new ArrayList<T>();

                    for (int i = 0, l = sourceObjects.size(); i < l; i++){
                        //the filtering itself:
                        Phonebook m = phonebookList.get(i);
                        if (m.getName().toString().toLowerCase().contains(filterSeq))
                            filter.add((T) m);
                    }
                    result.count = filter.size();
                    result.values = filter;
            } else {
                //add all objects
                synchronized (this) {
                    result.values = sourceObjects;
                    result.count = sourceObjects.size();
                }
            }
            return result;
        }
        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {
            // TODO Auto-generated method stub
            //this function is always called from the ui thread
            ArrayList<T> filtered = (ArrayList<T>) results.values;
            notifyDataSetChanged();
            clear();
            for (int i = 0, l = filtered.size(); i < l; i++)
                add((Phonebook) filtered.get(i));
            for (int i = 0; i <filtered.size(); i++) {
                Phonebook g = (Phonebook) filtered.get(i);
                Log.d("f", g.getName().toString());
            }
            notifyDataSetInvalidated();
        }

    }
}

提前致谢,

果酱

1 个答案:

答案 0 :(得分:1)

publishResults()中,您应该将FilterResults results分配给适配器private ArrayList<Phonebook> phonebookList;以使用结果。

但你的适配器应该随身携带&#39;两个ArrayLists。一个是原始的,另一个是过滤的&#39;在使用中&#39;之一。

我不理解陈述add((Phonebook) filtered.get(i));。要添加什么?