Android - ListView Item not changing its state - android

I'm currently facing a problem with background drawables on ListView Items.
I have a ListView XML, an Item XML, and a Drawable XML for the differents states that one item can have.
The problem is that when I click or press one of the item nothing changes visually, but the click works because the onItemClick() method I overrided is called and its code executed... Its like I didn't set the #background parameter !
layout/my_activity.xml (which contains the listview) :
<?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="match_parent"
android:background="#drawable/background"
android:orientation="vertical" >
<include ... />
<include ... />
<View
... />
<ListView
android:id="#+id/listViewPacks"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="#color/blue_vdark"
android:dividerHeight="2dp" >
</ListView>
</LinearLayout>
layout/listview_item_a.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="wrap_content"
android:background="#drawable/listview_item_a_d"
android:orientation="vertical"
android:padding="5dp" >
<TextView
... />
<TextView
... />
<TextView
... />
</LinearLayout>
drawable/listview_item_a_d.xml :
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"><shape>
<gradient android:angle="270" android:endColor="#bbbbbb" android:startColor="#e9e9e3" />
</shape></item>
<item android:state_enabled="true"><shape>
<gradient android:angle="270" android:endColor="#ecca2e" android:startColor="#f9f7c9" />
</shape></item>
<item><shape>
<solid android:color="#color/gray_dark" />
</shape></item>
</selector>

First, there is no persistent selected or focused state in touchmode.
You can get around this by using state_activated.
You can achieve this by setting the choice mode for the list to single or multiple (the default is none).
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
Then use the activated state in your selector XML:
<item android:state_activated="true">
<shape>
<gradient android:angle="270" android:endColor="#bbbbbb" droid:startColor="#e9e9e3" />
</shape>
</item>
Note that state_activated is for API 11+... for previous versions I believe you would have to go with an array in a custom adapter to keep track of the selected state and use that to set the background color/drawable in your adapter getView method.

I have an adapter with my ListView and the problem was I changed my views' background in the getView method so I think the selector was drawn behind, or maybe not drawn at all. Anyway I just removed those lines of code and now it works fine, thanks !

Related

how to show divider line in autocompleteTextview? [duplicate]

I've seen this question asked some other times on the site, but no one couldn't get any answer.
Is there any way to customize the appearance of the divider in the dropdown showing when using an AutocompleteTextview in android?
It's pretty easy for a ListView, but using only an ArrayAdapter for the autocompletetextview, is there any way to customize the divider.
(Not the textview, I already know doing that)
Im not sure how you can do it for single AutoCompleteTextView but I know how to set it for the whole application. This should also help you :)
<style name="MyTheme" parent="AppTheme">
<item name="android:dropDownListViewStyle">#style/MyListViewStyle</item>
</style>
<style name="MyListViewStyle" parent="#android:style/Widget.ListView">
<item name="android:divider">#F00</item>
<item name="android:dividerHeight">1px</item>
</style>
I didnt find any divider properties so I did this
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/black">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/textView129"
android:textColor="#000000"
android:background="#color/white"
android:layout_marginBottom="1dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"/>
</LinearLayout>
So wat im doing is I have a background color for the Linear layout and another background color for the text View (textView's background color overlaps the linear layout's background color) now using the margin property and setting the bottom margin of textview to 1dp u'll get a clean line between elements....
I had faced same problem and try many ways but not achieve result, at last i got a quick and easy way to set divider and divider lenght with AutocompleteTextview. Basically we can set a border from bottom side with TextView of ArrayAdapter Layout. Like as
step1. Make a layout for arrayadapetr like as
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/testt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/background_single_line"
android:textColor="#drawable/text_color"
android:textAppearance="?android:attr/textAppearanceMediumInverse"
style="?android:attr/dropDownItemStyle"
android:maxLines="1"
android:padding="3dp"
android:textSize="16sp" />
step2: in drawable folder create new layout its name background_single_line.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#android:color/black" />
</shape>
</item>
<item android:bottom="1dp">
<shape android:shape="rectangle">
<solid android:color="#android:color/white" />
</shape>
</item>
Finally looks as divider .
The answer from Mark is normally the best solution. However different versions of the AppCompat library have different behavior, regarding how android:dropDownListViewStyle affects other menus, like the system overflow/options menu. For example, in AppCompat version 23.0.1, it will not affect this menu in the ActionBar/Toolbar; whereas version 23.2.1 it will affect it, as explained here.
If you want a style that is isolated to only affect the AutoCompleteTextView, it may not be possible. But an alternative way is to create the list divider image manually, as part of the layout of the dropdown list row:
res/layout/autocomplete_list_row.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
tools:layout_height="50dip">
<TextView
android:id="#+id/text"
style="?android:attr/dropDownItemStyle"
android:textSize="18sp"
android:layout_width="fill_parent"
tools:text="An auto-complete list item"
android:minHeight="48dip"
android:layout_height="wrap_content"
android:ellipsize="marquee"/>
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:background="#drawable/divider"/>
</LinearLayout>
res/drawable/divider.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:height="1dp" />
<solid android:color="#458c8c8c" />
</shape>
Then use this layout in your adapter for the AutoCompleteTextView:
ArrayAdapter<CharSequence> autoCompleteListAdapter =
new ArrayAdapter<>(context,
R.layout.autocomplete_list_row,
R.id.text, arrayList);
Similar approach using ConstraintLayout here.

