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基づいていますが、アダプターのデータを更新する必要がある方法では、次のようにします。mainCatDAOListpublishResults

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 に答える