android - listview holt die Artikelansicht nach Position

69

Ich habe Listenansicht mit benutzerdefiniertem Adapter (Basisadapter). Ich möchte die Ansicht von der Listenansicht nach Position erhalten. Ich habe es versucht mListView.getChildAt(position), aber es funktioniert nicht. Wie kann ich die Artikelansicht nach Position abrufen?

Alashow
quelle
4
Sie müssen erklären, was "nicht funktioniert" in Ihrer Situation bedeutet. Veröffentlichen Sie auch den entsprechenden Code, der nicht funktioniert, und eventuelle Fehlermeldungen.
CodeMagic
2
Ansicht wie diese listView.getChildAt(pos - listView .getFirstVisiblePosition());abrufen <Position ist die Position, auf die Sie geklickt haben) Ändern Sie die Ansicht und rufen Sie refreshDrawableState()diese Ansicht auf, um sie zu aktualisieren. Einfach :)
AZ_

Antworten:

251

Benutze das :

public View getViewByPosition(int pos, ListView listView) {
    final int firstListItemPosition = listView.getFirstVisiblePosition();
    final int lastListItemPosition = firstListItemPosition + listView.getChildCount() - 1;

    if (pos < firstListItemPosition || pos > lastListItemPosition ) {
        return listView.getAdapter().getView(pos, null, listView);
    } else {
        final int childIndex = pos - firstListItemPosition;
        return listView.getChildAt(childIndex);
    }
}
VVB
quelle
6
Bitte fügen Sie die Anzahl der Header hinzu: final int childIndex = pos + getHeaderViewsCount () - firstListItemPosition;
Wind
@iwind Können Sie bitte erläutern, warum Sie dies hinzufügen?
VVB
1
@RIT Wenn die ListView Header-Ansichten enthält, beginnt das untergeordnete Element mit den Header-Ansichten. Also ItemChildIndex = HeadersCount + ItemPosition.
Wind
6
Wenn Sie der getView-Methode null übergeben, wird sie gezwungen, eine neue Ansicht zu erstellen. Die bereits vorhandene wird nicht verwendet.
Frankish
2
Vielleicht verstehe ich die Frage nicht ... aber er scheint nach einer untergeordneten Ansicht innerhalb des Listenansichtselements nach Position zu suchen ... also onItemClick (AdapterView <?>) Adapter, Ansicht v, int pos, lange ID) { VIEWTYPE mView = (VIEWTYPE) v.findViewById (R.id.desiredview)} ... Vielleicht fragt er nach einem Nicht-Benutzer-Interaktionsansatz?
me_
14

Sie können nur eine sichtbare Ansicht von ListView erhalten, da Zeilenansichten in ListView wiederverwendbar sind. Wenn Sie verwenden, erhalten mListView.getChildAt(0)Sie erste sichtbare Ansicht. Diese Ansicht ist dem Element vom Adapter an Position zugeordnet mListView.getFirstVisiblePosition().

Matt Twig
quelle
4

Die bevorzugte Methode zum Ändern des Erscheinungsbilds / der Zeilenansichten nach dem Zeichnen der ListView besteht darin, etwas an den Daten zu ändern, aus denen ListView zeichnet (das Array von Objekten, das an Ihren Adapter übergeben wird), und dies in Ihrem getView () zu berücksichtigen. Funktion, dann zeichnen Sie die ListView durch Aufrufen neu

notifyDataSetChanged();

BEARBEITEN: Es gibt zwar eine Möglichkeit, dies zu tun, aber wenn Sie dies tun müssen, machen Sie wahrscheinlich etwas falsch. Während es nur wenige Randfälle gibt, über die ich nachdenken kann, ist die Verwendung notifyDataSetChanged()und anderer eingebauter Mechanismen im Allgemeinen ein guter Weg.

BEARBEITEN 2: Einer der häufigsten Fehler, den Menschen machen, besteht darin, einen eigenen Weg zu finden, um auf das Klicken / Auswählen einer Zeile in der ListView durch den Benutzer zu reagieren, wie in einem der Kommentare zu diesem Beitrag. Es gibt einen bestehenden Weg, dies zu tun. Hier ist wie:

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    /* Parameters
    parent:     The AdapterView where the click happened.
    view:       The view within the AdapterView that was clicked (this will be a view provided by the adapter)
    position:   The position of the view in the adapter.
    id:         The row id of the item that was clicked. */
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        //your code here
    }
});

