显示相册在app中是一个比较常见的操作,大致的操作就是通过ContentProvider获取多媒体资源进行展示,我综合了一下QQ 的和微信的显示效果,实现了一下,仿微信QQ显示手机相册,在QQ的相册选择时是支持滑动选中的,即手指碰到哪个就选中哪张照片,正好公司的项目中用到了这个功能,在网上找了找没有很好的解决方案,所以通过自定义控件处理事件,这篇文章主要介绍这个功能的实现。
自定义控件SlidingSelectLayout的源代码点击这里获取
大体思路
自定义控件将会作为 RecyclerView
的父控件,这样使他可以优先于RecyclerView
捕捉事件
当手指竖向滑动时,父控件不作处理,RecyclerView
处理事件,进行滑动。当手指横向滑动达到阈值时自定义父控件会截断事件自己进行进行处理。
根据手指的滑动MotionEvent
获取x,y坐标,使用RecycelrView
的findViewUnder(float x,float y)
的方法,可以直接获取制定位置的View,再使用tag从view中拿到之前使用mScl.markView()
方法绑定的pos和data数据
使用该方法就不会因为动态计算距离而局限于RecyclerView的布局,九宫格模式下仍然可以很好的支持。
初始化参数
在处理事件获取手指滑动的位置时,需要使用RecyclerView
的LayoutManager
等,为了尽量对外简化使用的流程,在控件内部使用遍历子控件的方式来获取RecyclerView
和GridLayoutManager的列数等参数,初始化一些值。
获取 RecyclerView
1 | /** |
处理LayoutManager,初始化xTouchSlop,这个值是滑动多大距离触发水平滑动,根据GridLayoutManager的列数来动态设置。
1 | private void ensureLayoutManager() { |
拦截事件
1 | // 如果RecyclerView没有获取到,不进行事件的拦截 |
触摸事件
处理Touch事件
1 |
|
获取数据
1 | // 从View中使用getTag(int key)获取tag,也就是之前在onBindViewHolder中设置的数据 |
触发监听
使用监听向外发布事件,将获取的pos和data通过监听发布
1 | /** |
效果演示
使用
xml 中使用
1 | <com.march.slidingselect.SlidingSelectLayout |
java 代码中配置
在Adapter的onBindViewHolder方法中将pos和data与view进行绑定,之所以这样做是为了可以在手指划过Item时将对应的数据和位置通过监听发送回来。
1 | private SlidingSelectLayout mScl; |
监听回调
使用范型获得手指触摸到的位置和当前位置对应的数据进行更新adapter
1 | mScl.setOnSlidingSelectListener(new SlidingSelectLayout.OnSlidingSelectListener<Demo>() { |
源代码
1 | package com.march.dev.widget; |