I have a ListView and each row uses a custom background color. I'd like to ensure that the default highlight is shown when the user touches a row, so I've defined a drawable with a selector, like this:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:attr/colorControlHighlight">
<item>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/clear" android:state_selected="true"/>
<item android:drawable="#color/clear" android:state_focused="true" android:state_pressed="true"/>
<item android:drawable="#color/clear" android:state_pressed="true"/>
<item android:drawable="#color/white"/>
</selector>
</item>
</ripple>
At first glance, it seems to work. However, if I scroll to a row that wasn't previously on the screen, the first time I tap the row, I don't get a ripple. But then if I tap it again, I do see the ripple. If I scroll the row off the screen and then back on again, same thing keeps happening.
Any ideas??
Thanks!!
Related
I'm struggling with ListView selector. I want to have gray color on list item when the user has his finger on the screen. That's all. When the user releases the finger (or move it elsewhere) the color should back to white as it should be all the time. This is my ListView:
<ListView android:layout_width="match_parent"
android:layout_height="match_parent"
android:duplicateParentState="true"
android:textAppearance="?android:textAppearanceMedium"
android:drawSelectorOnTop="false"
android:listSelector="#drawable/my_list_selector"
android:id="#+id/list"/>
This is selector:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/colorPrimary"
android:state_activated="true"/>
<item android:drawable="#color/colorPrimaryDark"
android:state_activated="false"/>
</selector>
What am I doing wrong in here?
P.S. If true and false are given in the opposite way nothing happens.
Seems like you want to use android:state_pressed instead of android:state_activated
code
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/colorPrimary"
android:state_pressed="true"/>
<item android:drawable="#color/colorPrimaryDark"/>
</selector>
After the discussion with OP and #pskink the issue was resolved with
<item android:state_window_focused="false" android:drawable="#color/transparent"/>
I defined a ripple drawable and set it as the background for the listview item view's background. It almost works fine but the ripple effect just sometimes does not show up upon press.
Here is the ripple drawable code:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:attr/colorControlHighlight">
<item>
<selector>
<item android:state_activated="true">
<shape><solid android:color="?android:attr/colorButtonNormal"/>
</shape>
</item>
<item>
<shape><solid android:color="#android:color/transparent"/>
</shape>
</item>
</selector>
</item>
</ripple>
And I have a navigation drawer which uses this drawable as the background for drawer items:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="#dimen/navigation_menu_height"
android:orientation="horizontal"
android:background="#drawable/listItemBackground">
....
</RelativeLayout>
However every time when I open the app, the default selected item does not show the ripple effect when I press it. But after I select another item and then select it again, everything would just goes fine.
I use exactly the same for another almost the same ListView, except the choice mode is multiple. And this time, the items will not show the ripple effect upon press as long as they are selected.
In another listView, which does not specify choice mode, only the first item shows ripple effect, and others behave the same as in lower Android versions.
I really have no idea of how I can make it work for all scenarios. maybe is it really relates to the choice mode of the ListView?
====EDIT====
I just added property drawSelectorOnTop for all these three listViews and now the first two problems are cleared. However for the third one, it now becomes like this:
Ripple effect works good on all items except the first one which shows two ripples! One of them starts from where my finger presses while the other always starts from the middle!
====EDIT AGAIN====
OK, now I tweak the drawable to move the activated status outside of ripple node, together with the drawSelectorOnTop attribute for the listview, the problem's now completely gone.
OK, After some try and error, I have finally get it work.
First, move the activated state out of ripple node:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true">
<shape>
<solid android:color="?android:attr/colorButtonNormal"/>
</shape>
</item>
<item>
<ripple android:color="?android:attr/colorControlHighlight">
<item>
<shape>
<solid android:color="#android:color/transparent"/>
</shape>
</item>
</ripple>
</item>
</selector>
After that, set drawSelectorOnTop to true for the ListView that use the drawable as item background.
Now the ripple effect can work perfectly.
In my case ripple effect is working after the first click, but for first click it didn't work for me. Have changed the background selector file with android:state_activated="true" and in main.xml android:clickable="true" then it's work fine for all time.
selector.xml (under res\drawable\selector.xml)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true" android:drawable="#drawable/card_bg_pressed" android:state_enabled="true" android:state_pressed="true"/>
<item android:state_activated="true" android:drawable="#drawable/card_bg_focused" android:state_enabled="true" android:state_focused="true"/>
<item android:state_activated="true" android:drawable="#drawable/card_bg_selected" android:state_enabled="false" android:state_selected="true"/>
</selector>
In activity_main.xml
<com.mysample.RecyclingImageView
android:id="#+id/imageview_overlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="#drawable/selector"
android:clickable="true" />
I want to create a button animation like nexus back button in below image.
When it's clicked, it's highlighted with oval shape and then bending the transparency of background color smoothly.
Approximately similar effect you can achive by selector like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:exitFadeDuration="#android:integer/config_mediumAnimTime" >
<item android:state_pressed="false" android:state_focused="true" android:drawable="#color/red" />
<item android:state_pressed="true" android:drawable="#color/dark_red" />
<item android:drawable="#color/red" />
</selector>
add this selector as bg_selector.xml in your res/draweble folder.
And then set it is as background of TextView(or other View):
android:background="#drawable/bg_selector"
P.S: All magic in android:exitFadeDuration
This is the code that I am using for my ListSelector. Originally all items have transparent background. On press, they become red. When I lift my finger, the background returns to transparent. But, I dont want it to return to transparent. How do I ensure that the color remains red even after I have lifted my finger?
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:ignore="RequiredSize,RequiredSize">
<item android:drawable="#layout/gradient_bg" android:state_pressed="false" android:state_selected="false" tools:ignore="RequiredSize"/>
<item android:drawable="#layout/gradient_bg_hover" android:state_pressed="true" tools:ignore="RequiredSize"/>
<item android:drawable="#layout/gradient_bg_hover" android:state_pressed="false" android:state_selected="true"/>
</selector>
I've created a list view and set up a selector for it so that it has a background on it. I did the same for the list item elements in it.
http://dl.dropbox.com/u/67419/list.png
The list itself is grey and has the dark grey border on the right side. When a list item is activated, I have the background of the list item changed to white via its own selector. However, I can't seem to get the white background to take up the entire space of the listview and it leaves a few pixels to the right (just enough to only show the border from the background). Is there a way to make it extend all of the way? To the right of the list is a white fragment so I want the white from the list item to connect to the white of the fragment.
my list_item_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_activated="true"
android:drawable="#color/white" />
<item android:state_selected="true"
android:drawable="#color/grey" />
<item android:state_pressed="true"
android:drawable="#color/grey" />
</selector>
and my list_selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/rightborder" />
</selector>
Have you tried: android:constantSize="true" in the selector attributes?