Using a custom template for actionbar menu item

I am trying to display a menu with text and icon always visible. I have defined my item layout as following
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:drawableLeft="#drawable/ic_cart"
android:gravity="center"
android:orientation="vertical"
android:text="(0)"
android:drawablePadding="5dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:textColor="#android:color/white" />
And the menu is defined as following
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.taptoscan.taptoscan.MainActivity">
<item
android:id="#+id/action_sign"
android:title="(0)"
app:showAsAction="always|withText"
app:actionLayout="#layout/menu_sign" />
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never" />
</menu>
I'm having an issue with enabling the ripple effect on the background. It works but the ripple effect is not rounded, lik on a regular menu icon. It's square shaped and looks kinda ugly. What would be the best way to achieve the native ripple effect look on a custom menu item?
EDIT: This is what it looks like
NOTE: Better solution found, check the edit
I figured it out. First I created a background drawable with rounded corners, like this:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:colorControlHighlight">
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<padding
android:bottom="5dp"
android:left="5dp"
android:right="5dp"
android:top="5dp" />
<corners android:radius="5dp" />
</shape>
</ripple>
After that, I set the TextView's background as the drawable from above. Ripple effect works as intended and it's all rounded like on default menu items.
EDIT
After further messing around with the custom menu item, I have found out that just by using a TextView without a root element will cause TextView's baseline to be changed after clicking on another menu item and then clicking back on the custom one. The solution is using the following layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:background="#drawable/btn_actionbar_icon">
<TextView
android:id="#+id/icon_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="#drawable/ic_cart"
android:drawablePadding="5dp"
android:gravity="center_vertical"
android:padding="10dp"
android:text="(0)"
android:textColor="#android:color/white"
android:textSize="14sp" />
</RelativeLayout>

How to make a ripple effect over a linear layout, without overriding the background color on its children?

