ListView item not changing background - android

I'm trying to change the background of a listview item when it's pressed, and despite having tried what has been mentioned in other SO posts the item refuses to change background when clicked.
What I'm I doing wrong?
EDIT: What I want to achieve:
This is how the default listview reacts when clicking an item (talking about the background change), but since I'm using custom list elements layout the list doesn't respond to clicks at all and is very dull, so I'm trying to achieve similar behaviour with the background changing whenever I click a list element.
I have this simple selector:
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:drawable="#drawable/selected_state" />
</selector>
selected_state.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/darkblue" />
</shape>
I tried setting it to the selector of the listview and making the list view single choice
Main layout:
<?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="100dp">
...
<LinearLayout
android:id="#+id/tab1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:id="#+id/listViewCentral"
android:choiceMode="singleChoice"
android:listSelector="#drawable/selector" />
</LinearLayout>
...
</RelativeLayout>
List view item:
<?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="100dp"
android:background="#drawable/selector">
...
</RelativeLayout>
And I used OnItemClick listener to set the state to selected
Main activity:
ListView list = (ListView)findViewById(R.id.listViewCentral);
list.setAdapter(stringAdapter);
list.setOnItemClickListener(new TsClickListener());
Listener:
public class TsClickListener implements AdapterView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
view.setSelected(true);
}
}
Logcat is empty (no errors)

try adding the property android:state_focused
<?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/selected_state" />
<item android:state_focused="true" android:drawable="#drawable/selected_state" />
</selector>

The problem after all was the OnItemClick event wasn't being fired at all, and the solution was to add the 'clickable' attribute to the RelativeLayout of my list view element's layout and set it to true, everything works fine then.
<?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="100dp"
android:clickable="true" <-- Problem
android:background="#drawable/selector">
...
</RelativeLayout>

Related

Adding a custom shape to selected item inside RecyclerVIew

How to show a custom shape as background behind the selected item inside a recyclerview. I've tried several things but all failed:
activity_main.xml:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/nav_drawer_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/drawer_background"
android:theme="#style/drawer"></android.support.v7.widget.RecyclerView>
</LinearLayout>
drawer_background.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/drawable_shape_selected" android:state_checked="true"></item>
<item android:drawable="#android:color/transparent"></item>
</selector>
drawable_shape_selected.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFB74D"></solid>
</shape>
custom_layout.xml:For RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="vertical">
<TextView
android:id="#+id/TextViewDisplay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello" />
</LinearLayout>
Update:
itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
Toast.makeText(context, "Position " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
});
Change your drawer_background.xml like this
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/drawable_shape_selected"
android:state_pressed="true" />
<item android:drawable="#drawable/drawable_shape_selected"
android:state_focused="true" />
<item android:drawable="#android:color/transparent" />
</selector>
Also add android:focusableInTouchMode="true" to the linear Layout of custom_layout.xml
This is because by default when the view is touched it will take click instead of focus.If you want view to be focused and change its background when pressed add this to your view i.e LinearLayout in xml.
EDIT:focusableInTouchMode makes the view touch mode for the first time disabling click.So to make button click happen for the first time add focus listener in java class for the button and onFocuschange add view.performClick() to make button takes click.
Button button = view.findViewById(R.id.buttonPanel2);
button.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean focus) {
if(focus){
view.performClick();
}
}
});

Selector for Multi Choice ListView

I can't highlight a multichoice list view with custom adapter in android. The activated and pressed state works just fine. What I want is when the user taps on an item it should be highlighted.
my new_list_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:drawable="#drawable/list_selector_pressed" />
<item android:state_activated="true" android:drawable="#drawable/list_selector_selected" />
<item android:state_selected="true" android:drawable="#drawable/list_selector_pressed" />
</selector>
in the above xml, the states for "activated" and "pressed" are working but not "selected".
In my listview_item.xml I set the background to selector as follows
<?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="48dp"
android:background="#drawable/new_list_selector">
<!--list items goes here-->
</RelativeLayout>
I define my list view like this
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/masterContainer">
<ListView
android:minWidth="25px"
android:minHeight="25px"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/friendViewList" />
</RelativeLayout>
I get the activated state when I tap and hold a list item. The pressed state works when I tap the list item. I want it to be highlighted when the user taps the item. Can someone help me out on this? Thanks for any input in advance.
PS: I prefer xml solution over coding. I have also tried selector with state_focused set to true with no luck
Do the following:
listview_item.xml
<?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="48dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/new_list_selector"/>
</RelativeLayout>
This will set the selector on ImageView. You can also do it with your two TexTviews.

Making the background color of button change and persist after a click

