duplicateParentState stops working when ImageButton is added - android

I've got a ListView with a custom Adapter inheriting from ArrayAdapter. I'm using a custom Checkable subclass of LinearLayout to highlight the last selected item in the list where it basically maps the checked state to selected.
The layout used by the Adapter for list items is as follows:
<com.wordlistdictionary.CheckableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="40dp">
<LinearLayout
android:id="#+id/entry_text"
android:layout_width="0dp"
android:layout_weight="7"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:duplicateParentState="true"
/>
<TextView
android:id="#+id/entry_number_of_occurences_1"
android:textSize="9pt"
android:typeface="monospace"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#color/item_text_color_selector"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:duplicateParentState="true"
/>
<TextView
android:id="#+id/entry_frequency_1"
android:textSize="9pt"
android:typeface="monospace"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="#color/item_text_color_selector"
android:layout_gravity="center_vertical"
android:layout_weight="2"
android:duplicateParentState="true"/>
<ImageButton
android:id="#+id/delete_entry_button_1"
android:src="#drawable/delete_button_selector"
android:layout_height="40dp"
android:layout_width="40dp"
android:layout_gravity="center_vertical"
android:layout_marginRight="15dp"
android:duplicateParentState="true"
/>
</com.wordlistdictionary.CheckableLinearLayout>
It works as I expect it with the text color changing for the last touched item until I'm adding the last ImageButton view and it stops highlighting the text from that point.
Has anybody encountered this and what was your solution?
Currently I'm thinking of a workaround with manually propagating the selected state to all child views from my custom layout as opposed to just changing the selected state of the layout view itself and relying on the duplicateParentState mechanism.

It turns out when added to a list item a Button or ImageButton "swallows" the touched event so it doesn't propagate to the list view so I had to set imageButton.setTouchable(false) in getView() in my custom Adapter.
Note that I first tried to set android:touchable='falase' in my layout file but it didn't work so I had to set it programmatically.
I've found the answer in these 2 SO questions:
ListView setOnItemClickListener not working by adding button
Click is not working on the Listitem Listview android

Related

Why does adding a Button to (Android) ListView item shut down tap listener events for the item itself?

I have some pretty simple xml defining a ListView item. Each item contains 2 TextView widgets and a Button. I only added the Button yesterday, and suddenly taps on the ListView item itself no longer produce onItemClick() events.
I have reproduced this carefully and simply removing the Button entry in the XML for the ListItem allows the onItemClick() events to be fired. Answers to other SO questions showed it is possible for controls placed on a ListView item could capture or otherwise prevent tap events from firing the listener (see here for example). So, hoping to find a workaround I added the following 3 lines to my TextView controls to no effect:
android:focusable="false"
android:textIsSelectable="false"
android:clickable="false"
My xml displays everything properly and is:
<?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:id="#+id/linLyt"
>
<TextView
android:id="#+id/tvVal1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_gravity="left|center_vertical"
android:text="0."
android:textSize="16sp"
android:maxLines="1"
android:layout_weight=".15"
/>
<TextView
android:id="#+id/tvVal2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:gravity="left"
android:layout_gravity="center_vertical"
android:text=""
android:textSize="16sp"
android:maxLines="1"
android:layout_weight=".55"
android:focusable="false"
android:textIsSelectable="false"
android:clickable="false"
/>
<Button
android:id="#+id/btnClickMe"
android:layout_width="0dp"
android:layout_height="40dp"
android:gravity="right|center_vertical"
android:layout_gravity="right"
android:textColor="#color/CornflowerBlue"
android:text="Click"
android:minHeight="0dp"
android:minWidth="0dp"
android:textSize="16dp"
android:maxLines="1"
android:layout_weight=".3"
android:background="?android:attr/selectableItemBackground"
/>
</LinearLayout>
Again, just simply remove or comment out the Button xml and suddenly the listener begins firing again.
Add this :
android:descendantFocusability="blocksDescendants"
in your root layout of listview to make the listview Item click listener to work. blocksDescendants means that the ViewGroup will block its descendants from receiving focus.
<?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:descendantFocusability="blocksDescendants"
android:id="#+id/linLyt"
>
in code:
yourListview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> list, View v, int pos, long id) {
// Your code for item click
}
});
Now for Button click listener in listview row: You can set the onClick() event in your custom adapter's getView() method.

Android: Checkbox avoid list item be selected

