Enable selection inside ListView - android

The following problem is driving me crazy. I've defined an xml fragment, using this code:
<fragment class="host.helperclass.ServiceListFragment"
android:id="#+id/titles"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_width="0px"/>
Then I've implemented ServiceListFragment class which extends SherlockListFragment.
I've overridden the onActivityCreated method, with this code:
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
getListView().setDividerHeight(2);
getListView().setBackgroundColor(Color.parseColor("#EEEEEE"));
getListView().setCacheColorHint(Color.parseColor("#00000000"));
getListView().setSelector(R.drawable.list_selector);
Where list_selector.xml is very simple:
<?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/green"/>
<item android:state_focused="true"
android:drawable="#drawable/green"/>
<item android:state_selected="true"
android:drawable="#drawable/green"/>
</selector>
But the green background for an item is added only when I press the button. When I release it the green background is removed. It seems like the state_selected is not recognized.
Is this possible? If so, is there any way for enable the selection of items inside ListView?
NOTE:
I've also tried to use a selctor with only one item:
<item android:state_focused="true"
android:drawable="#drawable/green" />
And as result I obtaint that, when I press the ListView item the background become green, but when I release it the green background is removed. It seems that my item lost focus when I pull off my finger from item.
EDIT:
I have made another attempt.
I've added inside the onListItemClick method this line of code:
getListView().setItemChecked(index, true);
and in my xml selector I have put only this item:
<item android:state_checked="true"
android:drawable="#drawable/green" />
But strangely this does not work.

I believe the correct state for single choice mode is android:state_activated.
I noticed you are using the selector for the list.
You should use it as the background of the list row (the one you use in the adapter).
For example:
row_background.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/green"/>
</selector>
row_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/row_background">
<!-- your views -->
</LinearLayout>

Try this.
Add this item to selector
<item android:state_selected="true"
android:state_pressed="false"
android:drawable="#drawable/green" />
and remove
<item android:state_selected="true"
android:drawable="#drawable/green"/>

I found the problem.
Defining the xml layout for the row used in the custom adapter, I needed to add this row, to the root element:
android:background="?android:attr/activatedBackgroundIndicator"
But, the attribute activatedBackgroundIndicator has been introduced since API level 11, so I have put the previous version of my xml in layout folder, and the new one in the layout-v11 folder.
Also the following statement is required, inside the onListItemClick method:
getListView().setItemChecked(position, true);

Related

How can I change default background color of a selected ListView item in Android?

I want to change the default color (blue) of a selected item in a Navigation Drawer in Android. I have gotten it to work in past projects, but I cannot in the project I am currently working on.
This is the app theme.
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="android:actionBarStyle">#style/AppTheme.ActionBar</item>
<item name="android:activatedBackgroundIndicator">#drawable/activated_background</item>
<item name="android:buttonStyle">#style/AppTheme.Button</item>
</style>
This is the activated_background drawable.
<?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/list_selected"/>
<item android:state_selected="true" android:drawable="#drawable/list_selected"/>
<item android:state_pressed="true" android:drawable="#drawable/list_selected"/>
</selector>
Finally, this is the navigation drawer fragment.
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#cccc"
tools:context=".NavigationDrawerFragment" />
Like I said, this has worked for me before. The only difference between projects that I can think of is that before, my app theme was inherited from "Theme.AppCompat" and this project's theme is inherited from "android:Theme.Holo.Light.DarkActionBar". Also, I am using v4 support fragments in my new project, while as in the other project I was just using the standard fragment.
Any advice would be greatly appreciated. Thanks.
Edit:
Seems like the question is how to keep an item in a ListView selected, not actually how to set the resulting background of a selected item.
See this great answer for how change the background of a ListView item once it is selected:
Android - Keep ListView's item highlighted once one has been clicked
The basic idea is that when the item is tapped, you change it's background (or whatever else). The tricky part is you must have your List adapter remember the row that is selected. Otherwise when/if you scroll the list/navigation drawer, you'll lose the selection.
Original Answer:
You need to set a custom ListView style in AppTheme in which you set the android:listSelector item to #drawable/activated_background.
If you don't want that style for your entire app, just specify that style for the ListView in your application drawer layout, or even more simply just set the android:listSelector property of that ListView and don't even bother defining a style.
I figured it out. Instead of using my theme to try and apply the style, I just created my own xml layout for the list items instead of using the default and set the selector from there.
Here is what the list item xml looks like.
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:textColor="#drawable/list_txtcolor"
android:gravity="center_vertical"
android:paddingStart="?android:listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="#drawable/activated_background"
android:minHeight="?android:attr/listPreferredItemHeightSmall">
</TextView>
As you can see, I just set the item background to my selector.
android:background="#drawable/activated_background"
And again, here is my selector.
<?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/list_selected"/>
<item android:state_selected="true" android:drawable="#drawable/list_selected"/>
<item android:state_pressed="true" android:drawable="#drawable/list_selected"/>
</selector>