I have a ListFragment that contains a Button in every list item. When the Button is clicked, the colour of the Button changes (using a Drawable xml resource). Though the color of the Button changes during the click event, its color changes back to its default value after the event, i.e the color change is momentarily observable during the click and not afterwards. What I'd really like to happen is for the color change to persist after the event fires.
I have tried an approach to manipulate item views via the getView(int position, View convertView, ViewGroup parent) method of the ListFragment's custom adapter (a SimpleAdapter in my case) where I could store positions of the items and persist the background state of every Button. However I would like to replicate this solution using selectors.
I have two Drawable resources setting colours for the pressed and clicked states of each Button as well the selector resource that manages those states.
Here is my drawable resource that manipulates color states:
<?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="true"
android:drawable="#drawable/clicked_drawable" /> <!-- pressed -->
<item android:state_focused="false" android:state_pressed="false"
android:drawable="#drawable/clicked_drawable" />
<item android:drawable="#drawable/unclicked_drawable" /> <!-- default -->
</selector>
And the two resources that contain the different colours, clicked_drawable.xml & unclicked_drawable.xml, in order:
<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#F08080"
/>
</shape>
<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#FFB00F"
/>
</shape>
And the layout file for the ListFragment:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="300dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="1"
android:descendantFocusability="blocksDescendants"
android:layout_margin="5dp"
>
<ListView android:id="#id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/label"
android:gravity="start"
/>
<TextView
android:id="#+id/text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
/>
</LinearLayout>
<Button
android:id="#+id/button_1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="#string/button"
android:layout_margin="2dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:clickable="true"
android:background="#drawable/selector_drawable"
/>
</LinearLayout>
I am unable to solve this and any direction, guidance or a solution will be most appreciated.
Add the following code to your Adapter class' getView() method:
#Override
public void getView(int position, View view, ViewGroup parent){
final Button b = (Button) view.findViewById(R.id.button);
b.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
b.setBackgroundResource(R.drawable.clicked_drawable);
.....
.....
}
....
....
}
Try this. It will work.
<Button
android:id="#+id/button1"
android:background="#drawable/selector_xml_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="test" />
And make your selector like this, set all the states to the same drawable
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/button_bg_normal" android:state_selected="true"></item>
<item android:drawable="#drawable/button_bg_normal" android:state_pressed="true"></item>
<item android:drawable="#drawable/button_bg_normal"></item>
</selector>

Android's selector for selected item does not work

I have a listview, where I want to highlight selected items in a custom way. I'm setting every item properties in the adapter's getView method, including itemView.setSelected(true).
The main layout defines the listview in the following way:
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="multipleChoice"
android:listSelector="#drawable/list_selector" />
(Playing with choice mode does not help either).
The list_selector is an almost empty stub:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#android:color/transparent" />
</selector>
I don't need specific styles for listview as a whole, so I'd leave a default one, but according to this answer, we need a selector for a listview for item selector to work. Anyway, without the list_selector the problem remains.
The listview item layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:background="#drawable/listitem_background"
android:orientation="vertical">
and it references the following listitem_background selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="#android:color/white" />
<item android:drawable="#android:color/transparent" />
</selector>
The problem is, that selected items do not have white background.
If I change android:state_selected="true" selector in the listitem_background to, for example, android:state_pressed="true", then the selector starts to work, that is item background becomes white if an item is touched.
So, I suppose, there is an error either in the selectors, or in the way how I select items.
I can write a workaround by setting background from Java or utilizing checkable states, but I want to understand and fix current problem with selectors. Thanks in advance.
What about adding this line in your item view?
android:background="?android:attr/activatedBackgroundIndicator"
For instance:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/activatedBackgroundIndicator"
android:orientation="vertical" >
<TextView
android:id="#+id/textViewListRowOption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical" />
</LinearLayout>
Then the selector looks something like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:exitFadeDuration="#android:integer/config_mediumAnimTime">
<item android:drawable="#drawable/list_pressed" android:state_pressed="true"/>
<item android:drawable="#drawable/list_selected" android:state_activated="true"/>
<item android:drawable="#drawable/list_default"/>
</selector>
And the list view:
<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="#+id/listViewMainFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:listSelector="#drawable/list_item_selector"
android:choiceMode="singleChoice">
</ListView>
</LinearLayout>
Try this one to change the selected list item.Put it inside the list view.
if (currentSelectedView != null && currentSelectedView != v) {
unhighlightCurrentRow(currentSelectedView);
}
currentSelectedView = v;
highlightCurrentRow(currentSelectedView);
private void unhighlightCurrentRow(View rowView) {
rowView.setBackgroundColor(Color.TRANSPARENT);//to set a color for un-seclected row
}
private void highlightCurrentRow(View rowView) {
rowView.setBackgroundResource(R.drawable.selector_img);//to set a color for seclected row
}

Changing color of custom listview item on focus

I have created a custom list and managed to change the colors of the child items in normal and clicked view. But When I apply it to the focus view, then nothing happens and the default background color only gets displayed with the changed color of the text from white to black. Here are the xml files that I am using for what I have done so far.
Layout for listview (listview.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:orientation="horizontal" android:padding="18sp"
android:background="#drawable/backgroundselector">
<ImageView android:id="#+id/imageView1"
android:layout_height="fill_parent" android:layout_gravity="center_vertical"
android:layout_width="wrap_content" />
<TextView android:text="TextView" android:id="#+id/textView1"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:paddingLeft="10sp" android:textSize="20sp" />
</LinearLayout>
clicked.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#ffc61212" />
</shape>
focussed.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#ff26e0d7" />
</shape>
normal.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#ff0a4d66" />
</shape>
and finally backgroundselector.xml
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="#drawable/focussed" /> <!-- focused -->
<item android:state_pressed="true" android:drawable="#drawable/clicked" /> <!-- pressed -->
<item android:drawable="#drawable/normal" /> <!-- default -->
</selector>
Please I need help on how can I change the color of the child item of my list view when a child item is focussed...
My advice is to override ListView.onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) method, which will be called when an item is clicked.
And in this method, you can create a new ArrayAdapter. Like this:
ArrayAdapter<String> adpater=new ArrayAdapter<String>(CurrentActivity.this,R.layout.foucs,data); where data is an object array used to provide data for the ListView(generally, we use String[] or ArrayList class).
And then, call ListView.setAdapter(adapter) to show your new style.
Hope it helps. I am a greedhand:)
Ah, I find a new and convenient way to do this.
In ListView.onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) method,
just call arg1.setBackgroundColor(newColor); to change the color of the item.

Categories

Resources