I have a ListView with a custom list item layout and a selection state for that layout, also i have a checkbox inside a item layout, the problem is,the checkbox is avoiding list item be selected when is presented in layout, but when i change the visibility to gone of checkbox the layout for item respond to selectors.
selector_list.xml
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<CustomTextView
android:id="#id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/dp_8"
android:textColor="#color/gray_light_d2"
android:textSize="#dimen/sp_12"
custom:typeface="robotoBold" />
<CheckBox
android:id="#android:id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true" />
</RelativeLayout>
Add the below attributes to the check box
android:focusable="false"
android:focusableInTouchMode="false"
or add the below to the relative layout an try.
android:descendantFocusability="blocksDescendants"
This happens because the checkbox takes focus when you click on the list item. So try the above suggestions

ListView Custom row not clickable entirely

I am creating an App, in which I am showing information from a database in a ListView, using a custom row layout, which is populated using a SimpleCursorAdapter. I also handle onItemClickListner for the ListView.
My Layout of the custom rows is as follows:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
android:focusableInTouchMode="true"
android:padding="10dip" >
<ImageView android:id="#+id/imageButtonAccount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:src="#drawable/icon_account" />
<TextView
android:id="#+id/TextViewAccount"
style="#style/textView_normal_bold_style"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dip"
android:focusable="false"
android:focusableInTouchMode="false"
android:textSize="#dimen/text_size_large" />
</LinearLayout>
But I have one issue, which follows:
When I click above content of ListView row, it performs only click event, but what I want is when I click any where in a row then a click action should be performed. But it does not behave like this.
The XML of your row should have the attribute
android:layout_width="fill_parent"

Android custom spinner

I have a custom spinner that uses two custom views, one for the drop down and one for the currently selected item.
My problem is, the custom view for the currently selected item is always at least as wide as the longest item in the spinner list and it leaves a sizeable gap on the left hand side of my custom view. If I select the longest item from the spinner, the gap disappears. I have tried android:gravity="left" for my custom view. Also note that this only seems to be an issue with Android 3.0+.
Here is the code for my custom spinner view:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="#+id/folder_detail" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_width="wrap_content">
<TextView android:text="Folder Name"
android:id="#+id/folder_name" android:textColor="#ffffff"
android:layout_width="wrap_content" android:textSize="16sp"
android:textStyle="bold"
android:layout_height="wrap_content" android:layout_marginTop="0dp">
</TextView>
<TextView android:id="#+id/folder_count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="13sp" android:text="(0) " android:textColor="#color/light_blue" android:layout_marginLeft="2dp"/>
<ImageView android:id="#+id/icon" android:src="#android:drawable/arrow_down_float"
android:layout_marginRight="1dp" android:scaleType="fitXY"
android:layout_gravity="bottom" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
</LinearLayout>
This is intentional. It prevents the spinner from drastically changing size as the selection changes.
You're not meant to include an arrow as part of the item view; this is normally included as part of the background 9-patch of the spinner itself. The gravity setting on the spinner itself controls the alignment of the selected item view within the spinner. The Holo theme aligns it to the left, while the legacy themes horizontally center.

How can I add a checkbox to a ListActivity and not lose onListItemClick functionality?

I have a ListActivity working as expected. When a list item is clicked the app responds properly. I want to add a checkbox on the far right side of the screen, next to each list item. When I attempted to do that by updating the XML (see below) I lost the onListItemClick functionality. When I clicked on a list item nothing happened.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TableLayout
android:id="#+id/table1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="1">
<TableRow>
<TextView android:id="#+id/tvProduct"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:paddingLeft="10sp"
android:paddingRight="10sp" />
</TableRow>
</TableLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView android:id="#+id/tvPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10sp"
android:paddingRight="10sp"
android:textColor="#606060" />
</LinearLayout>
</LinearLayout>
I am trying to add the checkbox next to the tvProduct object.
Any help is appreciated.
When a ListView has focusable (clickable) children, it loses focusablitity itself. You can either have a checkbox (button, etc) by clickable inside of a ListView, or have the entire row be clickable.
If you are trying to allow the user to select multiple rows and show the selection state in a checkbox, you can use the choiceMode CHOICE_MODE_MULTIPLE.
Here is an example of it in use.
In the adapter in the getview method, set the checkbox use checkbox.setFocusable(false) and checkbox.setFocusableInTouchMode(false). You can still click the checkbox, but clicking anywhere else gets the list item. Both work fine.
I know there was already an answer, but this has worked for me in the past and is easy to implement so I wanted to add it.

Categories

Resources