I have a LinearLayout that looks like this.
I want each row to be clickable. The LinearLayout code for a row looks like this:
<LinearLayout
style="#style/home_menu_item_container"
android:id="#+id/home_menu_acronyms_button"
>
<ImageView
style="#style/home_menu_item_left"
android:background="#color/greyLight"
/>
<TextView
style="#style/home_menu_item_right"
android:text="#string/home_menu_option_2"
android:background="#color/grey"
/>
</LinearLayout>
How can I add a ripple effect that expands over the entire row (parent) - not just one child view in the row? The tricky part here is to let the ripple go over the two colored row.
So far, I found out the easiest way to do so is define a <ripple> in your drawable and then set the background of the LinearLayout to this drawable resource.
Define your drawable-v21/item_selector.xml
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/your_background_color">
<item android:id="#android:id/mask"
<!--color here doesn't matter-->
android:drawable="#android:color/white" />
</ripple>
Set the background of your LinearLayout to drawable/item_selector.
<LinearLayout
style="#style/home_menu_item_container"
android:background="#drawable/item_selector"
android:id="#+id/home_menu_acronyms_button" >
...
</LinearLayout>
Besides, if you don't have your own background color, then there is no need to define a item_selector at all. You can simply define background as android:background="?android:attr/selectableItemBackground" for your LinearLayout.
It is a little bit complicated for that what you need but I don't think there is another way,...
You need to put your ImageView's into a ListView so that every ImageView is a ListItem and then you can set the ripple but you also need to set drawSelectorOnTop="true" otherwise it won't work correctly
I too faced this problem, finally found a simple solution
In linear Layout just add android:clickable="true";
and set background with ur ripple effect as
android:background="#drawable/ripple_effect"
code:
<LinearLayout
android:clickable="true"
android:background="#drawable/ripple_effect"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Add your child views here -->
</LinearLayout>
add ripple_effect.xml in drawable
ripple_effect.xml:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#f87d05c2"
tools:targetApi="lollipop">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#f87d05c2" />
</shape>
</item>
</ripple>
<RelativeLayout
android:id="#+id/rll_privacy_policy"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?android:attr/selectableItemBackground"
android:orientation="vertical">
<TextView
android:id="#+id/txt_privacy_policy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/layout_margin_16"
android:text="#string/privacy_policy"
android:layout_centerVertical="true"
android:textColor="#color/link_acc"
android:textSize="#dimen/txt_title_20" />
</RelativeLayout>
Another option is to make the ripple's background color transparent. This way only the ripple can be seen. The ripple's xml file (in your drawable-v21/ folder) is thus:
<-- Ripple in some ghastly color, like bright red so you can see it -->
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/red"
>
<!-- background color uses a transparent mask set to full #ffffff (white) -->
<item
android:id="#android:id/mask"
android:drawable="#android:color/white"
/>
Note that if you are supporting pre-lollipop devices, you need to have a dummy file with the same name in your drawable/ folder. An empty selector is sufficient for that file. And remember that those older devices will not ripple.
answer above dont work for me,
here is my solution:
ripple.xml:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:colorControlHighlight">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="?android:colorAccent" />
</shape>
</item>
</ripple>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
>
...put het your design
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/ripple" />
</FrameLayout>

How to add border to the bottom of list item in listview

I have a list view and I want to add a bottom border to each list item so it acts as a separating line between all the cells.
This is my list view right now.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:descendantFocusability="blocksDescendants"
android:background="#FFFFFF"
>
....
.....
</LinearLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#color/red"
android:dividerHeight="1px">
</ListView>
and color value is inside colors.xml or strings.xml:
<color name="red">#FF0000</color>
P.S. I am using px on purpose check here
Create a drawable like this , and set it to the list item background. This will set border only for layout bottom.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="-1dp" android:right="-1dp" android:left="-1dp">
<shape >
<stroke
android:width="1dp"
android:color="#FFFF" />
</shape>
</item>
</layer-list>
or you can also try to set a divider for ListView
android:divider="#FFFF"
android:dividerHeight="1dp"

ListView item ListSelector drawable flickering

I have a custom drawable for my listSelection. When I select one Item it gets selected. But on selected when I scroll through the other items (scrolling up/down) the backgroung is flickering and sometimes it is also getting disappeared.
I am including my xml layouts:
ListView:
<ListView
android:id="#id/listView"
android:layout_width="100dp"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:listSelector="#drawable/list_selector"
android:clickable="true"
android:divider="#drawable/separetor_drawable"
android:fastScrollEnabled="true"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:scrollbars="none" >
</ListView>
drawable layout: list_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners android:radius="6dp" />
<solid android:color="#color/grey" />
<size android:width="50dp" />
</shape>
Also I even I specify shape width the shape automatically fill_parent and that goes for height as well.
Any suggestions?
//try in your listview attribute as
android:cacheColorHint = "#00000000"
or
android:cacheColorHint="#android:color/transparent"
at java code, you should use
listView.setCacheColorHint(Color.TRANSPARENT);
Try this in your listview:
android:listSelector="#android:color/transparent"
android:cacheColorHint="#00000000"
android:focusable="false"
android:focusableInTouchMode="false"
Don't know if you got your answer, but we had a similar problem at one point. We fixed it by setting a background on the outer element in our listitem's layout file:
listitem.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/listselector"
...>
....
</RelativeLayout>
and then the drawable.. listselector.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="#color/blue" />
<item android:state_selected="true" android:state_pressed="false" android:drawable="#color/yellow" />
<item android:state_selected="false" android:state_pressed="false" android:drawable="#color/black" />
</selector>
The background xml file sets values for pressed, selected, and normal states and you can change the colors to other drawable's if you wish. Seemed to fix the weird background flicker problem we were having.

Categories

Resources