ScrollView下拉刷新
来源:互联网 发布:b站 解除限制 知乎 编辑:程序博客网 时间:2024/05/22 07:41
public class PullScrollView extends RelativeLayout { public PullScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } public PullScrollView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public PullScrollView(Context context) { super(context); init(context); } /** *首先是初始化mTouchSlop 是触摸手势滑动的最小像素值,也就是说滑动多少 *的距离才算是手势滑动,这样可以防止手势一点点的移动就引起的滑动事件。 *mScroller 是用来处理平滑滚动的。之前的博客有介绍。 **/ private Scroller mScroller ; private int mTouchSlop ; private void init(Context context){ ViewConfiguration configuration = ViewConfiguration.get(getContext()); mTouchSlop = configuration.getScaledTouchSlop(); mScroller = new Scroller(context, new DecelerateInterpolator()); } /** * 在布局初始化结束之后,得到布局中的两个子孩子,为啥只能有两个孩子那?? * BottomView是用来下拉刷新展示的View contentView 就是我们的 * ScrollView了。如果子孩子多了,怎么知道哪个VIew是需要被隐藏的?所以只 * 处理两个View的情况,当然,如果还有上拉加载更多,就需要三个子孩子了。 **/ private ViewGroup bottomView ; private ScrollView contentView ; @Override public boolean dispatchTouchEvent(MotionEvent ev) { getTopPosition(); return super.dispatchTouchEvent(ev); } @Override protected void onFinishInflate() { super.onFinishInflate(); if (getChildCount() > 2) { throw new RuntimeException("子孩子只能有两个"); } bottomView = (ViewGroup) getChildAt(0); contentView = (ScrollView) getChildAt(1); } private int startY ; @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (getScrollY() < 0 ) { return true ; } switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: startY = (int) ev.getY(); break; case MotionEvent.ACTION_MOVE: int moveY = (int) ev.getY(); int delayY = moveY - startY ; Log.i("Test", delayY + " = " + mTouchSlop) ; if (getTopPosition() && delayY > mTouchSlop) { ev.setAction(MotionEvent.ACTION_DOWN); return true ; } break ; case MotionEvent.ACTION_UP: break; } return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: startY = (int) event.getY(); break; case MotionEvent.ACTION_MOVE: int delayY = (int) (event.getY() - startY) ; if (getTopPosition() && getScrollY() <= 0 ) { pullMove((int) (-delayY * 0.8)); } startY = (int) event.getY(); return true ; case MotionEvent.ACTION_UP: int scrollY = getScrollY(); if (state == PullState.ON_REFRESH && scrollY < 0 && Math.abs(scrollY) > bottomHeight) { restView(-getScrollY() - bottomHeight); return true ; }else if (state == PullState.ON_REFRESH && scrollY < 0 && Math.abs(scrollY) < bottomHeight) { return true ; } if (scrollY < 0 && Math.abs(scrollY) < bottomHeight ) { returnView(); }else if (scrollY < 0 && Math.abs(scrollY) > bottomHeight && state != PullState.ON_REFRESH) { if (onreListener != null) { state = PullState.ON_REFRESH ; onreListener.refresh(); } restView(-getScrollY() - bottomHeight); } break; } return true ; } private PullState state = PullState.REST ; @Override public void computeScroll() { super.computeScroll(); if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } } private void returnView(){ restView(-getScrollY()); } private void restView(int dy){ mScroller.startScroll(0, getScrollY(), 0, dy , 340); postInvalidate(); } private void pullMove(int delay){ if (getScrollY() <= 0 && (getScrollY() + delay) <= 0 ) { scrollBy(0, delay); }else { scrollTo(0, 0); } } /** *手势的拦截动作,通过getTopPosition()方式,来判断ScrollView时候处于 *下拉需要显示隐藏子View的状态,delayY > mTouchSlop 是用来判断是不是 *下拉的动作的。 如果符合条件 我们就需要将手势拦截掉,return true。 *为什么我觉得ScrollView做下来刷新比较好做那? 就是因为ScrollView的判断比较好判断。 */ private boolean getTopPosition(){ if (contentView.getScrollY() <= 0 ) { return true ; } return false ; } /** *onLayout,做过自定义的都应该很熟悉这个方法,放置子孩子位置的一个方法, *因为我们需要有一个子孩子隐藏掉,当我们需要它显示的时候才去显示,所以 *需要手动的去将BottomView放到布局-hight到0的位置,这样下拉的时候才能 *显示出来。 **/ @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { bottomHeight = getBottomViewHeight() ; Log.i("Test", l + "ceshi" + " t="+t + " r"+r + " b=" + b + " height= " + bottomHeight); bottomView.layout(l, - bottomHeight, r, t); contentView.layout(l, 0, r, b); } private int bottomHeight = 0 ; private int getBottomViewHeight(){ return bottomView.getMeasuredHeight(); } enum PullState{ REST , ON_REFRESH } public void stopRefresh(){ state = PullState.REST; returnView(); } private onRefreshListener onreListener ; public void setOnRefreshListener (onRefreshListener onreListener) { this.onreListener = onreListener ; } public interface onRefreshListener{ public void refresh(); }}
源码下载
0 0
- scrollview下拉刷新
- 下拉刷新ScrollView
- ScrollView 下拉刷新
- ScrollView下拉刷新
- listview、gridView、ScrollView 下拉刷新
- 下拉刷新之ScrollView--PullToRefreshScrollView
- 自定义ScrollView实现下拉刷新
- 使用ScrollView实现下拉刷新(一)
- ScrollView 实现下拉刷新(二)
- 分享一个可下拉刷新的ScrollView
- 使用ScrollView实现下拉刷新(一)
- UI:实现ScrollView能够下拉刷新效果
- android下拉刷新scrollview的用法pullToRefreshScrollview
- 自定义上拉刷新下拉加载ScrollView
- Android 下拉刷新(刷新布局需用ScrollView包裹)
- Android 下拉刷新控件之ScrollView版本实现
- Android 下拉刷新控件之ScrollView版本实现
- Android 下拉刷新控件之ScrollView版本实现 .
- java 数据类型转换
- 字符串反转的三种方法
- cocoa pods 使用记录
- Android APK的加密
- emmet 常用字符串
- ScrollView下拉刷新
- 1001 A+B Format
- 文章标题
- java NIO的一些个人总结
- Java垃圾回收机制(GC)详解
- 实现标准equals的流程
- libsvm3.2.1 - SVM多分类简单实现
- A prompt box with an arrow
- 二叉排序树