zoukankan      html  css  js  c++  java
  • Android 7.0 Gallery图库源码分析4

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

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

    SlotView中定义了一个GestureDetector。

    1 private final GestureDetector mGestureDetector;
    2 
    3 public SlotView(AbstractGalleryActivity activity, Spec spec) {
    4         //给GestureDetector传入我们自定义的Listener接口
    5         mGestureDetector = new GestureDetector(activity, new MyGestureListener());
    6         ......
    7     }

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

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

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

     1 private class MyGestureListener implements GestureDetector.OnGestureListener {
     2         ......
     3         //点击一次
     4         @Override
     5         public boolean onSingleTapUp(MotionEvent e) {
     6             ......
     7             //获取点击的相册索引
     8             int index = mLayout.getSlotIndexByPosition(e.getX(), e.getY());
     9             //处理点击事件
    10             if (index != INDEX_NONE) mListener.onSingleTapUp(index);
    11             return true;
    12         }
    13 }

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

     1 private void initializeViews() {
     2     mSlotView.setListener(new SlotView.SimpleListener() {
     3             @Override
     4             public void onDown(int index) {
     5                 AlbumSetPage.this.onDown(index);
     6             }
     7 
     8             @Override
     9             public void onUp(boolean followedByLongPress) {
    10                 AlbumSetPage.this.onUp(followedByLongPress);
    11             }
    12 
    13             @Override
    14             public void onSingleTapUp(int slotIndex) {
    15                 AlbumSetPage.this.onSingleTapUp(slotIndex);
    16             }
    17 
    18             @Override
    19             public void onLongTap(int slotIndex) {
    20                 AlbumSetPage.this.onLongTap(slotIndex);
    21             }
    22         });
    23 }

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

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

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

     1 mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
     2             @Override
     3             public void handleMessage(Message message) {
     4                 switch (message.what) {
     5                     case MSG_PICK_ALBUM: {
     6                         //跳转到相册
     7                         pickAlbum(message.arg1);
     8                         break;
     9                     }
    10                     default: throw new AssertionError(message.what);
    11                 }
    12             }
    13         };

    我们看一下pickAlbum的代码,

     1 private void pickAlbum(int slotIndex) {
     2     ......
     3     if (mGetAlbum && targetSet.isLeafAlbum()) {
     4             ......
     5         } else if (targetSet.getSubMediaSetCount() > 0) {
     6             ......
     7         } else {
     8             ......
     9             data.putString(AlbumPage.KEY_MEDIA_PATH, mediaPath);
    10 
    11             // We only show cluster menu in the first AlbumPage in stack
    12             boolean inAlbum = mActivity.getStateManager().hasStateClass(AlbumPage.class);
    13             data.putBoolean(AlbumPage.KEY_SHOW_CLUSTER_MENU, !inAlbum);
    14             //通过StateManager跳转到AlbumPage类中,跟应用的启动流程差不多
    15             mActivity.getStateManager().startStateForResult(
    16                     AlbumPage.class, REQUEST_DO_ANIMATION, data);
    17         }
    18 }

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

  • 相关阅读:
    normalize.css 中文版
    [转载]自适应高度输入框
    【转载】H5页面列表的无线滚动加载(前端分页)
    CSS设置table下tbody滚动条与thead对齐的方法
    [转载]Jquery mobiscroll 移动设备(手机)wap日期时间选择插件以及滑动、滚动插件
    wordpress 目录、数据结构和解析原理
    WordPress基础知识:条件判断标签及用法大全
    主题如何添加tag标签页面
    WordPress进阶:[2]不同页面显示不同的侧边栏
    WordPress进阶:[1]怎样用tag标签做导航菜单
  • 原文地址:https://www.cnblogs.com/zhao-shan/p/9838417.html
Copyright © 2011-2022 走看看