web-dev-qa-db-ja.com

ロングクリック後にListViewアイテムを選択するにはどうすればよいですか?

私はばかげた小さな問題を抱えています。 ListFragmentを独自のOnItemClickListenerOnItemLongClickListenerListViewの両方として登録しました。

onItemClickイベントが呼び出されると、そのアイテムの詳細ビューアクティビティのインテントが開始され、問題はありません。

onItemLongClickeventが発生したとき、私は次のことを達成したいと思います。

  • CABを作成する
  • 長押しのアイテムを選択したままにします

コード:

_@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
    if(this.cabMode != null)
        return false;
    this.cabMode = getActivity().startActionMode(editModeCallback);
    view.setSelected(true);
    return true;
}
_

CABは表示されますが、選択はアイテムにとどまりません。

関連する場合に備えて、いくつかの断片:view.requestFocusFromTouch()の呼び出しまたはlistView.setItemChecked()の使用でこの問題を修正する方法について読みましたが、うまくいきませんでした。また、リストアイテムのビューはカスタムレイアウトからインスタンス化されますが、カスタムイベントリスナーはアタッチされていません。

どんな助けでも大歓迎です。どうも!

14
Chris

可能ですが、かろうじて...こんなに単純なことがどうしてこんなにばかげて複雑になるのか、私にはわかりません。

答えの鍵はここにあります: Android:ListViewの選択後も青い背景を維持します

つまり、ListViewで使用される追加のスタイルを定義し、選択モードを_AbsListView.CHOICE_MODE_SINGLE_に設定することです(リンクされた回答で説明されています)。

これにより、Listview.setItemChecked()を使用してプログラムで選択を切り替えることができます。ただし、ListView.setSelection()はそれを行わないため、onItemLongClickコールバックでタッチされたアイテムのインデックスを自分で追跡する必要があります(少なくともListView.getSelectedItem()は常にそうします私が見る限り-1を返します)。

コード(簡単にするために、私のフラグメントは3つすべてのOnItemClickListenerOnItemLongClickListener、および_ActionMode.Callback_を実装します):

_@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    this.listViewAdapter = new ListViewAdapter();
    this.root = (ListView)inflater.inflate(R.layout.fragment_bookmarks, container, false);
    this.root.setAdapter(this.listViewAdapter);
    this.root.setOnItemClickListener(this);
    this.root.setOnItemLongClickListener(this);
    this.root.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
    return this.root;
}

@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
    if(this.cabMode != null)
        return false;
    this.selectedPosition = position;
    this.root.setItemChecked(position, true);

    this.root.setOnItemClickListener(null);
    this.cabMode = getActivity().startActionMode(this);
    return true;
}
_

そして最後に、CABが閉じているときに選択を削除したい場合は、次のようにします。

_@Override
public void onDestroyActionMode(ActionMode mode) {
    cabMode = null;
    this.root.setItemChecked(this.selectedPosition, false);
    this.selectedPosition = -1;
    this.root.setOnItemClickListener(this);
}
_

OnItemClickListenerを登録および登録解除すると、CABがアクティブなときに、通常はアイテムに関連付けられているアクション(詳細ビューを開くなど)が誤ってトリガーされないようになります。

8
Chris

私の解決策:(トリック)

final ListView lvMain = (ListView) activity.findViewById(R.id.listTHEMES);
lvMain.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
lvMain.setItemsCanFocus(false);

ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity,
            Android.R.layout.simple_list_item_multiple_choice, ArrayTheme);
lvMain.setAdapter(adapter);
lvMain.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
    @Override
    public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
                                       int pos, long id) {
        // TODO Auto-generated method stub
        if (lvMain.isItemChecked(pos)){lvMain.setItemChecked(pos,false);}else{lvMain.setItemChecked(pos,true);}
        Log.v(LOG_TAG,"long clicked pos: " + pos);
        //lvMain.setSelection();

        return true;
    }
});
lvMain.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {
        //Log.d(LOG_TAG, "itemClick: position = " + position + ", id = " + id);
        if (lvMain.isItemChecked(position)){lvMain.setItemChecked(position,false);}else{lvMain.setItemChecked(position,true);}

    }
});
1
Sergey Paukov