Tło elementu ListView za pomocą niestandardowego selektora

Czy można zastosować niestandardowe tło do każdego elementu Listview za pomocą selektora listy?

Domyślny selektor określa @android:color/transparent dla przypadku state_focused="false", ale zmiana tego na niestandardowy drawable nie wpływa na elementy, które nie są zaznaczone. Romain Guy wydaje się sugerować w tej odpowiedzi , że jest to możliwe.

Obecnie osiągam ten sam efekt, używając niestandardowego tła na każdym widoku i ukrywając go, gdy element jest zaznaczony/skupiony / cokolwiek więc Selektor jest pokazane, ale byłoby bardziej elegancko mieć to wszystko zdefiniowane w jednym miejscu.

Dla odniesienia, to jest selektor używam, aby spróbować to działa:

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

I tak ustawiam selektor:

<ListView
    android:id="@android:id/list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:listSelector="@drawable/list_selector_background" />    

Z góry dzięki za pomoc!

Author: Community, 2010-04-01

10 answers

Sam byłem tym sfrustrowany i w końcu to rozwiązałem. Jak powiedział Romain Guy, jest inny stan, "android:state_selected", którego musisz użyć. Użyj stanu drawable dla tła elementu listy i użyj innego stanu drawable dla listSelector Twojej listy:

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>

Układ.xml zawierający 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>
 127
Author: dgmltn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-27 13:07:24

Rozwiązanie dglmtn nie działa, gdy masz 9-patch drawable z wyściółką jako tłem. Dzieją się dziwne rzeczy, nawet nie chcę o tym rozmawiać, jeśli masz taki problem, znasz je.

Teraz, jeśli chcesz mieć listview z różnymi stanami i 9-patch drawables (to działa z dowolnymi drawables i kolorami, myślę), musisz zrobić 2 rzeczy:

  1. Ustaw selektor dla pozycji na liście.
  2. pozbądź się domyślnego selektora dla lista.

Co należy zrobić, to najpierw ustawić 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>

Nie zapomnij android:state_selected. To działa jak android:state_focused dla listy, ale jest stosowane dla pozycji listy.

Teraz zastosuj selektor do elementów (wiersz.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>

Zrób przezroczysty selektor dla listy:

<ListView
    android:id="@+id/android:list"
    ...
    android:listSelector="@android:color/transparent"
    />
To powinno wystarczyć.
 78
Author: Michał K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-15 10:13:21

Nigdy nie używaj "koloru tła" dla wierszy listview...

To zablokuje każdą akcję selektora (to był mój problem!)

Powodzenia!

 17
Author: cV2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-21 08:57:32

Artykuł " Dlaczego moja lista jest czarna? Optymalizacja Androida " na blogu deweloperów Androida zawiera dokładne wyjaśnienie, dlaczego tło listy zmienia kolor na czarny podczas przewijania. Prosta odpowiedź: Ustaw cacheColorHint na liście na przezroczysty (#00000000).

 5
Author: Scott D. Strader,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-06 16:29:39

Wystarczy, jeśli wpiszesz 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>
 5
Author: Cabezas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-27 13:07:31

Zamiast:

android:drawable="@color/transparent" 

Napisz

android:drawable="@android:color/transparent"
 4
Author: Butters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-11 12:57:04

Możesz napisać temat:

<pre>

    android:name=".List10" android:theme="@style/Theme"

Temat.xml

<style name="Theme" parent="android:Theme">
        <item name="android:listViewStyle">@style/MyListView</item>
</style>

Styles.xml

 <style name="MyListView" parent="@android:style/Widget.ListView">
<item name="android:listSelector">@drawable/my_selector</item>

My_selector to twój własny selektor Przepraszam, że nie wiem jak napisać mój kod

 4
Author: pengwang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-27 13:08:00

Nie jestem pewien, jak osiągnąć pożądany efekt poprzez sam selektor - przecież z definicji jest jeden selektor dla całej listy.

Możesz jednak kontrolować zmiany zaznaczenia i rysować, co chcesz. W tym przykładowym projekcie robię selektor przezroczysty i rysuję pasek na wybranym elemencie.

 2
Author: CommonsWare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-01 17:51:49

Zawsze używam tej samej metody i działa za każdym razem, wszędzie gdzie: Po prostu używam takiego selektora

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

I ustaw na ListView (jest to bardzo ważne, aby działało) atrybut

android:choiceMode="singleChoice"

Dla textColor po prostu umieścić w folderze kolor (ważne, nie drawable folderu!) taki selektor

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

To przykładowy szablon wiersza

<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" />

Wszystko działa bez żmudne obejścia. hope this help

 2
Author: Apperside,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-12 11:04:27

/ Align = "center" bgcolor = "# e0ffe0 " / cesarz chin / / align = center /

Wszystkie API selektora nie działa zgodnie z oczekiwaniami. Po wypróbowaniu wszystkich rozwiązań przedstawionych w tym wątku na nic, po prostu rozwiązaliśmy problem w momencie napompowania elementu ListView.

  1. Upewnij się, że element zachowuje swój stan, zrobiliśmy to jako zmienna członkowska MenuItem (boolean selected)

  2. Kiedy nadmuchujesz, zapytaj, czy element bazowy jest wybrany, jeśli tak, po prostu ustaw zasób drawable, który chcesz jako tło (czy to 9patch czy cokolwiek). Upewnij się, że karta jest tego świadoma i że wywołuje notifyDataChanged (), gdy coś zostało wybrane.

        @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;
    }
    
Fajnie by było, gdyby selektory rzeczywiście działały, teoretycznie to ładne i eleganckie rozwiązanie, ale wygląda na to, że jest zepsute. Buziak.
 -3
Author: Gubatron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-11 20:58:34