(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?
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
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With