Android自定义View(二)---拉刷新ListView 下之事件分发源码解析
来源:互联网 发布:淘宝彩票走势图 编辑:程序博客网 时间:2024/05/01 00:46
贴出来自定下拉刷新的源码,其主要部分已经贴出来了,欢迎拍砖。
git@git.oschina.net:gezihua/supro.git
package com.example.gezihua.myapplication.pull;import android.animation.ValueAnimator;import android.content.Context;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.ViewConfiguration;import android.view.animation.DecelerateInterpolator;import android.widget.RelativeLayout;import com.example.gezihua.myapplication.R;import java.lang.ref.WeakReference;/** * Created by gezihua on 16-12-20. */public class PullToRefresh extends RelativeLayout { private boolean mIsBeingDragged; private float mTouchSlop; private float mStartY; private float mLastMottionY; private ValueAnimator mResetAnimation; public void setmRefreshView(IPullView mRefreshView) { this.mRefreshView = mRefreshView; } private IPullView mRefreshView; public void setHeaderView(IHeaderView headerView) { mHeaderView = headerView; } private IHeaderView mHeaderView; public PullToRefresh(Context context) { super(context); init(); } private void init() { ViewConfiguration config = ViewConfiguration.get(getContext()); mTouchSlop = config.getScaledTouchSlop(); int dimensionPixelOffset = getResources().getDimensionPixelOffset(R.dimen.pull_to_refresh_max); if (dimensionPixelOffset < MAX_PULL) { MAX_PULL = dimensionPixelOffset; } } public PullToRefresh(Context context, AttributeSet attrs) { super(context, attrs); init(); } public PullToRefresh(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { //能相应第一个应该是Down事件 // 对于能滚动View的View来说,这个时候应该已经滚动到最上边 if (mRefreshView == null || !mRefreshView.canScroll()) { Log.e("suj", "can scroll" + mRefreshView.canScroll()); mIsBeingDragged = false; return super.onInterceptTouchEvent(ev); } int action = ev.getAction(); Log.e("suj", "onInterceptTouchEvent" + ev.toString()); switch (action) { case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: { if (mIsBeingDragged) { return true; } break; } // 这里应该返回false ,别问我为什么 //如果子布局还要处理事件,这里一定要返回false //真正拦截不下发的地方应该在 move 事件 case MotionEvent.ACTION_DOWN: { return startDragging(ev); } case MotionEvent.ACTION_MOVE: { return onDragging(ev); } } return super.onInterceptTouchEvent(ev); } private boolean onDragging(MotionEvent ev) { mLastMottionY = ev.getY(); if (mLastMottionY < mStartY) { mIsBeingDragged = false; return false; } mIsBeingDragged = true; boolean dragging = Math.abs(mLastMottionY - mStartY) >= mTouchSlop; //Log.e("suj","can dragging"+dragging); return dragging; } private boolean startDragging(MotionEvent ev) { mStartY = ev.getY(); mIsBeingDragged = true; return false; } private boolean showHeaderView() { if (mHeaderView == null) { return false; } return mHeaderView.canRefresh(); } private static class H extends Handler { WeakReference<PullToRefresh> pullToRefreshRef; public H(PullToRefresh refresh) { pullToRefreshRef = new WeakReference<PullToRefresh>(refresh); } @Override public void dispatchMessage(Message msg) { super.dispatchMessage(msg); if (msg.what != MSG_END_DRAGGING) { return; } PullToRefresh pullToRefresh = pullToRefreshRef.get(); if (pullToRefresh == null) { return; } pullToRefresh.reset(); } } private final static int MSG_END_DRAGGING = 1; private H mH; private Message generateDraggingMsg(int msg) { Message obtain = Message.obtain(); obtain.what = msg; return obtain; } private void handleEndDragging(MotionEvent ev) { mIsBeingDragged = false; mLastMottionY = 0; mStartY = 0; // 为了解决不能连续刷新的问题,应该把以前的动画以及刷新动画停止,并且重置状态 removeDelayEndDragging(); endResetAnimation(); // then we can do some refresh animator; // if the header is not show ,we can do animation immediately if (showHeaderView()) { if (mH == null) { mH = new H(this); } mH.sendMessageDelayed(generateDraggingMsg(MSG_END_DRAGGING), 350); // then we can start refresh animation mHeaderView.showRefresh(); } else { reset(); } } private void removeDelayEndDragging() { if (mH == null) { return; } mH.removeMessages(MSG_END_DRAGGING); } private void endResetAnimation(){ if (mResetAnimation==null){ return; } if (mResetAnimation.isRunning()){ mResetAnimation.cancel(); } } private void endHeaderAnimation(){ if (mHeaderView==null){ return; } mHeaderView.cancelRefresh(); } // when destroy we must remove the delayed msg @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); removeDelayEndDragging(); } private void reset() { mResetAnimation = ValueAnimator.ofFloat(mRefreshView.getPullTransY(), 0); mResetAnimation.setDuration(350); mResetAnimation.setRepeatMode(ValueAnimator.RESTART); mResetAnimation.setInterpolator(new DecelerateInterpolator()); mResetAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float animatedValue = (float) animation.getAnimatedValue(); mRefreshView.setPullTransY((int) animatedValue); } }); mResetAnimation.start(); } @Override public boolean onTouchEvent(MotionEvent event) { Log.e("suj", "onTouchEvent" + event.toString()); if (mIsBeingDragged) { int action = event.getAction(); //Log.e("suj","onTouchEvent"+event.toString()); switch (action) { case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: { handleEndDragging(event); break; } case MotionEvent.ACTION_MOVE: { return handleDragging(event); } case MotionEvent.ACTION_DOWN: { break; } } return true; } return super.onTouchEvent(event); } private int MAX_PULL = 300; private boolean handleDragging(MotionEvent event) { if (mRefreshView == null) { return false; } mLastMottionY = event.getY(); if (mLastMottionY < mStartY) { return false; } int lastTransY = mRefreshView.getPullTransY(); float v = mLastMottionY - mStartY; //Log.e("suj","mLastMottionY"+mLastMottionY+"startY"+mStartY); int pull = (lastTransY + v) / 2 > MAX_PULL ? MAX_PULL : (int) (lastTransY + v) / 2; mRefreshView.setPullTransY(pull); return true; }}
0 0
- Android自定义View(二)---拉刷新ListView 下之事件分发源码解析
- Android View 事件分发机制 源码解析(View篇)
- Android源码解析之四:View事件分发机制
- Android View 事件分发机制 源码解析
- Android View 事件分发机制 源码解析
- Android View 事件分发机制 源码解析
- Android View 事件分发机制 源码解析
- Android View 事件分发机制 源码解析
- Android View 事件分发机制 源码解析
- Android View 事件分发机制 源码解析
- Android View 事件分发机制 源码解析
- Android View 事件分发机制 源码解析
- android View的事件分发源码解析
- Android源码:事件分发源码解析(二)
- Android View 事件分发机制 源码解析 (上)
- Android View 事件分发机制 源码解析 (上)
- Android View 事件分发机制 源码解析 (上)
- Android View 事件分发机制 源码解析 (上)
- CodeForces - 91B 单调队列 或 线段树
- Lucene-Field.Store的Field.Index属性笔记
- Python练习实例18 数组相加
- 一个经典例子让你彻彻底底理解java回调机制
- jquery怎么获取select选中的值,默认选中
- Android自定义View(二)---拉刷新ListView 下之事件分发源码解析
- 浅谈Java中的对象和引用
- shell(缩小增量)排序
- struts2和servlet的共存问题
- webservice返回dataset
- 历尽千辛 升到四级了 happy
- Linux下使用inotify监控文件动作
- Ajax跨域请求
- 都说微商不好做!有谁考虑用户最终目的过?