Giter VIP home page Giter VIP logo

alipaypullrefresh's Introduction

支付宝首页下拉刷新

支付宝首页的下拉刷新效果不走寻常路,跟我们理解的很不一样。它在下拉刷新时,分成上下两段(topLayout & bottomLayout),loading动画处于中间的位置。在拖拽的时候,就像是从中间撕开的样子。

真要细细琢磨起来,这样的下拉刷新效果,确实挺难搞的。在页面中的任何一处都能上下拖动,相当考验细心和耐心。

截图

效果图如下:

点击图片可查看截屏视频

原理说明

或许很多人都想到了CoordinatorLayout,诚然,CoordinatorLayout是距离这种下拉刷新效果最近的官方控件。但是,有一些体验上的问题,却是CoordinatorLayout也无能为力的。比如说:在topLayout按下触摸,向下拖动时,怎么把loading动画慢慢显示出来? 或者,topLayout向上拖动,以较快的速度松手时,fling效果如何传达到bottomLayout?

或许你会说,我们自定义CoordinatorLayout...

我不否认这可能是一种可行的方案,如果你对其源码足够了解,如果你对Nesting机制和behavior有足够的掌控力。

可是我也想问,如果这些如果都能成真的话,干嘛不来一次全新的旅程?

CoordinatorLayout和Nesting机制告诉我们,一次Touch拖动事件,并不是一次性消费的,而是可以被多个View同时消费。如果你涉猎过足够多的系统源码,会知道Nesting机制的核心是MotionEvent有一个bug级的方法offsetLocation。这是一个public方法,我们在处理Touch事件时一样可以调用。

然而无论如何,CoordinatorLayout规规矩矩做事,本本分分做View,跟我们理解的Touch事件分发机制是并不冲突的。

我曾经做过一个试验:

  1. FrameLayout包含两个子View,第一个子View是ScrollView,放在底部;第二个子View是TextView(MATCH_PARENAT)放在顶部,用作遮罩,背景透明;
  2. 我用手指滑动屏幕,ScrollView可以正常滚动;
  3. 将TextView设置成可点击的,setClickable(true),用手指滑动屏幕时,ScrollView无法正常滚动。
  4. 自定义FrameLayout,onInterceptTouchEvent和onTouchEvent在自行处理的同时,也转发给scrollView,scrollView可以正常滑动;

关键代码如下:

public class AlipayContainerLayout extends FrameLayout {

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        scrollView.onInterceptTouchEvent(ev);
        return super.onInterceptTouchEvent(ev);
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        scrollView.onTouchEvent(event);
        return true;
    }
}

你可能会说:这扰乱了Touch事件的分发流程,简直就是在胡搞!
是的,不得不承认这确实是耍流氓,是一种违法行为!呵呵,淡定,不要鸡冻!我能想起很多开源框架,用反射、用Hook的方式欺骗系统、绕过检查等等,跟它们比起来,我们只能算轻微的投机倒把而已(捂脸),不要方!

那么,支付宝的首页刷新是不是可以理解成这样:

  1. FrameLayout包含两个子View,第一个子View是ScrollView,第二个子View是topLayout;
  2. ScrollView顶部留白,占位用;
  3. ScrollView消费Touch事件;如果触摸滑动落在topLayout,则Touch事件由FrameLayout转发给ScrollView;如果触摸滑动落在ScrollView内部,则ScrollView调用自身的Touch消费即可;

感兴趣的同学可以先这么试试看。

可以透露的是,你一定会遇到林林总总的麻烦。不用怕,这些都是考验,走过九九八十一道坎,你会对系统底层的理解更进一步;而且,前文提及offsetLocation是个好东西,能用好这个彩蛋,绝对是一件值得开心的事情。

使用方法

  1. layout布局文件
<com.stone.alipay.library.AlipayContainerLayout
    android:id="@+id/home_container_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    alipay:progressColor="@color/statusBarColor"
    alipay:progressCenterOffset="3dp"
    alipay:progressHeight="@dimen/alipay_progress_height" />
  1. java代码使用
    containerLayout = findViewById(R.id.home_container_layout)
    containerLayout.setDecorator(new AlipayContainerLayout.Decorator() {
        @Override
        public View getContentView() {
            // 内部滑动的scrollView content
            View contentView = initContentView(inflater);
            return contentView;
        }

        @Override
        public View getTopLayout() {
            // 顶部悬浮的topLayout
            topLinearLayout = (TopLinearLayout) initTopLayout(inflater);
            return topLinearLayout;
        }
    });

    // 2. 下拉刷新
    scrollView = containerLayout.getScrollView();
    scrollView.setOnRefreshListener(new AlipayScrollView.OnRefreshListener() {
        @Override
        public void onRefresh() {
            // 下拉刷新回调,请求网络数据
            requestNetwork();
        }
    });

    // 3. 顶部视差效果绑定
    scrollView.setScrollChangeListener(new AlipayScrollView.ScrollChangeListener() {
        @Override
        public void onScrollChange(int scrollY) {
            parallaxScroll(scrollY);
        }
    });
    topLinearLayout.bindParallax(scrollView, topBlueLayout);

demo APK下载

点击下载

alipaypullrefresh's People

Contributors

xmusistone avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.