Reputation: 2913
I have listview item like below
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android:descendantFocusability="blocksDescendants"
>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<CheckBox
android:id="@+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/music_list_item_checkbox_bg"
/>
</LinearLayout>
music_list_item_checkbox_bg.xml
is a selector which will show different drawable depending the different state.
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:state_pressed="false"
android:state_selected="true"
android:drawable="@drawable/btn_checkbox_check_untapped" />
<item android:state_selected="true"
android:state_pressed="true"
android:drawable="@drawable/btn_checkbox_check_tapped" />
<item android:state_selected="false"
android:state_pressed="false"
android:drawable="@drawable/btn_checkbox_uncheck_untapped" />
<item android:state_selected="false"
android:state_pressed="true"
android:drawable="@drawable/btn_checkbox_uncheck_tapped" />
</selector>
When i pressed the item in the listview and left the touch screen inside the item, the drawable depending on the different state is right.
Question: But if i pressed the item and move the finger horizontally out of the item (The X of touch point is between the top and bottom of the item), then left the screen, the drawable of the checkbox will remain in the state of pressed. (If the X of touch point is out of the top and bottom of the item, the state is right).
I tried add android:duplicateParentState="true"
to the checkbox to get the same state with the parent, but it not works.
I'm confused, Anyone have some ideas?
Edited
I tried implements onTouch and onIntercept in the item before, but only can receive action down, if i return super.onTouch(MotionEvent event). Only return true, then the sequence event will received, but the onItemClick of listview could't worked. I try to read the onTouch code snippet in the AbsListview to figure out how to resolve the problem, i found sometimes the press status of child(item) will not to clear to false by calling child.setPressed(false) which depending on the different touch mode.
I really really want an solution!!!
Upvotes: 3
Views: 3486
Reputation: 2913
I solve the problem but maybe not a good solution or official solution.
I use my own MyListView
class extends from ListView
instead of the SDK ListView
and receive the ACTION_UP
and ACTION_CANCEL
in its onTouchEvent
, then set the press state of the item to false manually. More details to see the below code.
@Override
public boolean onTouchEvent(MotionEvent event)
{
boolean handled = super.onTouchEvent(event);
Log.d("test", "event " + event.toString());
int action = event.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
m_downPosition = pointToPosition((int)event.getX(), (int)event.getY());
Log.d("test", "The down position " + m_downPosition);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
int position = m_downPosition - getFirstVisiblePosition();
View child = INVALID_POSITION != m_downPosition ? getChildAt(position) : null;
if (null != child)
{
child.setPressed(false);
}
break;
default:
break;
}
return handled;
}
Upvotes: 1
Reputation: 34765
<?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/btn_checkbox_check_tapped" />
<item android:state_selected="true"
android:drawable="@drawable/btn_checkbox_check_tapped" />
<item android:drawable="@drawable/btn_checkbox_uncheck_untapped" />
</selector>
try using these selector as background
Upvotes: 2
Reputation: 24235
Extend the LinearLayout
for your item and override the onTouch
in it. Handle the ACTION_CANCEL event(return true) and update the item's pressed and selected states.
class ItemLayout extends LinearLayout {
@override
boolean onTouch(MotionEvent ev) {
switch(ev.getAction()) {
case ACTION_CANCEL:
// Update/reset pressed and selected states of item or checbkox
return true;
}
return super.onTouch(ev);
}
}
Refer http://groups.google.com/group/android-developers/browse_thread/thread/df75c5b8e4605167#
Hope that helps.
<ItemLayout
....>
<TextView
...
/>
<CheckBox
...
/>
</ItemLayout >
Upvotes: 0
Reputation: 33983
You should try having a default selector item like this
<item android:drawable="@drawable/btn_checkbox_uncheck_untapped" />
and this will take care of all the remaining states
or you should have a selector item which takes care of the focussed
states which is missing in your xml.
Upvotes: 0
Reputation: 13501
try making the views inside it not focussable...
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<CheckBox
android:id="@+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/music_list_item_checkbox_bg"
android:focussableInTouchMode="false"
android:focussable="false"
/>
you cannot make a List item focussable in touch mode... here since your checkBox is focussable it creates problem...
Upvotes: 1