开发者

ListSelector applies to the entire list

I have a simple list with a listselector like so.

<ListView android:id="@+id/list" android:layout_width="fill_parent"
    android:layout_height="fill_parent" android:layout_below="@+id/round"
    android:listSelector="#99000000" android:clickable="true" android:cacheColorHint="#00000000" android:background="#00000000">
</ListView>

As you can see android:listSelector="#99000000" but the "black alpha" color is applied to the entire list, not the selected item.


So this is what I have now but the entire list still turns black

::listview_background.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_enabled="false" android:state_focused="true"
        android:drawable="@drawable/list_normal" />
  <item android:state_pressed="true"
        android:drawable="@drawable/list_pressed" />
  <item android:state_focused="true"
        android:drawable="@drawable/list_active" />
</selector>

::colors.xml

<resources>
    <drawable name="list_normal">#96FFFFFF</drawable>
    <drawable name="list_active">#66000000</drawable>
    <drawable name="list_pressed">#CA000000<开发者_开发技巧/drawable>
</resources>

::the xml tag in my list

android:listSelector="@drawable/listview_background"


I was having this same issue and while looking at one of the platform drawable XML files I noticed a way to eliminate the need to create an image file just for a color, by creating a shape in XML.

For example, instead of:

<item android:state_focused="true"
      android:drawable="@drawable/list_active" />

Do:

<item android:state_focused="true">
    <shape>
        <solid android:color="#66000000" />
    </shape>
</item>

Beyond just creating a plain color drawable, the shape is flexible, similar to a simple vector object. All the details can be found here: http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape


I had the same problem. I have a custom background image, and I don't want to have to make variants of that background image because that would be tedious to represent all the different states.

So I want to do the obvious thing, have a semi-transparent bar that is overlayed on top of the focused listitem and when the user taps the "enter" key or whatever, it flashes to the pressed overlay color which is more striking and somewhat more opaque.

The solution was to stay away from any @color or @drawable that refers to a color inside listSelector. I created two 3x3 pixel .png files. Each saved with the gamma layer. In my case it's two of the same color each mixed down in Gimp with a different transparency on the color layer. So when you select an item you get an overlay with 25% color, and when you press it you get a png with 50% color. I put them in my drawables as bg_list_item_pressed.png and bg_list_item_highlighted.png

Then I set my list selector to:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 

  <!-- Selected --> 
  <item 
    android:state_focused="true" 
    android:state_pressed="false" 
    android:drawable="@drawable/bg_list_item_highlighted" /> <!--  @drawable/tab_focus -->

  <!-- Pressed -->
  <item 
    android:state_pressed="true" 
    android:drawable="@drawable/bg_list_item_pressed" /> <!--  @drawable/tab_press -->

</selector> 

Then I added my listSelector attributes to my ListView in my layout xml:

android:listSelector="@drawable/list_selector"
android:drawSelectorOnTop="true"

Now it works exactly how I want it to work. Including using the D-pad to select a row, and click it with enter. Getting the highlighting and subsequent pressing colors exactly how they should be.


If you are setting up a row layout for each item in the list, this is how I do it. Note the transparent value set to the listSelector. (For brevity, I removed the colors.xml.)

main.xml

<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
  <ListView
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:listSelector="#00000000"/>
</LinearLayout>

row.xml

<FrameLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/row"
  android:layout_width="fill_parent"
  android:layout_height="?android:attr/listPreferredItemHeight"
  android:background="@drawable/list_selector">
  ...
</FrameLayout>

list_selector.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="#66FFFFFF" />
    <item android:drawable="#FF666666"/> 
</selector>


Jax,

I was trying to figure out why my entire list was changing color setting the listSelector, and found out that this is exactly what it is supposed to do, i.e. we are setting the color for the entire list, and not the row which is what we want.

Here is what you want to do: I assume you have a ListView defined in XML. And for this ListView, I assume you are using an adapter of some sort to set present the data. Also for this adapter, you are using some row view that is defined in XML. What you want to do is set the background of this row element like this:

<?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="fill_parent"
    android:orientation="horizontal"
    android:background="@drawable/textview_selector">
        <TextView       android:id="@+id/textForList"
        android:layout_height="fill_parent"
        android:layout_width="wrap_content"
        android:padding="10sp"  />
</LinearLayout>

Here is my textview_selector.xml stored in drawable:

<?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/teal" />
    <item android:drawable="@drawable/white" />
</selector>

Hope this helps


The list selector is a StateListDrawable — it contains reference to multiple drawables for each state the list can be, like selected, focused, pressed, disabled...

In your case, by setting a single colour, the list is drawing #9000 for every single state.

You need to define a StateListDrawable as described above, with XML similar to the following. This is what you set in your android:listSelector attribute.

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

Or, to set the same list selector for all lists in your application, you can override the selector in the Widget.ListView theme:

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


You don't always need to create an image, you can define a shape

<?xml version="1.0" encoding="utf-8"?>

<item android:state_focused="true" android:state_pressed="false">
     <shape android:shape="rectangle">
         <solid android:color="#40000000"/>
     </shape>
</item>
<item android:state_pressed="true">
     <shape android:shape="rectangle">
         <solid android:color="#80000000"/>
     </shape>
</item>

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