Android自定义View:超过最大高度时支持滚动并且解决滑动冲突的TextView

您所在的位置:网站首页 数据采集转换网关怎么弄 Android自定义View:超过最大高度时支持滚动并且解决滑动冲突的TextView

Android自定义View:超过最大高度时支持滚动并且解决滑动冲突的TextView

2023-07-10 22:57| 来源: 网络整理| 查看: 265

VerticalScrollTextView:超过最大高度时支持滚动并且解决滑动冲突的TextView

正如标题所说,这个自定义TextView在它的行数超过最大行数或是高度超过最大高度限制时,会将TextView设置为可纵向滑动的状态,如果没有超过限制,它还是跟普通的TextView保存一致。当滚动到边界时,自动将滑动事件归还给父布局。

效果图 XML布局

当TextView的外层是一些滚动布局时,直接让TextView简单地支持滑动是解决不了问题的,因为这时就会有滑动冲突的问题。 这时VerticalScrollTextView就派上用场了,我们在ScrollView的内部添加一个VerticalScrollTextView,布局代码如下:

源码如下:

VerticalScrollTextView代码解释 : 实现了默认的3个构造方法,在构造方法内部支持了TextView的滚动设置; 内部有一个 isNeedScroll 方法,用于判断是否需要滚动。如果最大行数大于0且小于实际行数,或者最大高度大于0且小于等于实际高度,则需要滚动; 有3个全局参数:mNeedScrollFlag、mLastScrollFlag、mLastY。 同时重写了 onTouchEvent 方法,对用户的屏幕操作进行处理:

当动作为 MotionEvent.ACTION_DOWN 时,会调用isNeedScroll方法,如果需要滚动,则设置 mNeedScrollFlag 为 true,并设置滚动方法和垂直滚动条,同时记录Y轴坐标。当动作为 MotionEvent.ACTION_MOVE 时,如果需要滚动并且触摸点的纵坐标发生了变化,则计算滚动方向并检查是否可以垂直滚动。如果可以垂直滚动的状态发生了变化,则更新状态并请求父视图不拦截触摸事件;当TextView滚动到边界的时候,就会通知父视图,触摸事件重新由它处理,这时也会将mNeedScrollFlag设置为false,代表此次的触摸事件将不再滑动TextView(变量orientation是判断当前的滑动方向,canScrollVertically方法是判断当前方向是否可继续滑动)。当动作为 MotionEvent.ACTION_UP 时,重置标志位。 class VerticalScrollTextView : AppCompatTextView { private var mNeedScrollFlag = false private var mLastScrollFlag = false private var mLastY = 0F constructor(context : Context) : this(context, null) constructor(context : Context, attrs : AttributeSet?) : this(context, attrs, 0) constructor(context : Context, attrs : AttributeSet?, defStyleAttr : Int) : super(context, attrs, defStyleAttr) { isVerticalScrollBarEnabled = true movementMethod = ScrollingMovementMethod.getInstance() } override fun onTouchEvent(event: MotionEvent?): Boolean { event?.run { when (action) { MotionEvent.ACTION_DOWN -> { if (isNeedScroll()) { mNeedScrollFlag = true mLastY = rawY } } MotionEvent.ACTION_MOVE -> { if (mNeedScrollFlag and (rawY != mLastY)) { val orientation = if (rawY - mLastY > 0) -1 else 1 val scrollFlag = canScrollVertically(orientation) if (scrollFlag != mLastScrollFlag) { parent.requestDisallowInterceptTouchEvent(scrollFlag) mLastScrollFlag = scrollFlag if (!scrollFlag) mNeedScrollFlag = false } mLastY = rawY } } MotionEvent.ACTION_UP -> { mNeedScrollFlag = false mLastScrollFlag = false } } } return super.onTouchEvent(event) } private fun isNeedScroll() : Boolean { return ((maxLines > 0) and (maxLines 0) and (maxHeight


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3