Android listSelector noch teilweise sichtbar, wenn das Element gescrollt wird

Das Bild zeigt das Problem: Venus Item ist gescrollt, aber es ist die Auswahl sichtbar.

Venus-Element wird gescrollt, aber die Auswahl ist sichtbar

  • C / C ++ printfs - Wo wird es in einem Android nativen Code angezeigt?
  • Ist versionCode / versionName im Bibliotheksmanifest erforderlich?
  • Konnte die Klasse XXX nicht finden, die von Methode XXX verwiesen wird. <YYY>
  • Android: Filtern eines SimpleCursorAdapter ListView
  • LOG4J in Android
  • Android: App laden Bibliothek zur Laufzeit auf Lollipop aber nicht IceCreamSandwich
  • Ich habe in Hanged listSelector in ListView gesehen und ich benutze Formen / Steigung, wie es beraten wurde, aber immer noch kein Glück.

    Gerät: MS VS Emulator für Android, Android 4.2 XHDPI API-17
    IDE: Android Studio 2. unter Windows 7 WM.

    Layout, Haupttätigkeit

     <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:choiceMode="singleChoice" android:drawSelectorOnTop="false" android:scrollingCache="false" android:animationCache="false" android:listSelector="@drawable/list_selector"> </ListView> </LinearLayout> 

    Listenauswahl

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

    Drawables, item_pressed

     <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <gradient android:angle="90" android:endColor="#0000ff" android:startColor="#0000ff" /> </shape> 

    Item_selected

     <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <gradient android:angle="90" android:endColor="#00ff00" android:startColor="#00ff00" /> </shape> 

    Und Aktivitätscode

     package com.example.listdemo; import android.app.ListActivity; import android.os.Bundle; import android.widget.ArrayAdapter; public class MainActivity extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.Planets, R.layout.myitem); setListAdapter(adapter); } } 

    Wo Planets nur eine Reihe von Streichern sind (Sonne, Merkur, Venus, Erde, Mars, Jupiter …) und myitem ist nur ein TextView mit benutzerdefinierter Höhe.

    Wo bin ich falsch, bitte?

    EDIT Um die Frage zu klären, geht es um das Default-Listen-Auswahlverhalten. Das ist über list selector item ohne android:state_xxx attributes. Achten Sie nicht auf den entsprechenden Zeichnungsnamen. Ich bin bereit, umbenennen @drawable/item_selected auf @drawable/item_default . Lassen Sie mich wissen, ob es helfen wird, das Problem zu klären, und ich werde es umbenennen.

  • Konvertieren von Android App in Java Desktop App
  • Wie bekomme ich Android-System Farben?
  • Wie kann ich wissen, ob ein Spinner-Item in Android ausgewählt wurde?
  • Hinzufügen von Enums zu Array Adapter für Spinner in Android
  • UUID und MACAddress für Bluetooth BLE
  • Streaming-Bibliothek VLC Android
  • 2 Solutions collect form web for “Android listSelector noch teilweise sichtbar, wenn das Element gescrollt wird”

    Tl; dr Legen Sie keine Voreinstellung fest.

    Dieses Problem tritt auf, wenn Sie dem Listenselektor einen Standardzeichner geben. Hiermit meine ich in deiner wählerdefinitionsdefinition, du hast eine item Tag ohne staatliche Anforderung, die diesen item versehentlich zum Standard Drawable macht. Hier können Sie mehr über Selektoren lesen.

    Ihre Liste selector code:

     <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/item_pressed" /> <item android:drawable="@drawable/item_selected" /> <-- this is what I'm referring to </selector> 

    Die Reparatur

    Das Problem, das Sie erhielten, wird durch den Listenauswahl verursacht, der immer gezeichnet wird (auch wenn der Selektor nicht auf dem Bildschirm ist). Normalerweise ist dies kein Problem, da der Listenwähler transparent (und damit unsichtbar) ist. Allerdings, da Sie die Liste selector einen Standard-Hintergrund gegeben, dies bedeutete, dass, wenn der Listen-Selektor auf dem Bildschirm war, wäre es sichtbar, was das seltsame Verhalten, das Sie beobachtet haben. Stattdessen, was Sie wirklich wollen, ist nur diesen Hintergrund zu zeigen, wenn ein Element tatsächlich ausgewählt ist.

    Um dies zu tun, müssen wir zuerst den Standardhintergrund aus dem Listenwähler entfernen. Dann brauchen wir einen neuen Weg, um ausgewählte Gegenstände anzuzeigen. Da Sie android:choiceMode="singleChoice" in Ihrem ListView angegeben haben, behandelt das ListView Ihre Listenelemente wie eine Liste von Checkboxen. Wenn also der Benutzer eines der Elemente überprüft, wird der aktivierte Zustand auf true gesetzt. TextViews werden jedoch keine visuellen Effekte anzeigen, wenn sie standardmäßig aktiviert sind. Um einen bestimmten Hintergrund anzuzeigen, müssen wir ein Listenelement-Layout verwenden, das den aktivierten Zustand anzeigen kann. Eine Möglichkeit dazu ist, den Hintergrund der ListView-Objektansicht auf einen Selektor zu ändern und eine Zeichenkette zu definieren, die Sie für den aktivierten Zustand verwenden möchten.

    Zum Beispiel:

    Adaptercode:

     ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.Planets, R.layout.myitem); 

    Myitem.xml:

     <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" style="?android:attr/spinnerItemStyle" android:singleLine="true" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/item_background" android:paddingTop="16dp" android:paddingBottom="16dp"/> 

    Item_background.xml:

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

    Oder wenn du faul bist:

     ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.planets_array, android.R.layout.simple_list_item_activated_1); 

    Weiterlesen

    Aus Android-Dokumentation ist es nicht ganz offensichtlich, dass das, was ich sagte, wahr ist, also könnten Sie fragen, ob meine Antwort glaubwürdig ist. Dieser Abschnitt widmet sich denen, die eine glaubwürdige Antwort und die sehr Neugierigen suchen.

    Um zu verstehen, wie der Listenauswahl funktioniert und wie es programmiert ist, müssen wir in den Android-Quellcode eintauchen. Um zu beginnen, ist das Fleisch der Logik der ListView tatsächlich in einer Klasse namens AbsListView (falls Sie nicht die Quelle heruntergeladen haben, können Sie sich darauf beziehen). Wenn wir in die Quelle dieser Klasse graben, finden wir ein paar nützliche Felder / Funktionen, die sich auf den Selektor beziehen:

    • mSelector : Dies ist die Zeichenkette des Selektors (die, die du mit android:listSelector )
    • mSelectorRect : Dieses Feld bestimmt, wo der Selektor gezeichnet wird und wie groß der Selektor ist
    • mSelectedPosition : Speichert den Index des ausgewählten Elements (dieses Feld ist eigentlich noch tiefer in der Klasse AdapterView )
    • positionSelector(...) : Updates, wo der Selektor gezogen werden soll
    • drawSelector(...) : Zeichnet den Selektor
    • trackMotionScroll(...) : Enthält die Logik des ListView Verhaltens der ListView

    Jetzt, da wir ein Verständnis für die Umwelt haben, können wir endlich die Kernlogik zum Verhalten des Listenwählers verstehen. Es kommt alles auf diese paar Zeilen Code in trackMotionScroll(...) :

     boolean trackMotionScroll(int deltaY, int incrementalDeltaY) { ... if (!inTouchMode && mSelectedPosition != INVALID_POSITION) { // if we are not in touch mode and there is a selected item then // we do a quick check if the selected item is on screen final int childIndex = mSelectedPosition - mFirstPosition; if (childIndex >= 0 && childIndex < getChildCount()) { // if the selected item is on screen, we move the selector to // where the selected item is positionSelector(mSelectedPosition, getChildAt(childIndex)); } } else if (mSelectorPosition != INVALID_POSITION) { // if we are in touch mode and there is a selected item then // we do a quick check if the selected item is on screen final int childIndex = mSelectorPosition - mFirstPosition; if (childIndex >= 0 && childIndex < getChildCount()) { // if the selected item is on screen, we move the selector to // where the selected item is positionSelector(INVALID_POSITION, getChildAt(childIndex)); } } else { // otherwise, if nothing is selected, hide the selector (don't draw it) mSelectorRect.setEmpty(); } ... } 

    Das Quell-Snippet oben wurde von der Vorlage bearbeitet, um Kommentare zu enthalten.

    Hier finden wir endlich die Logik, die das beobachtete Verhalten erklärt: Der mSelectorPosition == INVALID_POSITION wird nur dann ausgeblendet, wenn mSelectorPosition == INVALID_POSITION oder auf Englisch, wenn keine ausgewählten Elemente vorhanden sind. Andernfalls wird es an der ausgewählten Position positioniert, wenn das Element auf dem Bildschirm ist, ansonsten werden keine Änderungen an seiner Position vorgenommen.

    Wenn Sie also die ListView und das ausgewählte Element aus dem Bildschirm geht, bleibt der ListView nur an der letzten Stelle stehen. Das ausgewählte Element erklärte, dass der Ghost List Selektor beobachtet wurde.

    Abschließende Gedanken

    Von der Arbeit mit ListViews seit der Einführung, muss ich sagen, dass die ganze Sache ist nicht sehr gut entworfen und es kann extrem buggy sein. Ich empfehle es mit dem Nachfolger, dem RecyclerView , wann immer du kannst.

    Vielleicht kannst du versuchen, android hinzuzufügen: layerType = "software" in ListView.

     <ListView android:layerType="software" android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:choiceMode="singleChoice" android:drawSelectorOnTop="false" android:scrollingCache="false" android:animationCache="false" android:listSelector="@drawable/list_selector"> </ListView> 
    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.