I seem to be having a UI problem with a listview. I have a listview and selecting any item on the list, highlights the entire listview. The selection is working fine, I get the correct item in the listener.
But the problem is that when i select any item, the entire listview gets highlighted, so it is difficult to tell which row got selected.
This is working fine on Android >3.1 - Currently i am testing on a 2.3 device.
<ListView
android:id="#+id/myList"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_marginTop="#dimen/margin_medium"
android:background="#drawable/border"
android:listSelector="#99000000"
android:scrollbarFadeDuration="1000000"
android:scrollbars="vertical" >
</ListView>
I recently had the same issue, but the reason was in Android < 3.0 bug: if you set a #color as a drawable for your list item pressed selector, then it will fill the entire list area. Solution is to use a 'shape' drawable instead of #color.
So, create a new XML file in res/drawable folder with similar content:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#color/my_list_item_pressed_color" />
</shape>
And reference created drawable in your ListView selector for state_pressed (also created as an XML file in res/drawable folder):
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="#drawable/list_item_pressed_bg" />
<item android:drawable="#android:color/transparent" />
</selector>
And use this selector in your ListView:
<ListView
.....
android:listSelector="#drawable/list_item_selector" />
That's all. Works at least with Android 2.2-2.3.
If you don't want to change your selector, you can also set it as the background of the list item's layout, rather than in the listSelector field of the ListView. The list items receive the "selected" state when touched and the color is displayed properly.
This works for all versions of Android.
Ex: This is your list item layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/background_color">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Your text here" />
</LinearLayout>
And your list with no list selector:
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
I fixed this by removing this line: (not sure why it worked)
android:listSelector="#99000000"
Related
I am trying to add Ripple Effect to RecyclerView's item. I had a look online, but could not find what I need. I assume it has to be a custom effect. I have tried android:background attribute to the RecyclerView itself and set it to "?android:selectableItemBackground" but it did not work.:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:clickable="true"
android:background="?android:selectableItemBackground"
android:id="#+id/recyclerView"
android:layout_below="#+id/tool_bar"/>
This is the RecyclerView that I am trying to add the effect to:
I figured out. The only thing that I had to do is to add this attribute:
android:background="?android:attr/selectableItemBackground"
to the root element of the layout that my RecyclerView adapter inflates like that:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:background="?android:attr/selectableItemBackground"
tools:background="#drawable/bg_gradient">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="17sp"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:id="#+id/shoppingListItem"
android:hint="#string/enter_item_hint"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/shopping_list_item_checkbox_label"
android:id="#+id/shoppingListCheckBox"
android:layout_centerVertical="true"
android:layout_marginRight="15dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:checked="false"/>
</RelativeLayout>
Result:
If you are still not able to see ripple effect, add these lines also to the root element of the layout.
android:clickable="true"
android:focusable="true"
As already answered, the simplest solution is to just add one of the following as your RecyclerView row's background:
android:background="?android:attr/selectableItemBackground"
android:background="?attr/selectableItemBackground"
However if you are experiencing problems with this method or if you want finer control over the colors, then you can do the following.
Custom Ripple Effect
This answer is starting with this simple Android RecyclerView example. It will look like the following image.
Add selector for pre API 21 devices
Before API 21 (Android 5.0 Lollipop), clicking a RecyclerView item just changed its background color (no ripple effect). That is what we are going to do, too. If you still have users with those devices, they are used to that behavior, so we aren't going to worry about them too much. (Of course, if you really want the ripple effect for them, too, you could use a custom library.)
Right click your res/drawable folder and choose New > Drawable resource file. Call it custom_ripple. Click OK and paste in the following code.
custom_ripple.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#color/colorAccent" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="#android:color/transparent" />
</shape>
</item>
</selector>
I used colorAccent as the highlight color for the pressed state because it was already available, but you can define whatever color you want.
Add Ripple Effect for API 21+ devices
Right click your res/drawable folder and choose New > Drawable resource file. Call it custom_ripple again. Don't click OK, yet this time, though. From the Available qualifiers list choose Version, then click the >> button and write 21 for the Platform API level. Now click OK and paste in the following code.
v21/custom_ripple.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/colorAccent">
<item
android:id="#android:id/mask"
android:drawable="#android:color/white" />
</ripple>
Again, I used colorAccent for the ripple color because it was available, but you can use whatever color you want. The mask confines the ripple effect to just the row layout. The mask color apparently doesn't matter so I just used an opaque white.
Set as the background
In your RecyclerView item's root layout, set the background to the custom ripple that we created.
android:background="#drawable/custom_ripple"
In the example project that we started with, it looks like this:
<?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="wrap_content"
android:orientation="horizontal"
android:background="#drawable/custom_ripple"
android:padding="10dp">
<TextView
android:id="#+id/tvAnimalName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"/>
</LinearLayout>
Finished
That's it. You should be able to run your project now. Thanks to this answer and this YouTube video for help.
I think there is one small detail that is missed.
If you still do not get the ripple effect after adding android:background="?android:attr/selectableItemBackground" try adding these following lines in the root of the layout.
android:clickable="true"
android:focusable="true"
These will make sure that the view is clickable and will enable the ripple effect with the background attribute mentioned above
add this lines in your adapter xml root view
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
A simple and custom approach is to set a view theme as outlined here.
some_view.xml
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:focusable="true"
android:src="#drawable/up_arrow"
android:theme="#style/SomeButtonTheme"/>
some_style.xml
<style name="SomeButtonTheme" >
<item name="colorControlHighlight">#color/someColor</item>
</style>
Other custom implementations may be found here.
Using a Button Style
This has worked for me countlessly.
Add the Borderless Button Style to the root element of your layout.
There's no need for focusable or clickable attributes, the default styling encapsulates all that for you.
<androidx.constraintlayout.widget.ConstraintLayout
style="#android:style/Widget.Material.Button.Borderless"
android:layout_width="match_parent"
android:layout_height="wrap_content">
I'm using HoloEveryWhere to get support of the Holo themes on android 2.x and I want to change the default color of my ListView dividers.
I did this :
<ListView
android:id="#+id/listRecherche"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_width="wrap_content"
android:divider="#e5e5e5"
android:dividerHeight="1dp"
android:layout_height="wrap_content" >
</ListView>
It works well on android 4.x but in 2.x, what I get is no more dividers and instead a #e5e5e5 background on the whole ListView.
I've thought about a height problem since I know that changing the dividers color resets the dividers height. This is why I've set heights at the end... but no effect.
Use a drawable instead of an RGB color Just put a file named divider.xml in res/drawable/ so you can access it as R.drawable.divider; if you can access it that way, then you can use android:divider="#drawable/divider" in the XML for ListView.
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="schemas.android.com/apk/res/android">
<gradient
android:startColor="#ffcdcdcd"
android:endColor="#ffcdcdcd"
android:angle="270.0" />
And in styles.xml for listview item
<item name="android:divider">#drawable/divider</item>
<item name="android:dividerHeight">1px</item>
I am using ListView inside a ViewFlipper as follows:
<ViewFlipper
android:id="#+Category/viewFlipper"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:entries="#array/options"
android:cacheColorHint="#FFFFFF"
android:background="#FFFFFF"/>
</ViewFlipper>
I want to change the background color of the ListView.
I have only 5 items in the options array and they do not fill the screen. So, the remaining part of the listView appears in the default grey color. I want to change this default color. I read about cacheColorHint attribute in questions posted by others related to this. But it did not work out. Can anyone please help me with this?
Thanks in advance
You should use layout_height="wrap_content" (and layout_width="wrap_content" also if need) for your ListView and change the "default grey color" like you said by set the background for ViewFlipper.
Set a selector as the background of your ListView:
ListView mylw = findViewById(R.id.mylistView);
//Do not use reserved android or java identifiers as your id or variable!
mylw.setBackgroundResource(R.drawable.thexmlbelow);
Drawable:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false" android:drawable="Background Color" />
<item android:drawable="Background Color when pressed" />
</selector>
I created a custom layout (using LayoutInflator) for list items. Here are the relevant files:
my_list.xml - the main activity which has the ListView
<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:listSelector="#drawable/listitem_selector"
>
</ListView>
list_item.xml - references drawable .png for background
android:background="#drawable/list_item_bg"
listitem_selector.xml
<selector>
<item android:state_focused="false" android:drawable="#drawable/list_item_bg" />
<item android:state_pressed="true"
android:drawable="#drawable/list_item_pressed_bg" />
<item android:state_focused="true"
android:drawable="#drawable/list_item_pressed_bg" />
</selector>
If I don't use the listitem_selector.xml to override the default state styles, I get the ugly default Android green/orange colors, but otherwise the layout looks fine. When I use the listitem_selector.xml, it adds extra space at the top of each list item. (if I use smaller images, it still adds space)
here's a screenshot: [edit - not screenshots allowed.]
How can I override the default list item state styling without adding the weird space?
p.s. - I referenced this very helpful post to get where I got.
I want to change the color of child divider of ExpandableListView by writing:
android:childDivider="#drawable/yellow"
in layout file. However, when I collapse the item, I found the background of the ExpandableListView turn yellow (#drawable/yellow) , but I just want to change the color of child divider. Who can tell me why? To my surprise, if I change it by java code like
expandableListView.setChildDivider(this.getResources().getDrawable(R.drawable.yellow));
it works normally. It is very weird, who can tell me the reason?
<!-- if I set childDivider in Layout xml, it can't work normally.
However, if set childDivider in java code, it work normally -->
<ExpandableListView android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:dividerHeight="2dp"
android:divider="#drawable/yellow"
android:childDivider="#drawable/yellow"
/>
create a drawable with small height and set it to childDivider
property
"child_separator.xml":
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#color/child_separator_color"/>
<size android:height="1dp"/>
</shape>
expandable list view:
android:childDivider="#drawable/child_separator"
Simply set child divider as the color of your choice.
<ExpandableListView
android:id="#+id/list_shopping"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:childDivider="#color/LightGrey"
android:dividerHeight="1dp" />
You just need to remove android:divider="#drawable/yellow" from your layout. This should resolve your problem if I understood it correctly.
Here is what I mean: