ListView 嵌套 ListView,为什么里面的 ListView 不能滑动

10 篇文章 0 订阅
3 篇文章 0 订阅

ListView 嵌套 ListView,child 是不能滑动的,为什么呢?我们来看看。

一、源码分析

ListView 的滚动在 scrollIfNeeded() 方法中实现。

scrollIfNeed() 方法的调用:

  • startScrollIfNeeded() 里返回 true 时
    • onTouchMove() 里 mTouchMode == DOWN、TAP、DONE_WAITING 时
      • onTouceEvent() 处理 MOVE 事件时
    • onInterceptTouchEvent() 处理 MOVE 事件时
  • onTouchMove() 里 mTouchMode == SCROLL、OVERSCROLL 时
    • onTouceEvent() 处理 MOVE 事件时

mTouchMode 变为 SCROLL 的时机:

  • startScrollIfNeeded() 返回 true 时
    • onTouchMove() 里 mTouchMode == DOWN、TAP、DONE_WAITING 时
      • onTouceEvent() 处理 MOVE 事件时
    • onInterceptTouchEvent() 处理 MOVE 事件时
  • scrollIfNeeded() 里 mTouchMode == OVERSCROLL 时
    • startScrollIfNeeded() 同上
    • onTouchMove() mTouchMode == SCROLL、OVERSCROLL 时
      • onTouchEvent() 处理 MOVE 事件时
  • onTouchDown 里 mTouchMode == FLING 时
    • onTouchEvent() 处理 DOWN 事件时
  • FlingRunnable (不常用,先忽略)

startScrollIfNeeded() (AbsListView 类)返回 true 的条件:
在这里插入图片描述

  • overscroll
    一般情况下 mScrollY 都是 0,所以 overscroll 都是 false。
  • distance > mTouchSlop
    mTouchSlop 一般是 8,正常的滑动都会大于,所有一般是 true。
  • 滚动轴
    要是竖向滚动。

所以竖向的正常滚动,startScrollIfNeeded() 都会返回 true。

二、结论

2.1 不做处理的 ListView 嵌套 ListView

  • 正常滑动的 MOVE 事件
    父 ListView 的 onInterceptTouchEvent() 中,startScrollIfNeeded() 返回 true,触摸事件由父亲拦截。
    随后 mFirstTouchTarget 被置空(dispatch 方法中),之后的 MOVE 事件直接交给父 ListView,不传递给 child。

  • 按住不动的 MOVE 事件
    父 ListView 的 onInterceptTouchEvent() 中,startScrollIfNeeded() 返回 false,触摸事件传给 child。
    随后 mFirstTouchTarget 被赋值(child 的 onTouchEvent() 方法中),之后 dispatch 给 child 的事件不走 onInterceptTouchEvent。
    但 child 的 touchMode == TOUCH_MODE_DONE_WAITING,所以也不会调到 scrollIfNeeded。

2.2 重写父 ListView 的 onInterceptTouchEvent(),使其返回 false

  • 正常滑动的 MOVE 事件
    父 ListView 的 onInterceptTouchEvent() 返回 false,触摸事件传给 child。
    随后 mFirstTouchTarget 被赋值(child 的 onTouchEvent() 方法中),之后 dispatch 给 child 的事件不走 onInterceptTouchEvent。
    同时 child 会调父 ListView 的 requestDisallowInterceptTouchEvent(),之后 dispatch 给父 ListView 的事件不走 onInterceptTouchEvent。

  • 按住不动的 MOVE 事件
    父 ListView 的 onInterceptTouchEvent() 返回 false,触摸事件传给 child。
    随后 mFirstTouchTarget 被赋值(child 的 onTouchEvent() 方法中),之后 dispatch 给 child 的事件不走 onInterceptTouchEvent。的 onInterceptTouchEvent。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值