Android 7.0 Gallery图库源码分析4 - SlotView手势监听及页面跳转

转载请注明出处: http://blog.csdn.net/lb377463323/article/details/70208825

上篇文章讲了初始化View时会实例化一个SlotView并监听其事件,至于它是怎么实现的,用的是Android自带的GestureDetector。

GestureDetector是Android自带的用来监听各种用户手势的的一个类,比如监听单击、双击和长按等操作。关于GestureDetector的详解可以参考此文章用户手势检测-GestureDetector使用详解

SlotView中定义了一个GestureDetector。

private final GestureDetector mGestureDetector;

public SlotView(AbstractGalleryActivity activity, Spec spec) {
        //给GestureDetector传入我们自定义的Listener接口
        mGestureDetector = new GestureDetector(activity, new MyGestureListener());
        ......
    }

然后在onTouch中拦截SlotView的触摸事件并交给GestureDetector处理

    @Override
    protected boolean onTouch(MotionEvent event) {
        ......
        mGestureDetector.onTouchEvent(event);
        ......
        //必须返回true,不然监听不到完整事件
        return true;
    }

至于GestureDetector的监听事件怎么和SlotView的Listener绑定到一起的?我们看一下自定义的MyGestureListener接口,它就是实现了GestureDetector的OnGestureListener接口。

private class MyGestureListener implements GestureDetector.OnGestureListener {
        ......
        //点击一次
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            ......
            //获取点击的相册索引
            int index = mLayout.getSlotIndexByPosition(e.getX(), e.getY());
            //处理点击事件
            if (index != INDEX_NONE) mListener.onSingleTapUp(index);
            return true;
        }
}

从上述代码可以看出当GestureDetector监测到点击事件时会回调onSingleTapUp方法,在这个方法里我们对点击事件进行处理。上面的mListener就是SlotView中的Listener接口,这样就将GestureDetector的监听事件和SlotView的Listener绑定到一起了。所以每次接收到触摸事件时最终都会传给SlotView的Listener处理,至于SlotView的Listener具体怎么实现每个ActivityState页面都不一样,比如AlbumSetPage中就是如下实现的,最后会调用AlbumSetPage对应的方法来处理触摸事件:

private void initializeViews() {
    mSlotView.setListener(new SlotView.SimpleListener() {
            @Override
            public void onDown(int index) {
                AlbumSetPage.this.onDown(index);
            }

            @Override
            public void onUp(boolean followedByLongPress) {
                AlbumSetPage.this.onUp(followedByLongPress);
            }

            @Override
            public void onSingleTapUp(int slotIndex) {
                AlbumSetPage.this.onSingleTapUp(slotIndex);
            }

            @Override
            public void onLongTap(int slotIndex) {
                AlbumSetPage.this.onLongTap(slotIndex);
            }
        });
}

现在手势监听流程已经讲解完了,下面讲一下界面的跳转,我们找到AlbumSetPage的onSingleTapUp方法

public void onSingleTapUp(int slotIndex) {
        if (mSelectionManager.inSelectionMode()) {
            ......
        } else {
            //显示动画
            mAlbumSetView.setPressedIndex(slotIndex);
            mAlbumSetView.setPressedUp();
            //通过Handler发送消息,msg.arg1是slotIndex,也就是点击的相册索引
            mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PICK_ALBUM, slotIndex, 0),
                    FadeTexture.DURATION);
        }
    }

Handler的handleMessage方法在AlbumSetPage的onCreate方法中

    mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
            @Override
            public void handleMessage(Message message) {
                switch (message.what) {
                    case MSG_PICK_ALBUM: {
                        //跳转到相册
                        pickAlbum(message.arg1);
                        break;
                    }
                    default: throw new AssertionError(message.what);
                }
            }
        };

我们看一下pickAlbum的代码,

private void pickAlbum(int slotIndex) {
    ......
    if (mGetAlbum && targetSet.isLeafAlbum()) {
            ......
        } else if (targetSet.getSubMediaSetCount() > 0) {
            ......
        } else {
            ......
            data.putString(AlbumPage.KEY_MEDIA_PATH, mediaPath);

            // We only show cluster menu in the first AlbumPage in stack
            boolean inAlbum = mActivity.getStateManager().hasStateClass(AlbumPage.class);
            data.putBoolean(AlbumPage.KEY_SHOW_CLUSTER_MENU, !inAlbum);
            //通过StateManager跳转到AlbumPage类中,跟应用的启动流程差不多
            mActivity.getStateManager().startStateForResult(
                    AlbumPage.class, REQUEST_DO_ANIMATION, data);
        }
}

通过上述代码可以看出页面Gallery的页面跳转都是通过StateManager来管理的。如果从相册点击进入某一张图片,跳转逻辑也跟着一样,看下AlbumPage的handleMessage方法就知道了。

猜你喜欢

转载自blog.csdn.net/lb377463323/article/details/70208825