views:

19

answers:

0

My app used to use a standard ListView, and registerForContextMenu(getListView()) and everything worked just fine.

I needed to change my app to accommodate nested lists so I replaced the ListView with ExpandableListView. I changed the Activity to ExpandableListActivity. I also changed my adapter to a tree adapter and implemented a custom view class to populate the list with (based on a LinearLayout viewgroup).

I have been trying to track down where I screwed it up and I've found several things.

The most important is that when I add a longclick listener to my custom view and return false from it, my context menu pops up and functions properly. However, I don't get the fading orange-to-white long click animation because the long click is being sucked up somewhere else until it is handled by a longclicklistener and ignored (thus being thrown back up the chain until it reaches the ExpandableListView (which is registered for context menus).

I am using a TouchInterceptor model to handle certain gestures from my listview with the following implementation:

public class TouchInterceptor extends ExpandableListView {
... protected MotionEvent downStart = null;

public boolean onInterceptTouchEvent(MotionEvent event) {

    switch(event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        // keep track of the starting down-event
        downStart = MotionEvent.obtain(event);
        break;
    case MotionEvent.ACTION_MOVE:
        // if moved horizontally more than slop*2, capture the event for ourselves
        if(downStart == null)
        {
            break;
        }
        float deltaX = event.getX() - downStart.getX();
        if(Math.abs(deltaX) > ViewConfiguration.getTouchSlop() * 2)
            return true;
        break;
    }

    // otherwise let the event slip through to children
    return super.onInterceptTouchEvent(event);
}

public boolean onTouchEvent(MotionEvent event) {

    // check if we crossed an item
    if(downStart != null)
    {
        float targetWidth = this.getWidth() / 4;

        float deltaX = event.getX() - downStart.getX(),
            deltaY = event.getY() - downStart.getY();

        boolean movedAcross = (Math.abs(deltaX) > targetWidth);
        boolean steadyHand = (Math.abs(deltaX / deltaY) > 2);

        if(movedAcross && steadyHand) {
            boolean crossRight = (deltaX > 0);

            // figure out which child view we crossed
            ListView list = (ListView)this.findViewById(android.R.id.list);
            int position = list.pointToPosition((int)downStart.getX(), (int)downStart.getY());

            // pass crossed event to any listeners
            onCross(crossRight, position);
            downStart = null;
            // and return true to consume this event
            return true;
        }
    }
    return super.onTouchEvent(event);
}

... }

Is there something wrong with how I'm handling these events?

Note: although my context menu pops up, it only does so when the long-click event is triggered, not a long OK button click.

Something is screwed up here and I'm not sure how to track it down.