Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change how SlidingDrawer responds to trackball or cursor

(Please note that the behavior described in this question only appeared because of something else seemingly unrelated we were doing. See the accepted answer.)

We have an Android activity with a GridView and a SlidingDrawer inside of a RelativeLayout. The way this activity responds to the trackball (or cursor keys) is rather odd. The focus will move among the items in the GridView, but whenever the cursor moves in a direction "out" of the GridView. (e.g. up when at the top, left when already at the leftmost item) the sliding drawer opens or shut. Notably, the focus stays on the same item in the GridView---it does not move to the sliding drawer.

With a trackball this is particularly horrible, as spinning the trackball past your real destination will cause the sliding drawer to repeatedly open and close.

We've determined that we can turn off the trackball entirely by overriding onTrackballEvent(). We'd prefer to have the trackball and cursor work normally on the GridView but not cause the sliding drawer to open or close. In principle we'd also like the trackball to focus on the various contents of the sliding drawer when it is open.

How?

like image 351
Robert Tupelo-Schneck Avatar asked Nov 29 '11 17:11

Robert Tupelo-Schneck


2 Answers

You may consider creating custom views extending GridView and SlidingDrawer and using custom implementations of onInterceptTouchEvent and onTouchEvent for the GridView and a custom implementation just for onInterceptTouchEvent for the SlidingDrawer. You may not need to implement a custom SlidingDrawer depending on what user interactions may be triggered on the handle

for your custom GridView, give it an interface maybe defined like this:

public interface MyGridViewListener {
    public boolean shouldPreventScroll();
}

return if your custom SlidingDrawer is opened. this returned value will be used to determine if actions should be performed(for onInterceptTouchEvent and onTouchEvent methods) on the GridView. So when the SlidingDrawer is opened, actions performed on the GridView will not trigger anything on the SlidingDrawer.

Activity:

MyGridView gridView = (MyGridView) findViewById(R.id.gridView);
gridView.setMyGridViewListener(new MyGridViewListener() {
    @Override
    public boolean shouldPreventScroll() {
        return slidingDrawer.isOpened();
    }
});

MyCustomGridView: shouldIntercept will be called whenever some touch/track event happens on the GridView.

private boolean shouldIntercept() {
    boolean shouldIntercept = false;
    if(myGridViewListener != null) {
        shouldIntercept = myGridViewListener.shouldPreventScroll();
    }
    return shouldIntercept;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return shouldIntercept() ? true : super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
    return shouldIntercept() ? true : super.onTouchEvent(ev);
}
@Override
public boolean onTrackballEvent(MotionEvent event) {
    return shouldIntercept() ? true : super.onTrackballEvent(event);
}
public MyGridViewListener getMyGridViewListener() {
    return myGridViewListener;
}
public void setMyGridViewListener(
        MyGridViewListener myGridViewListener) {
    this.myGridViewListener = myGridViewListener;
}

I hope this points you in a right direction or at least helps

like image 57
james Avatar answered Oct 13 '22 05:10

james


While playing around with a custom sliding drawer I set the layout of the handle to some odd value, something like

handle.layout(0, 0,0, 0);

to make the handle disappear but dragging a finger from the side of the screen would still open the sliding drawer, which is what I didn't want, so I set

handle.layout(10000, 10000, 10000, 10000); 

which moved it way outside the viewable area and the drawer could no longer be pulled out manually by dragging from the side of the screen. After looking at the source code its teh position of the handle that determines the sliding of the drawer, get rid of the handle and it should solve your problem.

If you need to open/close the drawer call animateOpen()/animateClose()

like image 27
triggs Avatar answered Oct 13 '22 06:10

triggs