ListView中让TextView中的文字进行单独滚动

TextView不能在ListeView中单独的滚动原因

默认ListView将会拦截MOVE事件向下传递

参见源码

 case MotionEvent.ACTION_MOVE: {
        switch (mTouchMode) {
        case TOUCH_MODE_DOWN:
            int pointerIndex = ev.findPointerIndex(mActivePointerId);
            if (pointerIndex == -1) {
                pointerIndex = 0;
                mActivePointerId = ev.getPointerId(pointerIndex);
            }
            final int y = (int) ev.getY(pointerIndex);
            initVelocityTrackerIfNotExists();
            mVelocityTracker.addMovement(ev);
            if (startScrollIfNeeded((int) ev.getX(pointerIndex), y, null)) {//此处将会拦截事件的传递
                return true;
            }
            break;
        }
        break;
    }

方案

使用NestedScrollChild\NestedScrollParent进行实现
Android 5.0 Lollipop 提供该套功能的API,NestedScrollChild\NestedScrollParent的定义集成到了View,ViewGroup中,V4包中提供向前兼容的API

具体步骤-此处采用集成的API,而未采用直接继承NestedScrollChild/NestedScrollParent

xml文件设置

TextView设置属性:android:nestedScrollingEnable=”true” //允许进行嵌套滚动

代码设置

ListeView中的改写

改写事件拦截条件,默认拦截ACTION_MOVE,不传递给子View
改写实现

/**
* 改写MotionEvent 拦截条件,当子View中有需要请求nested scroll 的时候不进行拦截
*/
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
var superIntecept: Boolean
val actionMasked = ev.actionMasked

//先不改变ListView的默认实现,在下面的代码中根据情况进行拦截修改
superIntecept = super.onInterceptTouchEvent(ev)

    //当进行移动,且有子View需nested scroll,则一定不拦截
    when (actionMasked) {
        MotionEvent.ACTION_MOVE -> {
            //选择性的拦截-有需要配合nested scroll的子View则不拦截,否则拦截
            //nestedScrollAxes默认为SCROLL_AXIS_NONE=0,即没有子View调用startNestedScroll向其进行nestedScroll的请求
            if (nestedScrollAxes and ViewCompat.SCROLL_AXIS_VERTICAL == ViewCompat.SCROLL_AXIS_VERTICAL) {
                val parent = parent
                parent?.requestDisallowInterceptTouchEvent(true)
                return false
            }
        }
    }

    return superIntecept
}

TextView中的改写

改写onTouchEvent,当刚触摸时立即请求NestedScroll ,即调用startNestedScroll(View中已实现)
具体实现
 override fun onTouchEvent(event: MotionEvent?): Boolean {
    var action = event!!.actionMasked
    when (action) {//down之后就开始nested scroll声明,并请求父View不拦截 touch event
        MotionEvent.ACTION_DOWN -> {
            startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL)
            val parent = parent
            parent?.requestDisallowInterceptTouchEvent(true)
        }
    }
    return super.onTouchEvent(event)
}

附-NestedScrollChild/NestedScrollParent使用介绍相关博客

https://blog.csdn.net/chen930724/article/details/50307193
https://blog.csdn.net/lmj623565791/article/details/52204039
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0822/3342.html
https://segmentfault.com/a/1190000002873657

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值