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

news2024/9/28 13:35:40

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

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

效果图

XML布局

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

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <View
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:background="#666600"/>

            <View
                android:layout_width="match_parent"
                android:layout_height="300dp"
                android:background="#660000"/>

            <com.hbh.swipecaptchademo.VerticalScrollTextView
                android:id="@+id/test"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="123\n\n\n\n154\n\n5484\n\n\n12\n8484\n\n121\n\niailll "
                android:textSize="16sp"
                android:textColor="@color/black"
                android:maxLines="6"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                />

            <View
                android:layout_width="match_parent"
                android:layout_height="300dp"
                android:background="#660000"/>

            <View
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:background="#666600"/>

        </LinearLayout>

    </androidx.core.widget.NestedScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>

源码如下:

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

  1. 当动作为 MotionEvent.ACTION_DOWN 时,会调用isNeedScroll方法,如果需要滚动,则设置 mNeedScrollFlag 为 true,并设置滚动方法和垂直滚动条,同时记录Y轴坐标。
  2. 当动作为 MotionEvent.ACTION_MOVE 时,如果需要滚动并且触摸点的纵坐标发生了变化,则计算滚动方向并检查是否可以垂直滚动。如果可以垂直滚动的状态发生了变化,则更新状态并请求父视图不拦截触摸事件;当TextView滚动到边界的时候,就会通知父视图,触摸事件重新由它处理,这时也会将mNeedScrollFlag设置为false,代表此次的触摸事件将不再滑动TextView。
  3. 当动作为 MotionEvent.ACTION_UP 时,重置标志位。
class VerticalScrollTextView : AppCompatTextView {

    private var mNeedScrollFlag = false
    private var mLastScrollFlag = false
    private var mLastY = 0F

