swipmenulistview+pulltorefresh整合
来源:互联网 发布:最新网络币 编辑:程序博客网 时间:2024/06/07 01:27
大概在今年1月份吧,项目中有需要用到pulltorefresh+swipmenulistview,但是这两个控件整合到一块,在网上找了好久都没找到好的,要么是整合的不好,要么是直接重写swipmenulistview控件来实现下拉刷新的功能
于是我就把两个控件整合到了一起,以后项目想用的时候就很方便了哈~ 先看看如下效果
是不是很爽?!接下来我就分析其中的原理,细节性的我就不说,我就大概给个思路和一些关键性代码,细节性的大家就去下源码看看吧~
先分析下,上拉和下拉操作都要给pulltorefresh处理,左滑和右滑都要交给swipmenulistview,然后swipmenulistview的父布局是pulltorefresh,刚开始整合的时候很容易,功能也能实现,但是用户体验非常差,例如swipmenulistview左滑和右滑时,如果滑动时,Y轴方向的移动距离达到触发下拉事件的话,左右滑动就会停止,滑动事件被pulltorefresh进行处理,导致左右滑动就无法进行了
既然原因知道了,然后需要根据Touch事件的分发处理机制,那问题很容易解决,在swipmenulistview进行滑动时,所有的滑动事件都交由swipmenulistview处理就行,但是根据Touch事件的触发机制,是从外到内,即父布局传到子布局,这里的父布局就是pulltorefresh,子布局就是swipmenulistview。 一旦swipmenulistview进行滑动了,那么在swipmenulistview滑动事件未处理完毕之前,所有的Touch事件都交由swipmenulistview进行处理,思路就是这样子 接下来看一些修改的关键性代码
首先swipmenulistview需要暴露一个接口,来让父布局即pulltorefresh监听它的当前状态,pulltorefresh根据swipmenulistview状态是否将Touch事件传递下去
在SwipeMenuListView这个类中,有这么个属性
private int mTouchPosition;它就是代表着当前swipmenulistview的状态,下面这三个属性,分别代表当前swipmenulistview的状态,TOUCH_STATE_X代表现在是左右滑动中,在这个状态中,所有的Touch事件需要它处理,父布局不能处理
private static final int TOUCH_STATE_NONE = 0;private static final int TOUCH_STATE_X = 1;private static final int TOUCH_STATE_Y = 2;
现在 就是关键的部分,就是在SwipeMenuListView进行滑动时,实时改写mTouchPosition的状态,然后父布局根据这个状态是否需要处理当前的Touch事件
首先如何动态改写:覆写SwipeMenuListView的onTouchEvent(MotionEvent ev),如下代码
public boolean onTouchEvent(MotionEvent ev) { int action = MotionEventCompat.getActionMasked(ev); action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: mDownX = ev.getX(); mDownY = ev.getY(); mTouchState = TOUCH_STATE_NONE;//重置当前状态 if (mTouchView != null && mTouchView.isOpen()) { mTouchView.smoothCloseMenu(); return false; } mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY()); View view = getChildAt(mTouchPosition - getFirstVisiblePosition()); if (view instanceof SwipeMenuLayout) { mTouchView = (SwipeMenuLayout) view; mTouchView.setmSwipeStateListen(new SwipeMenuLayout.SwipeStateListen() { @Override public void stateChange() { mTouchState = TOUCH_STATE_NONE; } }); } if (mTouchView != null) { mTouchView.onSwipe(ev); } break; case MotionEvent.ACTION_MOVE: float dy = Math.abs((ev.getY() - mDownY)); float dx = Math.abs((ev.getX() - mDownX)); if (mTouchState == TOUCH_STATE_X) { // 滑动 if (mTouchView != null) { mTouchView.onSwipe(ev); } getSelector().setState(new int[]{0}); ev.setAction(MotionEvent.ACTION_CANCEL); super.onTouchEvent(ev); return true; } else { // Log.i("byz", "state = " + mTouchState + ", dx = " + dx // + ", max = " + MAX_X); if (mTouchState != TOUCH_STATE_X && Math.abs(dy) > MAX_Y) {//是左右滑动,改写状态为TOUCH_STATE_X mTouchState = TOUCH_STATE_Y; } if (mTouchState != TOUCH_STATE_Y && dx > MAX_X) {//是左右滑动,改写状态为TOUCH_STATE_Y mTouchState = TOUCH_STATE_X; } } break; case MotionEvent.ACTION_UP: if (mTouchState == TOUCH_STATE_X) {//将滑动动画播放完毕 if (mTouchView != null) { mTouchView.onSwipe(ev); } ev.setAction(MotionEvent.ACTION_CANCEL); super.onTouchEvent(ev); return true; } break; } return super.onTouchEvent(ev); }
状态已经实时改写,现在就是在pulltorefresh的onInterceptTouchEvent(MotionEvent event)方法中进行事件的分发操作,pulltorefresh根据状态为1的就进行事件下发,自己不处理,如下代码
@Override public final boolean onInterceptTouchEvent(MotionEvent event) { if (mListView.getmTouchState() == 1) { return false; } return super.onInterceptTouchEvent(event); }
pulltorefresh这个控件相信在很多项目都有使用过,即防ios的下拉刷新效果~下载地址
swipmenulistview 这个控件也是仿ios的item的左滑效果,以有更多功能选项 下载地址
整合swipmenulistview+pulltorefresh 点击打开链接,如果打不开,可以私信我~(项目是用Gradle构建,最好用as打开)
- swipmenulistview+pulltorefresh整合
- pulltorefresh
- PullToRefresh
- PullToRefresh
- PullToRefresh
- PullToRefresh
- PullToRefresh
- pullToRefresh
- PullToRefresh
- PullToRefresh
- pullToRefresh
- pulltorefresh
- Pulltorefresh
- PullToRefresh
- Pulltorefresh
- PullToRefresh
- pullToRefresh
- pulltorefresh
- 七步从AngularJS菜鸟到专家(6):服务
- 实验项目2-13:两个有序序列的中位数
- Android自定义View自定义圆形Dialog
- MySQL优化之一--硬件和操作系统
- JAVA学习笔记--线程请求Json数据,并解析绑定到listView
- swipmenulistview+pulltorefresh整合
- 160722界面的颜色透明度渐变
- 链表相加
- ecshop数据库操作函数
- tabbar和navigationbar
- Ignatius and the Princess I
- Teradata Tomcat 连接池
- C++异常捕获和动态内存申请
- Windbg 自动加载到启动的进程