dreamtale
dreamtale

Reputation: 2913

Wierd listview item selector appearance (pressed state was not removed when finger left the screen)

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

Answers (5)

dreamtale
dreamtale

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

Shankar Agarwal
Shankar Agarwal

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

Ron
Ron

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

Varun
Varun

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

ngesh
ngesh

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

Related Questions