    constructor(context : Context) : super(context)
    constructor(context : Context, attrs : AttributeSet?) : super(context, attrs)
    constructor(context : Context, attrs : AttributeSet?, defStyleAttr : Int) : super(context, attrs, defStyleAttr)

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        event?.run {
            when (action) {
                MotionEvent.ACTION_DOWN -> {
                    if (isNeedScroll()) {
                        mNeedScrollFlag = true
                        movementMethod = ScrollingMovementMethod.getInstance()
                        isVerticalScrollBarEnabled = 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 < lineCount)) or ((maxHeight > 0) and (maxHeight <= height))
    }

}

总结

对自己写的自定义View做一个记录,方便以后的使用,也希望可以帮助大家解决类似的情况。创作不易,觉得不错的话,就来个一键三连吧,感谢大家!
  未经许可,请勿转载!
本文链接:[https://blog.csdn.net/weixin_44337681/article/details/130864426]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/570932.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python 的APScheduler配置的定时任务会被Miss掉

背景 python 的APScheduler配置的定时任务会被Miss掉&#xff0c;经常在控制台收到一些Miss的告警信息&#xff0c;就觉得是任务太多导致的&#xff0c;为了定位到具体的原因&#xff0c;看了一些源码&#xff0c;了解到了定时任务的6大模块的协同工作模式。异常信息及来源 异…

01.GATK人种系变异最佳实践SnakeMake流程:WorkFlow简介

<~生~信~交~流~与~合~作~请~关~注~公~众~号生信探索> 学习的第一个GATK找变异流程&#xff0c;人的种系变异的短序列变异&#xff0c;包括SNP和INDEL。写了一个SnakeMake分析流程&#xff0c;从fastq文件到最后的vep注释后的VCF文件&#xff0c;关于VCF的介绍可以参考上一…

Windows 安装 GCC

文章目录 GCC 是什么&#xff1f;GCC 和 gcc 什么关系&#xff1f;Windows 安装 GCC选型下载安装配置环境变量验证 参考文献 GCC 是什么&#xff1f; GCC&#xff08;GNU Compiler Collection&#xff09;是一个开源的编译器套件&#xff0c;由 GNU 项目开发和维护。 GNU 编译…

悠可集团再获金鼠标3项大奖,自研营销工具助推全渠道数字营销

5月19日,第14届金鼠标数字营销大赛评选结果揭晓,悠可集团斩获3项大奖,其中悠可集团被评为“年度数字营销杰出代理商”,悠可DTC团队自主研发的智能广告投放引擎Turbo Media及点正科技申报的KOL优先自动化工具均荣获“年度最佳数字营销工具”奖项。 据主办方介绍,本届金鼠标数字营…

java基础 - jvm 堆、栈、方法区 java 内存模型

一、 概览 在进入主题前&#xff0c;我们先了解一些相关的知识&#xff0c;方面后面对运行时数据区进行分类。 进程中&#xff0c;有很多数据是多线程之间共享的&#xff0c;线程在执行时&#xff0c;会先从主存中读取数据&#xff0c;然后复制一份到高速缓存中&#xff0c;当…

【Docker容器】Docker安装Kibana详细步骤(看完这一篇就够啦!)

前言 安装Kibana的版本一定要跟ElaticSearch的版本是一样的&#xff0c;这样才不会容易出问题。 安装ElasticSearch请点击以下链接前去学习。 【Docker容器】Docker安装ElasticSearch详细步骤(看这一篇就够啦&#xff01;) 安装 1.访问镜像官网 https://hub.docker.com/ 搜索…

Java的内存模型(Java Memory Mode,JMM)

并发编程模型的两个关键问题 线程之间如何通信及线程之间如何同步。 线程之间如何通信&#xff1a;共享内存&#xff0c;消息传递线程之间如何同步通信是指线程之间以何种机制来 交换信息同步是指程序中用于控制不同线程间 操作发生相对顺序 的机制在共享内存的并发模型里&a…

【PHP图片托管】免费CFimagehost图床源码搭建私人图床 - 无需数据库

文章目录 1.前言2. CFImagehost网站搭建2.1 CFImagehost下载和安装2.2 CFImagehost网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar临时数据隧道3.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 4.公网访问测…

C#入门:编写运行第一个Windows窗体应用程序Helloworld_WinForm

下载及安装Visual Studio的链接&#xff0c;具体见C#入门&#xff1a;编写运行第一个C#程序Helloworld 目录 下载.NET桌面开发组件创建新项目添加控件编辑程序运行查看效果补充 下载.NET桌面开发组件 Visual Studio中需下载安装.NET桌面开发组件。 创建新项目 创建项目&…

【2】Jmeter获取token,模拟多用户并发及token存储文本文件

按以下步骤来&#xff0c;以下各种处理程序的放置位置很重要&#xff01;&#xff01;不然会出现各种问题&#xff1a; 1、setup线程组 前置获取token的接口&#xff08;login&#xff0c;以下都用login表示获取token接口&#xff09;请求&#xff0c;获取类似token等后续需要…

10 个对 Android 开发者有用的 Kotlin 扩展函数 #2

10 个对 Android 开发者有用的 Kotlin 扩展函数 #2 通过出色的 Kotlin 扩展提高您的工作效率 EditText 通过EditText的“text”属性&#xff0c;您可以快速获取EditText中的文本。但是&#xff0c;这个文本是“可编辑”的&#xff0c;因此每次都需要将其转换为字符串才能获…

前端食堂技术周刊第 83 期:TS 5.1 RC、Nuxt 3.5、INP、Knip、管理 GitHub 通知、WebXR

By Midjournery 美味值&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f; 口味&#xff1a;杏花乌龙拿铁 食堂技术周刊仓库地址&#xff1a;https://github.com/Geekhyt/weekly 本期摘要 TypeScript 5.1 RCNuxt 3.5INP 将成为新的 Core Web…

SSM 如何使用 Seata 框架实现分布式事务?

SSM 如何使用 Seata 框架实现分布式事务&#xff1f; 分布式事务是现代分布式系统中必不可少的一部分&#xff0c;而 Seata 框架是一种常用的分布式事务处理方式。在 SSM 框架中&#xff0c;我们可以使用 Seata 框架来管理分布式事务。本文将介绍如何在 SSM 框架中使用 Seata …

好用工具第2期:手机电脑传文件LocalSend

1. 概要 LocalSend 是一个跨平台的 AirDrop替工具软件。 适用于手机电脑之间的数据文件传输&#xff0c;不需要互联网连接或第三方服务器&#xff0c;是局域网本地通信的快速可靠解决方案。 LocalSend 是一个开源项目, 项目地址是: https://github.com/localsend/localsend …

webpack简单的搭建和使用

随便创建一个空的文件夹&#xff0c;例如说&#xff1a;explore 然后我们测试一下我们的node是否存在 可以正确打印出版本 我们再次输入&#xff1a;npm init -y 创建一个package.json文件 出现这样的情况就成功了 然后我们要安装webpack在终端上输入命令&#xff1a; npm i …

辅助生成: 低延迟文本生成的新方向

大型语言模型如今风靡一时&#xff0c;许多公司投入大量资源来扩展它们规模并解锁新功能。然而&#xff0c;作为注意力持续时间不断缩短的人类&#xff0c;我们并不喜欢大模型缓慢的响应时间。由于延迟对于良好的用户体验至关重要&#xff0c;人们通常使用较小的模型来完成任务…

Kotlin SOLID 原则

Kotlin SOLID 原则 许多 Kotlin 开发者并不完全了解 SOLID 原理&#xff0c;即使他们知道&#xff0c;他们也不知道为什么要使用它。您准备好了解所有细节了吗&#xff1f; 介绍 亲爱的 Kotlin 爱好者&#xff0c;您好&#xff01;欢迎来到我的新文章。今天我要讲的是 Kotli…

Qt编程基础 | 第六章-窗体 | 6.2、VS导入资源文件

一、VS导入资源文件 1.1、导入资源文件 步骤一&#xff1a; 将所有图片放到各自文件夹下&#xff0c;并将文件夹拷贝到资源文件&#xff08;.qrc文件&#xff09;的同级目录下&#xff0c;如下&#xff1a; 步骤二&#xff1a; 新建VS项目的时候&#xff0c;系统会自动建好一…

如何在华为OD机试中获得满分?Java实现【最差产品奖】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…

NetApp AFF C 系列——可持续、可扩展且安全可靠的全闪存解决方案

NetApp AFF C 系列 采用全新的闪存技术&#xff0c;同时辅以智能科技加持&#xff0c;将为您带来一个更为经济实惠的全闪存解决方案&#xff0c;它重新定义了安全性、可扩展性和可持续性。 为什么选择 AFF C 系列的新一代全闪存解决方案&#xff1f; 实现现代化&#xff0c;打…