1

在我的应用程序中,我从 Web 服务器获取数据并在列表视图中显示数据。我的列表视图的适配器包含图像和文本。现在,我想过滤列表视图。为此,我在我的自定义适配器中实现了 Filterable 接口。但是,它没有给出任何结果。我搜索了很多,但找不到任何结果。这是我的代码:

主要活动

Runnable r = new Runnable() 
        {
            @Override
            public void run() 
            { 
                listMainMenu.setAdapter(mMenuAdapter);
                listMainMenu.setTextFilterEnabled(true);
                mMenuAdapter.notifyDataSetChanged();
                pd.dismiss();
                updateUI = false;
            }//run
        };

文本观察器类

_txtAutoSearch.addTextChangedListener(filterTextWatcher);

private TextWatcher filterTextWatcher = new TextWatcher() {
    public void afterTextChanged(Editable s) {
        Log.v(TAG+" filtertextwatcher", "afterTextChanged");
    }//afterTextChanged

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        Log.v(TAG+" filtertextwatcher", "beforeTextChanged");
    }//beforeTextChanged

    public void onTextChanged(CharSequence s, int start, int before, int count) {
        Log.v(TAG+" filtertextwatcher", "onTextChanged");
        ((Filterable) listMainMenu.getAdapter()).getFilter().filter(s.toString());
    }//onTextChanged
};

我的自定义适配器:

    public class MainMenuAdapter extends BaseAdapter implements Filterable {
    Context ctx;
    ArrayList<MainCategoryDAO> mainCatDAOList;
    public static final String TAG = "MainMenuAdapter";
    ArrayList<MainCategoryDAO> arrayList;

    public MainMenuAdapter(Context ctx, ArrayList<MainCategoryDAO> mainCatDAOList) {
        this.ctx = ctx;
        this.mainCatDAOList = mainCatDAOList;
    }//Constructor

    public int getCount() {
        return mainCatDAOList.size();
    }//getCount

    public Object getItem(int position) {
        return mainCatDAOList.get(position);
    }//getItem

    public long getItemId(int position) {
        return 0;
    }//getItemId

    class ViewHolder {
        ImageView imgCategoryIcon;
        TextView txtCategoryName;
    }//ViewHolder

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if(convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_menu_adapter, null);
            holder = new ViewHolder();
            holder.imgCategoryIcon = (ImageView)convertView.findViewById(R.id.imgCategoryIcon);
            holder.txtCategoryName = (TextView)convertView.findViewById(R.id.txtCategoryName);
            convertView.setTag(holder);
        }//if
        else {
            holder = (ViewHolder) convertView.getTag();
        }//else
        Typeface cat_nameTF = Typeface.createFromAsset(ctx.getAssets(), "fonts/arial.ttf");
        Log.v(TAG, "category name "+ mainCatDAOList.get(position).getCategory_name());
        Log.v(TAG, "category icon "+ mainCatDAOList.get(position).getCategory_icon());
        BitmapManager.INSTANCE.loadBitmap(mainCatDAOList.get(position).getCategory_icon(), holder.imgCategoryIcon, 50, 50);
        holder.txtCategoryName.setTypeface(cat_nameTF);
        holder.txtCategoryName.setText(mainCatDAOList.get(position).getCategory_name());
        Log.v(TAG, "text view category name "+ holder.txtCategoryName.getText());
        return convertView;
    }//getView

    @Override
public Filter getFilter() 
{
    Filter mFilter = new Filter() 
    {

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) 
        {
            Log.v(TAG+" getFilter", "publishResults called");
            arrayList = (ArrayList<MainCategoryDAO>) results.values;
            Log.v(TAG+" getFilter", "publishResults arrayList size "+arrayList.size());
            for(int i = 0; i < arrayList.size(); i++)
            {
                Log.v(TAG+" getFilter filtered name", " "+arrayList.get(i).getCategory_name());
            }//for
            notifyDataSetChanged();
        }//publishResults

        @Override
        protected FilterResults performFiltering(CharSequence constraint) 
        {
            Log.v(TAG+" getFilter", "performFiltering called");
            FilterResults results = new FilterResults();
            ArrayList<MainCategoryDAO> FilteredArrList = new ArrayList<MainCategoryDAO>();

            if (constraint == null || constraint.length() == 0) 
            {
                Log.v(TAG+" getFilter", "if, constraint.length null or 0");
                results.count = mainCatDAOList.size();
                results.values = mainCatDAOList;
            }//if 
            else 
            {
                Log.v(TAG+" getFilter", "else, constraint.length not 0");
                constraint = constraint.toString();
                Log.v(TAG+" getFilter", "else, constraint = "+constraint);
                for (int i = 0; i < mainCatDAOList.size(); i++) 
                {
                    Log.v(TAG+" getFilter", "for loop, constraint.length not null or 0");
                    String data = mainCatDAOList.get(i).getCategory_name();
                    Log.v(TAG+" getFilter", "else, data to check "+data);
                    if (data.toLowerCase().startsWith(constraint.toString()))   
                    {
                        Log.v(TAG+" getFilter", "if in for loop, constraint.length not null or 0");
                        FilteredArrList.add(mainCatDAOList.get(i));
                    }//if
                }//for
                results.count = FilteredArrList.size();
                results.values = FilteredArrList;
            }//else
            return results;
        }//performFiltering
    };
    return mFilter;
}//getFilter
}//MainMenuAdapter

经过测试,我发现它正在过滤结果,但是更改没有反映在列表视图中。我什至尝试将 listview.setTextFilterEnabled() 设置为 true,但也没有用。在我的 logcat 上,我可以看到过滤后的值。但不明白为什么同样没有反映在 UI 中。

4

2 回答 2

4

您看不到任何 UI 更改是正常的,因为您没有在过滤后更新正确的数据列表。您MainMenuAdapter基于mainCatDAOList数据列表,但是在publishResults应该刷新适配器数据的方法中,您可以:

arrayList = (ArrayList<MainCategoryDAO>) results.values;
notifyDataSetChanged();

如您所见,您正在arrayList使用过滤后的值更新 ,而不是mainCatDAOList让适配器看不到任何更改。所以你的代码应该是:

protected void publishResults(CharSequence constraint,
            FilterResults results) {
        Log.v(TAG+" getFilter", "publishResults called");
        mainCatDAOList = (ArrayList<MainCategoryDAO>) results.values;
        Log.v(TAG+" getFilter", "publishResults arrayList size "+arrayList.size());
        for(int i = 0; i < arrayList.size(); i++)
        {
            Log.v(TAG+" getFilter filtered name", " "+arrayList.get(i).getCategory_name());
        }//for
        notifyDataSetChanged();
    }

此外,您应该有一份用于过滤的初始数据列表的副本,否则您将无法返回完整的值集。

于 2012-12-25T09:31:59.817 回答
1

你加吗

Adapter.notifyDataSetChanged();

在你的代码中?你能显示你的主要活动代码吗?我会帮助我们的。

于 2012-12-24T12:35:36.907 回答