Intereting Posts
Добавленный EditText не является TextInputEditText. Вместо этого переключитесь на использование этого класса В чем разница между расширением действия и расширением ListActivity? Очистить данные пользователя или Очистить кеш на Android-телефоне Невозможно сгенерировать подписанный APK с proguard, включенным при использовании Joda Time './gradlew -Dtest.single = тест SimpleTest' запускает все тесты, которые у меня есть OnGlobalLayout различать различные вызовы Извлечение контактов в Android очень медленно Проблема с Jar-файлом с ADT r17 Adwhirl вызывает приложение для Android Как создать группы заголовков предпочтений в Android PreferenceActivity? Как получить представление из эспрессо, чтобы перейти в IdlingResource? Как проверить, зарегистрирован ли пользователь в Google+? Как эмуляция карт на основе программного обеспечения (HCE) гарантирует безопасность NFC? Android: изменение цвета строки состояния для уровня API ниже 21 Как я могу получить рабочую вертикальную SeekBar в Android?

Android listSelector все еще частично отображается, когда элемент прокручивается

На изображении показана проблема: элемент Venus прокручивается, но его выделение видно.

Элемент Венеры прокручивается, но его выбор видим

Я посмотрел на Hanged listSelector в ListView, и я использую фигуры / градиент, как это было рекомендовано, но все равно не повезло.

Устройство: MS VS Emulator для Android, Android 4.2 XHDPI API-17
IDE: Android Studio 2. на Windows 7 WM.

Макет, основная деятельность

 <?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> 

Селектор списка

 <?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> 

И код операции

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

Где Planets – это всего лишь массив строк (Солнце, Меркурий, Венера, Земля, Марс, Юпитер …), а myitem – это только myitem изображение с пользовательской высотой.

Где я ошибаюсь, пожалуйста?

EDIT Чтобы прояснить вопрос, речь идет о поведении списка по умолчанию. android:state_xxx идет о элементе выбора списка без атрибутов android:state_xxx . Не обращайте особого внимания на подходящее имя. Я готов переименовать @drawable/item_selected в @drawable/item_default . Дайте мне знать, если это поможет прояснить проблему, и я ее переименую.

Solutions Collecting From Web of "Android listSelector все еще частично отображается, когда элемент прокручивается"

Tl; dr Не устанавливать Default Drawable в вашем селекторе списка.

Эта проблема возникает, когда вы предоставляете селектору списка по умолчанию Drawable. Под этим я подразумеваю, что в определении селектора списка у вас есть тег item без требования штата, который делает этот item непреднамеренно по умолчанию . Здесь вы можете узнать больше о селекторах.

Ваш код выбора списка:

 <?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> 

Исправить

Проблема, с которой вы столкнулись, вызвана тем, что селектор списка всегда отображается (даже если селектор не находится на экране). Обычно это не проблема, поскольку селектор списков прозрачен (и, следовательно, невидим). Однако, поскольку вы предоставили селектору списка фон по умолчанию, это означало, что всякий раз, когда селектор списка находился на экране, он был бы виден, вызывая странное поведение, которое вы наблюдали. Вместо этого вы действительно хотите только показать этот фон, когда элемент действительно выбран.

Для этого сначала нужно удалить фон по умолчанию из селектора списков. Затем нам нужен новый способ указать выбранные элементы. Поскольку вы указали android:choiceMode="singleChoice" в ListView, ListView будет обрабатывать ваши элементы списка, как список флажков. Таким образом, когда пользователь проверяет один из элементов, активированное состояние будет установлено в true. Тем не менее, TextViews не будет показывать никаких визуальных эффектов при активации по умолчанию. Чтобы отобразить определенный фон при выборе, нам нужно использовать макет элемента списка, который может отображать активированное состояние. Один из способов сделать это – изменить фон представления элемента ListView на селектор и определить Drawable, который вы хотите использовать для активированного состояния.

Например:

Код адаптера:

 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> 

Или если вы ленивы:

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

дальнейшее чтение

Из документации Android не совсем очевидно, что то, что я сказал, верно, поэтому вы можете спросить, действительно ли мой ответ правдоподобен. Этот раздел посвящен тем, кто ищет надежный ответ и очень любопытный.

Чтобы понять, как работает селектор списков и как он запрограммирован, нам нужно будет погрузиться в исходный код Android. Для начала мясо логики ListView фактически хранится в классе AbsListView (в случае, если у вас нет загруженного источника, вы можете сослаться на это ). Копаясь в источнике этого класса, мы найдем несколько полезных полей / функций, относящихся к селектору:

  • mSelector : это Drawable селектора (тот, который вы указываете с помощью android:listSelector )
  • mSelectorRect : в этом поле определяется, где выполняется селектор, и насколько велика селектор
  • mSelectedPosition : Сохраняет индекс выбранного элемента (это поле фактически объявлено еще глубже в классе AdapterView )
  • positionSelector(...) : обновления, в которых должен быть выбран селектор
  • drawSelector(...) : Рисует селектор
  • trackMotionScroll(...) : Содержит логику поведения прокрутки ListView

Теперь, когда у нас есть понимание среды, мы можем, наконец, понять основную логику поведения селектора списков. Все это сводится к этим небольшим строкам кода в 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(); } ... } 

Исходный фрагмент выше был отредактирован из оригинала, чтобы включить комментарии.

Именно здесь мы, наконец, находим логику, объясняющую наблюдаемое поведение: Селектор списков скрыт только тогда, когда mSelectorPosition == INVALID_POSITION или на английском языке, когда нет выбранных элементов. В противном случае он позиционируется в выбранном элементе, если элемент находится на экране, иначе изменения не будут внесены в его положение.

Поэтому, когда вы просматриваете ListView и выбранный элемент отключается, селектор списков просто остается в последнем месте, в котором выбранный элемент объяснял выбранный селектор списка призраков .

Последние мысли

От работы с ListViews с момента его введения я должен сказать, что все это не очень хорошо спроектировано, и оно может быть чрезвычайно затруднительным. Я настоятельно рекомендую использовать его преемника, RecyclerView , когда это возможно.

Возможно, вы можете попробовать добавить android: layerType = "software" в 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>