webentwicklung-frage-antwort-db.com.de

Wie wähle ich ein ListView-Objekt nach einem langen Klick aus?

Ich habe ein dummes kleines Problem. Ich habe eine ListFragment sowohl als OnItemClickListener als auch als OnItemLongClickListener für eine eigene ListView registriert.

Wenn das Ereignis onItemClick aufgerufen wird, wird eine Absicht für die Detailansichtsaktivität dieses Elements gestartet, und es treten keine Probleme auf.

Wenn die onItemLongClickevent passiert, möchte ich die folgenden Dinge erreichen:

  • Erstellen Sie eine CAB
  • Halten Sie das lang gedrückte Element ausgewählt

Code:

@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;
}

In der CAB wird jedoch angezeigt, dass die Auswahl nicht beim Element verbleibt.

Einige Kleinigkeiten, falls sie relevant sind: Ich habe gelesen, wie man dieses Problem mit Aufrufen von view.requestFocusFromTouch() oder mit listView.setItemChecked() behebt, aber das hat bei mir nicht funktioniert. Außerdem werden die Ansichten für die Listenelemente aus einem benutzerdefinierten Layout instanziiert, es sind jedoch keine benutzerdefinierten Ereignis-Listener angehängt.

Jede Hilfe wird geschätzt. Vielen Dank!

12
Chris

Es ist möglich, aber kaum ... Ich weiß eigentlich nicht, wie so ein einfaches Ding so lächerlich kompliziert werden kann.

Der Schlüssel zur Antwort ist hier zu finden: Android: Blauen Hintergrund nach Auswahl von ListView beibehalten

Darauf kommt es an, einen zusätzlichen Stil zu definieren, der von ListView verwendet wird, und den Auswahlmodus auf AbsListView.CHOICE_MODE_SINGLE zu setzen (wie in der verknüpften Antwort erläutert).

Auf diese Weise können Sie die Auswahl mit Listview.setItemChecked() programmgesteuert umschalten. Sie müssen jedoch den Index des berührten Elements im Rückruf für onItemLongClick selbst nachverfolgen, da ListView.setSelection() dies nicht tut (zumindest wird ListView.getSelectedItem() immer -1 zurückgeben, soweit ich das sehe).

Code (zur Vereinfachung implementiert mein Fragment alle drei OnItemClickListener, OnItemLongClickListener und 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;
}

Und zum Schluss, wenn Sie die Auswahl aufheben möchten, wenn das CAB geschlossen ist:

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

Durch das Registrieren und Aufheben der Registrierung von OnItemClickListener wird sichergestellt, dass Sie bei aktivem CAB nicht versehentlich die mit dem Element verbundene Aktion auslösen (z. B. das Öffnen einer Detailansicht).

8
Chris

Meine Lösung: (Trick)

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