ListView элемент фона с помощью пользовательского селектора
можно ли применить пользовательский фон к каждому элементу Listview с помощью селектора списка?
селектор по умолчанию указывает @android:color/transparent
на state_focused="false"
case, но изменение этого на некоторые пользовательские drawable не влияет на элементы, которые не выбраны. Ромен Гай, кажется, предполагает в этом ответе, что это возможно.
в настоящее время я достигаю того же эффекта, используя пользовательский фон на каждом представлении и скрывая его, когда элемент выбран / сфокусирован / независимо от того, что селектор показан, но было бы более элегантно, чтобы все это было определено в одном месте.
для справки, это селектор я использую, чтобы попытаться получить эту работу:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="false"
android:drawable="@drawable/list_item_gradient" />
<!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
<item android:state_focused="true" android:state_enabled="false"
android:state_pressed="true"
android:drawable="@drawable/list_selector_background_disabled" />
<item android:state_focused="true" android:state_enabled="false"
android:drawable="@drawable/list_selector_background_disabled" />
<item android:state_focused="true" android:state_pressed="true"
android:drawable="@drawable/list_selector_background_transition" />
<item android:state_focused="false" android:state_pressed="true"
android:drawable="@drawable/list_selector_background_transition" />
<item android:state_focused="true"
android:drawable="@drawable/list_selector_background_focus" />
</selector>
и вот как я устанавливаю селектор:
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:listSelector="@drawable/list_selector_background" />
заранее спасибо за любую помощь!
10 ответов:
Я был разочарован этим сам и, наконец, решил его. Как намекнул Ромен Гай, есть еще одно государство,
"android:state_selected"
, что вы должны использовать. Использовать государственного выигрышного для фона своего элемента списка, и использовать различные государства мешочки дляlistSelector
список:list_row_layout.XML-код:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="?android:attr/listPreferredItemHeight" android:background="@drawable/listitem_background" > ... </LinearLayout>
listitem_background.XML-код:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" android:drawable="@color/android:transparent" /> <item android:drawable="@drawable/listitem_normal" /> </selector>
макет.xml, который включает в себя ListView:
... <ListView android:layout_width="fill_parent" android:layout_height="wrap_content" android:listSelector="@drawable/listitem_selector" /> ...
listitem_selector.XML-код:
<?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/listitem_pressed" /> <item android:state_focused="true" android:drawable="@drawable/listitem_selected" /> </selector>
решение dglmtn не работает, когда у вас есть 9-патч drawable с дополнением в качестве фона. Странные вещи происходят, я даже не хочу говорить об этом, если у вас такая проблема, вы их знаете.
теперь, если вы хотите иметь listview с различными состояниями и 9-патч drawables (он будет работать с любыми drawables и цветами, я думаю), вы должны сделать 2 вещи:
- установите селектор для элементов в списке.
- избавиться от значения по умолчанию селектор для списка.
что вы должны сделать, это сначала установить row_selector.XML-код:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:state_enabled="true" android:state_pressed="true" android:drawable="@drawable/list_item_bg_pressed" /> <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/list_item_bg_focused" /> <item android:state_enabled="true" android:state_selected="true" android:drawable="@drawable/list_item_bg_focused" /> <item android:drawable="@drawable/list_item_bg_normal" /> </selector>
не забудьте
android:state_selected
. Он работает какandroid:state_focused
для списка, но он применяется для элемента списка.теперь примените селектор к элементам (строка.xml):
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:background="@drawable/row_selector" > ... </RelativeLayout>
сделайте прозрачный селектор для списка:
<ListView android:id="@+id/android:list" ... android:listSelector="@android:color/transparent" />
это дело.
никогда не используйте "цвет фона" для ваших строк listview...
Это будет блокировать каждое действие селектора (была моя проблема!)
удачи!
этого достаточно, если вы вставляете
list_row_layout.xml
:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:background="@drawable/listitem_background">... </LinearLayout>
listitem_selector.XML-код:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@color/dark" android:state_pressed="true" /> <item android:drawable="@color/dark" android:state_focused="true" /> <item android:drawable="@android:color/white" /> </selector>
вместо:
android:drawable="@color/transparent"
написать
android:drawable="@android:color/transparent"
вы можете написать тему:
<pre> android:name=".List10" android:theme="@style/Theme"
тема.xml
<style name="Theme" parent="android:Theme"> <item name="android:listViewStyle">@style/MyListView</item> </style>
стили.xml
<style name="MyListView" parent="@android:style/Widget.ListView"> <item name="android:listSelector">@drawable/my_selector</item>
my_selector - это ваш пользовательский селектор Мне жаль, что я не знаю как написать мой код
Я не уверен, как достичь желаемого эффекта через сам селектор-в конце концов, по определению, есть один селектор для всего списка.
тем не менее, вы можете получить контроль над изменениями выбора и рисовать все, что хотите. В этот пример проекта, Я делаю селектор прозрачным и рисую полосу на выбранном элементе.
Я всегда использую тот же метод, и он работает каждый раз, каждый где: Я просто использую селектор, как это
<item android:state_activated="true" android:color="@color/your_selected_color" /> <item android:state_pressed="true" android:color="@color/your_pressed_color" /> <item android:color="@color/your_normal_color"></item>
и установите на ListView (это очень важно, чтобы он работал) атрибут
android:choiceMode="singleChoice"
для textColor просто поместите в папку color (важно, не рисуемая папка!) селектор, как это
<item android:state_activated="true" android:color="@color/your_selected_textColor" /> <item android:state_pressed="true" android:color="@color/your_pressed_textColor" /> <item android:color="@color/your_normal_textColor"></item>
это пример строки шаблон
<ImageView android:id="@+skinMenu/lblIcon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_horizontal" android:src="@drawable/menu_catalog" /> <TextView android:id="@+skinMenu/lblTitle" style="@style/superlabelStyle" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginLeft="20dp" android:gravity="center_vertical" android:text="test menu testo" android:textColor="@color/menu_textcolor_selector" android:textSize="20dp" android:textStyle="bold" />
все должен работать без утомительных обходные пути. надеюсь, что это поможет
команда FrostWire здесь.
все селектор дерьмо api не работает, как ожидалось. После попытки всех решений, представленных в этом потоке, мы просто решили проблему в момент раздувания элемента ListView.
убедитесь, что ваш элемент сохраняет его состояние, мы сделали это в качестве переменной-члена MenuItem (boolean selected)
когда вы надуваете, спросите, выбран ли Базовый элемент, если да, просто установите drawable ресурс, который вы хотите в качестве фона (будь то 9patch или что-то еще). Убедитесь, что ваш адаптер знает об этом и что он вызывает notifyDataChanged (), когда что-то было выбрано.
@Override public View getView(int position, View convertView, ViewGroup parent) { View rowView = convertView; if (rowView == null) { LayoutInflater inflater = act.getLayoutInflater(); rowView = inflater.inflate(R.layout.slidemenu_listitem, null); MenuItemHolder viewHolder = new MenuItemHolder(); viewHolder.label = (TextView) rowView.findViewById(R.id.slidemenu_item_label); viewHolder.icon = (ImageView) rowView.findViewById(R.id.slidemenu_item_icon); rowView.setTag(viewHolder); } MenuItemHolder holder = (MenuItemHolder) rowView.getTag(); String s = items[position].label; holder.label.setText(s); holder.icon.setImageDrawable(items[position].icon); //Here comes the magic rowView.setSelected(items[position].selected); rowView.setBackgroundResource((rowView.isSelected()) ? R.drawable.slidemenu_item_background_selected : R.drawable.slidemenu_item_background); return rowView; }
было бы очень хорошо, если бы селекторы действительно работали, теоретически это хорошее и элегантное решение, но похоже, что оно сломано. ПОЦЕЛУЙ.