2

カスタム チェック可能リストに基づいて複数選択リストを実装しようとしています。必要なリストが 1 つだけの場合はかなり単純ですが、複数のリストを切り替える必要がある場合は複雑になります。

私の場合、アクティビティの上部にはカテゴリを表すボタンがたくさんあります。それらのすぐ下には、現在選択されているカテゴリのアイテムを含むリストがあります。

ListAdapter項目のリスト ビューは、拡張する に基づいていBaseAdapterます。

public class ListAdapter extends BaseAdapter {

    private static LayoutInflater layoutInflater = null;
    private ArrayList<String> data;

    public ListAdapter(Activity activity, ArrayList<String> data) {
        layoutInflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.data = data;
    }

    public void setData(ArrayList<String> data) {
        this.data = data;
    }

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

    @Override
    public Object getItem(int position) {
        return data.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        CheckableRelativeLayout view = (CheckableRelativeLayout) convertView;

        if (view == null) {
            view = (CheckableRelativeLayout) layoutInflater.inflate(
                    R.layout.checkable_relative_layout, null);
        }

        TextView number = (TextView) view.findViewById(R.id.number);
        TextView name = (TextView) view.findViewById(R.id.name);

        number.setText(Integer.toString(position));
        name.setText(data.get(position));

        return view;
    }

}

各アイテムのビューは膨張していCheckableRelativeLayoutます:

public class CheckableRelativeLayout extends RelativeLayout implements
        Checkable {

    private static final int[] CheckedStateSet = { android.R.attr.state_checked };
    private boolean isChecked = false;

    public CheckableRelativeLayout(Context context) {
        super(context);
    }

    public CheckableRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CheckableRelativeLayout(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean isChecked() {
        return isChecked;
    }

    @Override
    public void setChecked(boolean checked) {
        isChecked = checked;
        refreshDrawableState();
    }

    @Override
    public void toggle() {
        isChecked = !isChecked;
        refreshDrawableState();
    }

    @Override
    protected int[] onCreateDrawableState(int extraSpace) {
        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
        if (isChecked()) {
            mergeDrawableStates(drawableState, CheckedStateSet);
        }
        return drawableState;
    }

}

UI での選択表現は、 内で指定されますselection.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/gradient_bg_checked" android:state_checked="true"/>
    <item android:drawable="@drawable/gradient_bg"/>
</selector>

そして、主な活動は次のようになります。

public class MultipleCheckList extends Activity {

    private ListView listView;
    private ListAdapter adapter;
    private SparseArray<ArrayList<String>> data = new SparseArray<ArrayList<String>>();

    private class ButtonClickListner implements OnClickListener {
        @Override
        public void onClick(View buttonView) {
            Integer tag = (Integer) buttonView.getTag();
            adapter.setData(data.get(tag));
            adapter.notifyDataSetChanged();
            listView.refreshDrawableState();
            // How to save user's selections?
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_multiple_check);

        Button button1 = (Button) findViewById(R.id.button_1);
        Button button2 = (Button) findViewById(R.id.button_2);
        button1.setTag(1);
        button2.setTag(2);
        button1.setOnClickListener(new ButtonClickListner());
        button2.setOnClickListener(new ButtonClickListner());
        button1.setText("First category");
        button2.setText("Second category");

        ArrayList<String> data1 = new ArrayList<String>();
        data1.add("John");
        data1.add("Bob");
        data1.add("Ted");

        ArrayList<String> data2 = new ArrayList<String>();
        data2.add("Summer");
        data2.add("Winter");
        data2.add("Spring");

        data.append(1, data1);
        data.append(2, data2);

        adapter = new ListAdapter(this, data1);

        listView = (ListView) findViewById(R.id.list);
        listView.setAdapter(adapter);
        listView.setItemsCanFocus(false);
        listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    }
}

私の質問は、ユーザーの選択を保存する最良の方法は何ですか?

ListAdapter各カテゴリのインスタンスをに保存し、 for each inHashMapを呼び出して再利用しようとしました。機能していないように見えるだけでなく (選択の状態が復元されない)、不要なガベージ コレクションが原因で効率的ではありません。setAdapter()onClick()ButtonClickListner

setData()次に、 、notifyDataSetChanged()およびrefreshDrawableState()呼び出し (上記のコードのように) を使用して、それらを組み合わせてHashMap選択ストレージ用に使用しようとしました。問題は、refreshDrawableState()が呼び出されたとしても、すべての選択がカテゴリ間で共有されることです。

ここに画像の説明を入力 ここに画像の説明を入力

も調べましたParcelableが、それは活動間のリソース交換にのみ役立つようです。たぶん、各リストを個別に膨らませることが良い解決策と見なされるでしょうか? しかし、効率はどうでしょうか?setData()アプローチはおそらくはるかに経済的です。

ご協力ありがとうございました。

4

3 に答える 3

0

ListAdapter() 内に、名前を格納するカスタマイズ クラスを格納し、項目が選択されているかどうかを確認できます。

public class ListAdapter extends BaseAdapter {
    private static LayoutInflater layoutInflater = null;
    private ArrayList<Object E> data; // Here E will your customize Class.
    ...
}
于 2013-05-28T21:34:16.353 に答える
0

私はあなたの目的が何であるか分かりません。

ListAdapter の 1 つのインスタンス:

あなたは、私の上記の回答と、以下に示すように1つの小さな変更でこれに問題がないことに同意するでしょうgetView:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
      if(data.selected) {
             // Make item selected.
       }
}

ListAdapter の複数のインスタンス:

別のポインターでそれらにアクセスする必要があります。

于 2013-05-28T23:18:04.357 に答える