6

(请注意,这个问题中描述的行为只是因为我们正在做的其他看似无关的事情而出现。请参阅接受的答案。)

我们有一个带有 aGridView和 aSlidingDrawer的Android 活动RelativeLayout。此活动响应轨迹球(或光标键)的方式相当奇怪。焦点将在 GridView 中的项目之间移动,但只要光标朝 GridView“外”的方向移动。(例如,在顶部时向上,当已经在最左边的项目时向左)滑动抽屉打开或关闭。值得注意的是,焦点停留在 GridView 中的同一项目上——它不会移动到滑动抽屉。

对于轨迹球,这尤其可怕,因为将轨迹球旋转到您的真实目的地会导致滑动抽屉反复打开和关闭。

我们已经确定我们可以通过覆盖来完全关闭轨迹球onTrackballEvent()。我们希望轨迹球和光标在 GridView 上正常工作,但不会导致滑动抽屉打开或关闭。原则上,我们还希望轨迹球在打开时关注滑动抽屉的各种内容。

如何?

4

3 回答 3

3

您可以考虑创建自定义视图,扩展GridViewSlidingDrawer使用和的自定义实现onInterceptTouchEvent以及仅为. 您可能不需要实现自定义,具体取决于可能触发的用户交互onTouchEventGridViewonInterceptTouchEventSlidingDrawerSlidingDrawerhandle

对于您的自定义GridView,给它一个接口,可能定义如下:

public interface MyGridViewListener {
    public boolean shouldPreventScroll();
}

如果您的自定义SlidingDrawer已打开,则返回。此返回值将用于确定是否onInterceptTouchEventonTouchEventGridView. 因此,当SlidingDrawer打开 时,对 执行的操作GridView不会触发SlidingDrawer.

活动:

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

MyCustomGridView: shouldIntercept只要在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;
}

我希望这能为您指明正确的方向或至少有所帮助

于 2011-12-01T20:56:05.833 回答
1

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()

于 2011-12-01T21:56:33.027 回答
0

事实证明,我们是由于一些不相关的愚蠢行为造成了这个问题。我们想要MENU打开和关闭SlidingDrawer. 我们通过覆盖来做到这一点onPrepareOptionsMenu()

public boolean onPrepareOptionsMenu (Menu menu) {
    slidingDrawer.animateToggle();
    return true;
}

这很好用;但事实证明它可以在菜单不打开时调用。特别是,如果Activity使用setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT),则未处理的键事件将最终访问菜单。这包括离开屏幕边缘的轨迹球运动。

获得所需行为的不太愚蠢的方法是

public boolean onKeyUp(int keyCode, KeyEvent event) {
    if(keyCode==KeyEvent.KEYCODE_MENU) {
        slidingDrawer.animateToggle();
    }
    return super.onKeyUp(keyCode,event);
}

SlidingDrawer同时,我们可以通过设置SlidingDrawer.OnDrawerOpenListenerwhich 调用来让轨迹球在它打开时移动

slidingDrawer.getContent().requestFocus();

最后,打电话似乎是个好主意

slidingDrawer.getHandle().setFocusable(false);
于 2011-12-08T18:24:58.940 回答