一步步自定义下拉刷新上拉加载——自定义简单的刷新组件

一、必备基础
二、入门
三、进阶
四、优化

上一篇文章介绍了 事件分发机制 和 滑动冲突的解决方案,本篇文章开启自定义下拉刷新之旅。首先,我们看效果图。

这里写图片描述
在自定义下拉刷新时,我们通过使用Scroller 来滑动布局。接下来,我们先了解Scroller的使用。

Scroller

这篇文章郭霖 完全解析Scroller,详细地介绍了Scroller。
使用Scroller的步骤非常简单:

  1. 创建Scroller的实例
  2. 调用startScroll()方法来初始化滚动数据并刷新界面
  3. 重写computeScroll()方法,并在其内部完成平滑滚动的逻辑

同时我们要注意到ScrollTo 表示滚动到指定位置,ScrollBy表示每次滚动一段距离。

我们自定义一个ScrollerLayout来模拟ViewPager的滑动切换效果。

这里写图片描述

布局如下,在ScrollerLayout中嵌套了三个Button

<?xml version="1.0" encoding="utf-8"?>
<com.example.com.myapplication.view.ScrollerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:text="This is first child view" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:text="This is second child view" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:text="This is third child view" />
</com.example.com.myapplication.view.ScrollerLayout>

由于Button是可点击的,它会消费点击事件,导致ScrollerLayout 不能调用OnTouchEvent。根据上篇文章介绍的 事件拦截机制和滑动冲突解决方案,我们必须在自定义ScrollerLayout添加拦截事件,即在ScrollerLayout滑动时进行拦截

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int x = (int) ev.getRawX();
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mLastX = x;
                break;
            case MotionEvent.ACTION_MOVE:
                int deltaX = x - mLastX;//拦截横向滑动事件
                if (Math.abs(deltaX) > mTouchSlop) {
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return false;
    }
左边界

当我们处于第一个界面,向右滑动

很明显
scrolledX = LastX - X < 0
getScroller()+ScrolledX < 0

 if (getScrollX() + scrolledX < mLeftBorder) { //左边界
                    scrollTo(mLeftBorder, 0);
                    return true;
                } 
右边界

当我们处于最后一个界面,向左滑动

scrolledX = LastX - X > 0

我们要控制
getScroller + scrolledX + getWidth > rightBorder

if (getScrollX() + getWidth() + scrolledX > mRightBorder) {
  
  // 右边界
                    scrollTo(mRightBorder - getWidth(), 0);
                    return true;
                }

完整代码

public class ScrollerLayout extends ViewGroup {
    private static String TAG = "ScrollerLayout";

    private Scroller mScroller;
    private int mTouchSlop;//最小的滑动距离

    private int mLeftBorder;
    private int mRightBorder;

    public ScrollerLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mScroller = new Scroller(context);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        Log.d(TAG, "最小滑动距离: TouchSlop " + mTouchSlop);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值