BounceScrollView 引发的思考

作者: Hello_Google | 来源:发表于2016-05-13 15:24 被阅读1220次

前言

近期看了几篇关于 ScrollView 回弹的文章,比如下面几篇

android 滚动条下拉反弹的效果(类似微信朋友圈)

ScrollView反弹效果 仿小米私密短信效果

Android ScrollView反弹效果的实现

android 实现反弹效果的ScrollView

可以看到,这几篇实现的原理,嗯,都是大同小异。但是,如果仔细看看网友的回复以及评论后,你会发现,好像这个是存在些许不完美的地方,并且我也遇到了。下面讲讲我复现的问题

复现

Step One

我的布局如下

<com.lib.bounceScrollView
    android:id="@+id/bs_test"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusable="true"
    android:focusableInTouchMode="true">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rc_test"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>

</com.lib.bounceScrollView>

ScrollView 中嵌套了 RecyclerView

Step Two

上面的 RecyclerView 中的模拟数据如下

/**
 * 初始化数据
 */
private void initData(){
    for(int i = 0; i < 5; i ++){
        List<String> url = new ArrayList<>();
        url.add("http://g.hiphotos.baidu.com/image/pic/item/c75c10385343fbf25431e823b27eca8065388f95.jpg");
        url.add("http://g.hiphotos.baidu.com/image/pic/item/960a304e251f95ca2f34115acd177f3e6609521d.jpg");
        mLists.add(url);
    }
}

就是利用 Fresco 加载图片,用一个循环添加多条数据

Step Three

首先是模拟 RecyclerView 里面的数据高度不超过 ScrollView 的高度,效果如下:

可以看到,当我在下面空白区域进行上下拖动的时候,是有明显的回弹效果的;但是当点击图片上下拖动时,是不会存在回弹效果的(这个 Bug 也是大家发现最多的)

其次,模拟 RecyclerView 里面的数据高度超过 ScrollView 的高度,效果如下:

可以看出,当上滑到底部和头部的时候,是没有回弹效果的(这个 Bug 是我在使用 RecyclerView 后发现的,当我使用自定义 View 的时候没有发现)

why

从博客主那里,并没有得到相关的解释,那么我们就自己想想这究竟是为什么?

从上面的失败情况来看,很大的可能就是事件冲突导致的,大家可以想想整个事件的一个基本流程 ScrollView --> RecyclerView --> ItemView,尤其从未超过 ScrollView 高度来看,是最明显的:首先点击 ScrollView 的其他空白区域,可以明显的进行拖动显示回弹效果;但点击图片的位置上线拖到却没有效果,说明 ACTION_DOWN、ACTION_MOVE、ACTION_UP 等相关事件肯定存在被 RecyclerView 的 Item 的布局所消费。

解决

Step One

带着怀疑的态度,我在 ScrollView 中做了如下的更改

/**
* 用于解决事件冲突
* @param ev 事件
* @return 是否拦截
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int offset = inner.getMeasuredHeight() - getHeight();//子布局总长度是否超过了scrollview的高度
if (offset <= 0) {//未超过
boolean intercepted = false;
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
intercepted = false;
break;
case MotionEvent.ACTION_MOVE:
intercepted = true;
break;
case MotionEvent.ACTION_UP:
intercepted = false;
break;
}
return intercepted;
}
else {//超过
return super.onInterceptTouchEvent(ev);
}
}

运行效果在 未超过 ScrollView 的情况下运行良好,但是,超过 ScrollView 的高度后,存在问题,如下图所示

可以看到,滑倒顶部或者头部,还是有问题(但是嵌套我写的一个自定义布局中,表现良好),说明事件分发没有写好

首先,上下滑动的事件 RecyclerView 自己就支持(而我写的自定义布局,需要使用到 Scrollview,二者的区别),而 ScrollView 自己也是支持这个的,所以二者存在冲突

Step Two

既然这样,我们既要支持 RecyclerView 的上下滑动,也要支持 ScrollView 滑倒底部和顶部的拖动效果,那么解决方法如下

/**
 * solve the problem for not support little view to bounce
 * @param ev event
 */
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    super.onInterceptTouchEvent(ev);
    boolean intercepted = false;
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            intercepted = false;
            break;
        case MotionEvent.ACTION_MOVE:
            intercepted = true;
            break;
        case MotionEvent.ACTION_UP:
            intercepted = false;
            break;
    }
    return intercepted;
}

运行情况 如下

嵌套子 View 超过 ScrollVeiw 高度嵌套子 View 超过 ScrollVeiw 高度 嵌套子 View 未超过 ScrollVeiw 高度嵌套子 View 未超过 ScrollVeiw 高度

运行良好,Bingo。(这个过程中,还要解决 onClick 事件冲突,整个过程比较坎坷)该代码已传 Github,可以看看写的示例。

另外,在定义布局中,事件的分发机制是一个重点也是一个难点更是面试过程中的“考点”,大家一定要把这方面理解吃透,补充一个自己之前写的一个理解性的项目,希望对大家有帮助。

总结

现在的开源环境很良好,但是总会有很多的 Bug,所以大家在发现问题后,一方面可以咨询原主,但是最大的方面,还是要靠我们自己解决,要不然总是在 Copy 中,很难锻炼自己。

相关文章

  • BounceScrollView 引发的思考

    前言 近期看了几篇关于 ScrollView 回弹的文章,比如下面几篇 android 滚动条下拉反弹的效果(类似...

  • 引发的思考

  • 引发的思考

    一、 每天进店的各色人群中,我根据他们的行为举止大概可以归纳他们的品性怎么样: 有的人结账的时候,十分的客气,他们...

  • 造纸行业

    纸巾引发的思考

  • 引发思考

    今天参加了远道而来的学习培训班,学习用NLP的技术解决,企业文化与管理脱节的问题。 这是一个历时三个小时的培训课堂...

  • 引发思考

    刚刚步入职场,慢慢的发现一切都和以前的学生生涯有所不同。 当学生的时候可以默默地做自己喜欢的事,不用担心该是自己的...

  • 引发思考

    知乎链接-1,每天什么都不想做怎么办 知乎链接-2,人迷茫的时候该干什么

  • 引发思考

    阅读新记录 雨泽今天晚上主动给妈妈讲故事,偶尔会有不认识的字,让妈妈告诉他, 今天在学校自己阅读《大卫,不可以》,...

  • 引发思考

    世界杯以来,每天凌晨来自楼上一个男人的呐喊,漂亮!哎吆!TMD! 对这种狂热或者爱好或者是球迷不提倡,或者激动或者...

  • 从“思考”引发的思考

    下面的图片是几个六年级孩子读书之后向老师提出的问题。他们的老师在强制读《史记》,过后的交流方式就是提问,学生...

网友评论

    本文标题:BounceScrollView 引发的思考

    本文链接:https://www.haomeiwen.com/subject/vmqmrttx.html