Android: Set TextView color on click like in the ListView

I have some textViews in my LinearLayout.
They are clickable and I would like to make them onClick like for a ListView.
For the listView, when the user clicks an item, the background becomes green I think.
I know that i can do this manually with
tv.SetBackgroundColor(Color.GREEN);
But is there something automaticaly to do this, like for the listView where the selection is managed automaticaly.
Thank you.
You need to define the background as a new XML file containing a list of states.
http://developer.android.com/guide/topics/resources/color-list-resource.html
For example, create a file called background_states.xml in your drawable folder and write something like this:
<?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/white" ></item>
<item
android:state_pressed="true"
android:drawable="#color/white" ></item>
<item
android:drawable="#color/black" />
</selector>
Then define this new file as background in your TextView:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/background_states"
See the link above for more information about the different states.

Drawable with selector?

in drawable folder:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#drawable/icon2" />
<item android:drawable="#drawable/icon3" />
</selector>
and the layout is just simple linear layout that fill the whole space
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#drawable/on_touch_"
android:weightSum="1" android:focusable="true" android:focusableInTouchMode="true">
</LinearLayout>
and when I press this nothing happens
If I add, for example, some textview and assign android:background="#drawable/on_touch_" then that textview when pressed it changes the image correctly.
Where is the problem with the linear layout why it does not change the image when pressed ?
Edit:
I am sure that my drawable selector is good and working cause I put as a background to other elements and it is working.
But my problem is how to set the drawable to the root element
Add this to your layout :
android:clickable="true"
This will set the pressed state when you'll click it.
try out
save_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_pressed="false"
android:drawable="#drawable/save_hover_new" />
<item android:state_focused="true" android:state_pressed="true"
android:drawable="#drawable/save_hover_new" />
<item android:state_focused="false" android:state_pressed="true"
android:drawable="#drawable/save_hover_new" />
<item android:drawable="#drawable/save_new" />
</selector>
and give layout's background as selector like
android:background="#drawable/save_selector
I would make sure I do not have a drawable namesake. You seem to be using on_touch_.xml as your selector. Is there perhaps also an on_touch_.png?
I would also make sure that I am not setting the background again, to something else, or making it unclickable, in code.
I got a selector in a root element that is working fine; the background switches when pressed. It is not the root element of the activity layout, but it is the root element of the XML file.
The background is assigned with a png at first:
<?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:orientation="horizontal"
android:background="#drawable/panel"
>
...
I assign the background to the selector only when assigning an OnClickListener:
private void setClickListener(OnClickListener ocl) {
View boxRoot = findViewById(R.id.box_root);
if (ocl != null) {
boxRoot.setOnClickListener(ocl);
boxRoot.setBackgroundDrawable(getResources().getDrawable(R.drawable.panel_arrow_right_bgstate));
setClickable(true);
...
In my XML, I used android:clickable="true" but then I also added android:focusable="true" android:focusableInTouchMode="true" to match your case. That also worked fine, with background switching for all my four states.
// panel_arrow_right_bgstate.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="false" android:state_pressed="false" android:drawable="#drawable/panel_arrow_right_normal"/>
<item android:state_focused="false" android:state_pressed="true" android:drawable="#drawable/panel_arrow_right_pressed"/>
<item android:state_focused="true" android:state_pressed="false" android:drawable="#drawable/panel_arrow_right_selected"/>
<item android:state_focused="true" android:state_pressed="true" android:drawable="#drawable/panel_arrow_right_pressed"/>
If this is not working for you, something else is wrong with your code, somewhere else.
When I add or remove drawables, Eclipse sometimes gets fishy and mix them up. My normal measurements are:
Clean project
Refresh res folder in Eclipse
Delete gen\com.comp.proj\R.java

how to change font color in selected/focused ListView items?

I am struggling with this which apparently is a very simple effect but incredibly haven't found any intutitive way for doing it in Android.
I have a ListView and I managed to customize the background images so the selected item gets highlighted by getting a new background drawable. This I do creating a new style where I set the android:listSelector attribute to point a StateListDrawable where I have specified which drawables to use for every state.
However each ListView item is a LinearLayout where i have two TextViews. My goal is to be able to change the text color of these child views whenever the parent is selected or pressed, at the same time as the background drawable does. I know there is a ColorStateList but haven't been succesful setting that up.
Has anybody succeed getting something like this to work?
Thanks.
Neither of these are possible answers when your ListView is compromised of a layout that has multiple views. You need to set your child views to:
android:duplicateParentState="true"
Now you can use the methods others have described above to declare your TextViews' colors using a selector such as:
android:textColor="#drawable/my_row_selector"
and I'm sure you're aware, but the selector can be as simple as:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#color/white" />
<item android:color="#color/black" />
</selector>
As you can see, #color values are allowed. Hope this helps.
Also - android:state_pressed is used in conjunction with the AdapterView.OnItemClickListener.
in your textview propeties
android:textColor="#color/text_selector"
in res/color
text_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:color="YOUR_CUSTOM_COLOR" />
<item android:state_selected="true" android:color="YOUR_CUSTOM_COLOR" />
<item android:color="YOUR_CUSTOM_COLOR" />
</selector>
In order to make it work on selection use the following code:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#fff"/>
<item android:state_activated="true" android:color="#fff"/>
<item android:color="#000" />
</selector>
Apparently the key is state_activated="true" state.
When you are deploying the app for Android 11+ (HoneyComb+), you should use
android:state_activated="true"
for selected list state.
For the earlier versions use the combination of:
android:state_checked="true"
android:state_activated="true"
Of course don't forget to include the
android:duplicateParentState="true"
so the view can get the activated/checked state from a parent list view item
Also you may create a res/color folder and add a file "text_selector.xml" with the following lines:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true" android:color="#f0f"/>
<item android:state_pressed="true" android:color="#f0f"/>
<item android:color="#000"/>
</selector>
After that assign in TextView:
android:textColor="#color/text_selector"

Android Selector Problem

i have a listview with a custom item_row.xml. I've defined a selector in this way:
<?xml version="1.0" encoding="utf-8"?>
<item
android:state_pressed="false"
android:drawable="#drawable/list_bg" >
</item>
<item
android:state_pressed="true"
android:drawable="#drawable/header_bg" >
</item>
<item
android:state_focused="false"
android:drawable="#drawable/list_bg" >
</item>
<item
android:state_focused="true"
android:drawable="#drawable/header_bg">
</item>
and then put into item_row.xml in this way:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="70dip"
android:orientation="vertical"
android:background="#drawable/list_selector">
I want 2 things:
When i move with arrow keys, the item selected changed its background. It's works fine with the actual implementation of selector.
When i press a item, the item changed its background too, but it doesn't work with the actual selector.
Any idea? I try to set also into the ListView android:listSelector="#drawable/list_selector"
but it doesn't work neither.
Thanks
You should model your StateListDrawable after the one used by Android itself for ListView selectors. You can find this in $ANDROID_HOME/platforms/$VERSION/data/res/drawable/list_selector_background.xml, where $ANDROID_HOME is where your Android SDK is installed and $VERSION is some Android version (e.g., android-2.1). Then, apply the list selector via android:listSelector in the ListView in your layout XML.

Categories

Resources