ListView verfügt über viele integrierte Funktionen und es ist nicht erforderlich, das Rad für einfachere Fälle neu zu erfinden. Da Listview erweitert AdapterView , können Sie die gleichen Hörer, wie Set OnItemClickListener wie im Beispiel oben.

C0D3LIC1OU5
quelle
2
Sie liegen extrem falsch, mein Freund :) Sie können das Kind erhalten, indem Sie die ID des Kindes angeben, auf das der Klick ausgeführt wird. In der folgenden Zeile wird das Kind zurückgegeben, auf das der Klick ausgeführt wird. Sobald Sie dieses Kind bekommen haben, können Sie ändern, was Sie wollen, und dann müssen Sie diese Ansicht aufrufen refreshDrawableState(), um es zu aktualisieren :)listView.getChildAt(pos - listView .getFirstVisiblePosition());
AZ_
Sie müssen dies nicht tun, wenn Sie nur die Ansicht abrufen möchten, auf die der Benutzer geklickt hat. Siehe Änderungen am Beitrag.
C0D3LIC1OU5
Bitte geben Sie den Link zum Beitrag an, um zu sehen!
AZ_
Schauen Sie sich die EDIT 2 meiner Antwort an
C0D3LIC1OU5
1
Ihre Antwort ist sehr gut. Beantwortet meine Frage einfach nicht genau. In der Tat ist Ihre Antwort genauer. Ich meine, das Ändern des Ansichtsstatus / -stils durch Abrufen der Elementansicht ist falsch. Wenn Sie den Status / Stil der Elementansicht ändern, indem Sie die Elementansicht abrufen, werden die Änderungen beim nächsten Neuzeichnen / Scrollen übernommen. Es tut mir leid, dass die Leute dich missverstehen und dich dafür abstimmen.
Alashow
1
workignHoursListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent,View view, int position, long id) {
        viewtype yourview=yourListViewId.getChildAt(position).findViewById(R.id.viewid);
    }
});
Mohamed Ayed
quelle
0

Dies ist die Kotlin-Version der von VVB geposteten Funktion. Ich habe es im ListView-Adapter verwendet, um die Funktion "Zur nächsten Zeile zuerst EditText wechseln, wenn die Eingabetaste beim letzten EditText der aktuellen Zeile gedrückt wird" in getView () zu implementieren.

Fügen Sie in der ListViewAdapter-Klasse, fun getView (), lastEditText.setOnKeyListner wie folgt hinzu:

lastEditText.setOnKeyListener { v, keyCode, event ->
    var setOnKeyListener = false
    if (keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_UP) {
        try {
            val nextRow = getViewByPosition(position + 1, parent as ListView) as LinearLayout
            val nextET = nextRow.findViewById(R.id.firstEditText) as EditText
            nextET.isFocusableInTouchMode = true
            nextET.requestFocus()
        } catch (e: Exception) {
            // do nothing
        }
        setOnKeyListener = true
    }
    setOnKeyListener
}

Fügen Sie den Spaß getViewByPosition () nach dem Spaß getView () wie folgt hinzu:

private fun getViewByPosition(pos: Int, listView: ListView): View? {
    val firstListItemPosition: Int = listView.firstVisiblePosition
    val lastListItemPosition: Int = firstListItemPosition + listView.childCount - 1
    return if (pos < firstListItemPosition || pos > lastListItemPosition) {
        listView.adapter.getView(pos, null, listView)
    } else {
        val childIndex = pos + listView.headerViewsCount - firstListItemPosition
        listView.getChildAt(childIndex)
    }
}
David Chai
quelle
-4
Listview lv = (ListView) findViewById(R.id.previewlist);

    final BaseAdapter adapter = new PreviewAdapter(this, name, age);

    confirm.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub


            View view = null;

            String value;
            for (int i = 0; i < adapter.getCount(); i++) {

                view = adapter.getView(i, view, lv);

                Textview et = (TextView) view.findViewById(R.id.passfare);


                value=et.getText().toString();

                 Toast.makeText(getApplicationContext(), value,
                 Toast.LENGTH_SHORT).show();
            }



        }
    });
Arjun
quelle