EditText与NestScrollView嵌套使用时,滑动冲突处理

期望

Android开发中经常会有在一个大页面中,包含一个EditText的情况,一般情况下,大页面会通过NestScrollView或者ScrollView当作根View

于是在布局文件中,我们常常这么写:

<?xml version="1.0" encoding="utf-8"?>  
<androidx.core.widget.NestedScrollView  xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:app="http://schemas.android.com/apk/res-auto"  xmlns:tools="http://schemas.android.com/tools"  android:layout_width="match_parent"  android:layout_height="match_parent"  tools:context=".EditTextScrollActivity">  <LinearLayout  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:orientation="vertical" > 	 <View  android:layout_width="match_parent"  android:layout_height="400dp"  android:background="@android:color/holo_blue_bright"  />  <EditText  android:id="@+id/et"  android:layout_width="match_parent"  android:layout_height="100dp"/>  <View  android:layout_width="match_parent"  android:layout_height="600dp"  android:background="@android:color/holo_red_light"  />  </LinearLayout>  </androidx.core.widget.NestedScrollView>

EditText上下的两个View是为了模拟其他内容,以达到让整个页面显示超过屏幕高度的效果。

在这种情况下,我们根据UI稿设置了一个固定高度的EditText,这时直接运行时会发现一个问题,我们输入了过高的文字时,EditText内的文字无法正常上下划动了。

此时我们提出我们的期望:

  1. EditText内的内容,超出自身的高度时:
    1. 手指上划时,若EditText还没划到底,则划动EditText的内容部分;当Edit Text划到底时,整体页面上划。
    2. 手指下划时,若EditText还没划到顶,则划动EditText的内容部分;当Edit Text划到顶时,整体页面下划。
  2. 当EditText内的内容没有超出自身高度时:
    1. 划动整体页面

实现方案

这是典型的划动冲突问题,解决方案就从事件分发入手了。

如果想要了解事件分发,请查阅我之前发表的博客。

事件分发汇总帖

总之,我们此刻一句话描述我们的处理逻辑:

  1. 若EditText内部内容能够划动,划内部,若EditText内部内容不能划动,划外部。
  2. 如何控制划内部外部?使用requestDisallowInterceptTouchEvent

接下来写一下代码吧!

public class EditTextTouchListener(view: EditText) : OnTouchListener {  private var viewConfig = ViewConfiguration.get(view.context)  private var originalTouchY: Float = 0f  private var originalTouchX: Float = 0f  @SuppressLint("ClickableViewAccessibility")  override fun onTouch(v: View?, event: MotionEvent?): Boolean {  event ?: return false  if (v is EditText) {  when (event.actionMasked) {  MotionEvent.ACTION_DOWN -> {  // 1 按下时,记录一下位置,并请求父布局不要拦截事件v.parent?.requestDisallowInterceptTouchEvent(true)  originalTouchY = event.y  originalTouchX = event.x  }  MotionEvent.ACTION_MOVE -> {  val nowY = event.y  val nowX = event.x  // 计算X方向划动距离val distance = abs(nowX - originalTouchX)  // 如果横向划动已经超过了最小值,交由EditText自己处理if (viewConfig.scaledTouchSlop < distance ) {  return false  }  // 计算竖直方向,如果划动距离小于最小值,交给EditText自己处理if (abs(nowY - originalTouchY) < viewConfig.scaledTouchSlop) {  return false  }  // 执行到此处,那么竖直方向一定划动超过了最小值,此时判断是,向上划动还是向下划动。// 如果当前位置Y大于  初始Y,即手指下划if (nowY > originalTouchY) {  return if (v.canScrollVertically(-1)) {  false  }else {  v.parent?.requestDisallowInterceptTouchEvent(false)  true  }  }else {  // 如果当前位置Y小于 初始Y,即手指上划if (nowY < originalTouchY) {  return if (v.canScrollVertically(1)) {  false  }else {  v.parent?.requestDisallowInterceptTouchEvent(false)  true  }  }  }  }  else -> {  v.parent?.requestDisallowInterceptTouchEvent(false)  }  }  }  return false  }  }

这种实现方案有一个问题:

当划动交给外部之后,便一直由外部处理了:

假设,EditText的内容可以往上划动,那我开始划动,划动到底之后,EditText不能继续往上划了之后,把滑动操作交给了外边的NestScrollView;此时,手不松开,开始反向滑动,EditText也不会滑动里边的内容了。

当然这种已经已经满足我的期望了。

延申

上面的实现方案满足了产品需求、UI需求,但是我在想,还可以实现另一种,就是当手指划出EditView的范围之后,就不再可划。


public class EditTextRangeTouchListener(view: EditText) : OnTouchListener {  private var viewConfig = ViewConfiguration.get(view.context)  private var originalTouchY: Float = 0f  private var originalTouchX: Float = 0f  @SuppressLint("ClickableViewAccessibility")  override fun onTouch(v: View?, event: MotionEvent?): Boolean {  event ?: return false  if (v is EditText) {  when (event.actionMasked) {  MotionEvent.ACTION_DOWN -> {  v.parent?.requestDisallowInterceptTouchEvent(true)  originalTouchY = event.y  originalTouchX = event.x  }  MotionEvent.ACTION_MOVE -> {  val nowY = event.y  val nowX = event.x  val distance = abs(nowX - originalTouchX)  if (nowY < 0 || nowY > v.height) {  v.parent?.requestDisallowInterceptTouchEvent(false)  return true  }  if (viewConfig.scaledTouchSlop < distance ) {  return false  }  if (abs(nowY - originalTouchY) < viewConfig.scaledTouchSlop) {  return false  }  if (nowY > originalTouchY) {  return if (v.canScrollVertically(-1)) {  false  }else {  v.parent?.requestDisallowInterceptTouchEvent(false)  true  }  }else {  if (nowY < originalTouchY) {  return if (v.canScrollVertically(1)) {  false  }else {  v.parent?.requestDisallowInterceptTouchEvent(false)  true  }  }  }  }  else -> {  v.parent?.requestDisallowInterceptTouchEvent(false)  }  }  }  return false  }  }

这种实现方式放到NestScrollView中,划起来还是挺怪的。这个方案不采用了。

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

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

相关文章

HTTP方式在线访问Hadoop HDFS上的文件解决方案

背景&#xff1a; 在做大数据和大模型产品的时候&#xff0c;方式设计的是将文件放在hdfs上进行管理&#xff0c;前几天遇到一个需求&#xff1a;需要通过http的方式去访问hdfs上的问题&#xff0c;以前基本上都是通过hdfs://hadoop01:9000,去访问文件&#xff0c;于是经过一番…

注册表获取autoCAD安装位置

注意事项 注意&#xff1a;①64位操作系统注册表会重定向&#xff0c;RegOpenKeyEx第4个参数得加上KEY_WOW64_64KEY&#xff1b;②RegOpenKeyEx遍历子项时注意第2和第4参数&#xff0c;参考图&#xff1a; ③RegQueryValueEx同样得注意第6参数 完整代码 std::unordered_map…

基于ssm+vue+Mysql的药源购物网站

开发语言&#xff1a;Java框架&#xff1a;ssmJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;Maven3.…

【Redis基础】Redis知识体系详解-Redis概念和基础

1. 什么是Redis Redis是一款用C语言编写的key-value存储系统&#xff08;键值存储系统&#xff09;&#xff0c;支持丰富的数据类型&#xff0c;如&#xff1a;String、list、set、zset、hash。 Redis是一种支持key-value等多种数据结构的存储系统。可用于缓存&#xff0c;事…

SpringBoot / SpringCloud 注册与发现

SpringBoot / SpringCloud EnableDiscoveryClient与EnableEurekaClient区别 在使用Spring Cloud feign使用中在使用服务发现的时候提到了两种注解&#xff0c;一种为EnableDiscoveryClient,一种为EnableEurekaClient,用法上基本一致。 spring cloud中discovery service有许多…

C#(C Sharp)学习笔记_方法(Medthod)【十六】

什么是方法&#xff1f; 在编程中&#xff0c;方法&#xff08;Method&#xff09;是一个执行特定操作的代码块。它是一种将逻辑封装起来的方式&#xff0c;使得代码更加模块化、重用性更高&#xff0c;并且易于维护。以下是方法的一些关键特性&#xff1a; 封装性&#xff1a…

【WEEK10】学习目标及总结【Spring Boot】【中文版】

学习目标&#xff1a; 学习SpringBoot 学习内容&#xff1a; 参考视频教程【狂神说Java】SpringBoot最新教程IDEA版通俗易懂MVC自动配置原理员工管理系统 准备工作首页实现 学习时间及产出&#xff1a; 第十周MON~TUE 2024.4.29【WEEK10】 【DAY1】MVC自动配置原理【中文版…

使用Spring Boot、Redis和Spring Cache实现高效缓存

在当今互联网应用开发中&#xff0c;性能是至关重要的因素之一。随着用户量的增加和数据量的膨胀&#xff0c;有效地管理数据的访问和处理变得愈发重要。 在这个背景下&#xff0c;缓存成为了提升应用性能的常用手段之一。本文将介绍如何利用Spring Boot、Redis以及Spring Cac…

Unity编辑器扩展

Unity编辑器扩展 引言 在游戏开发领域&#xff0c;Unity因其强大的功能和灵活性而备受欢迎。Unity的编辑器扩展能力尤其突出&#xff0c;它允许开发者自定义编辑器界面和功能来满足特定的开发需求。通过编辑器扩展&#xff0c;我们可以优化工作流程&#xff0c;提高生产力&am…

Cokejogo巴西 电子游戏源码 游戏网站源码 电子游戏合集 电子游戏软件下载 游戏源码(带安装教程)

Cokejogo巴西pg电子游戏源码/H5PC端 前端vue编译后后端PHP/修复图片资源失效 后端测试环境&#xff1a;Linux系统CentOS7.6、宝塔、PHP7.2、MySQL5.6&#xff0c;根目录public&#xff0c;伪静态thinkPHP&#xff0c;开启ssl证书 源码下载&#xff1a;https://download.csdn.n…

CUDA内存模型

核函数性能并不只与线程束的执行有关。 CUDA内存模型概述 GPU和CPU内存模型的主要区别是&#xff0c;CUDA编程模型能将内存层次结构更好地呈现给用户&#xff0c;能让我们显示的控制它的行为。 对程序员来说&#xff0c;一般有两种类型的存储器&#xff1a; 可编程的&#x…

JSP和tomcat

JSP&#xff08;JavaServer Pages&#xff09;是一种用于开发动态Web内容的技术&#xff0c;它允许开发者将Java代码嵌入到HTML页面中。JSP页面在服务器端被解析并转换成Servlet&#xff0c;然后由Servlet容器&#xff08;比如Tomcat&#xff09;执行。JSP允许开发者在页面中使…

YOLO系列改进,自研模块助力涨点

目录 一、原理 二、代码 三、添加到YOLOv5中 一、原理 论文地址:

截取视频第一帧当做封面

看了好多处理视频的框架 比如ffmpeg&#xff0c;很多都需要依赖安装第三方插件&#xff0c;比较麻烦&#xff0c;找到一个内嵌进去不需要额外安装的&#xff1a;jcodec 一 首先代码中添加依赖 <!--视频生成预览图用--><dependency><groupId>org.jcodec</…

企业职能部门定岗定编项目如何做?

某国家级高新技术开发区成立于上世纪90年代&#xff0c;位于南方某市&#xff0c;地处三省交界处&#xff0c;是直接由该省委省政府创办的全省首批高新技术开发区。该开发区面积达到300平方公里&#xff0c;辖区人口30万人。历经数十年发展&#xff0c;在省委省政府的高度重视下…

QT:核心控件-QWidget

文章目录 控件enableobjectNamegeometrysetWindowTitleopacitycursorFonttooltipstyleSheet 控件 什么是控件&#xff1f; 如上所示&#xff0c;就是控件&#xff0c;而本篇要做的就是对于这些控件挑选一些比较有用的常用的进行讲解分析 在QT的右侧&#xff0c;会有对应的空间…

unity制作app(1)--登录 注册 界面

把学到的知识投入到生产中反而是一件简单的事情&#xff01; 1.调整canvas的形状&#xff0c;这里和camera没有任何关系! overlay&#xff01; 2.既然自适应&#xff0c;空间按钮的位置比例就很重要了&#xff01; game窗口中新增720*1280的分辨率&#xff01; 3.再回到can…

【论文阅读】ViTAE:Vision transformer advanced by exploring intrinsic inductive bias

ViTAE:Vision transformer advanced by exploring intrinsic inductive bias 论文地址摘要&#xff1a;简介&#xff1a;3 方法论3.1 重温视觉变压器3.2 ViTAE3.3 缩减单元3.4 Normal cell3.5 模型细节 4 训练4.1 Implementation details4.2 Comparison with the state-of-the-…

高速收发器(GTX)文章导航

关于FPGA的开发&#xff0c;大致可以分为算法和接口两类&#xff0c;其中接口又可以分为高速和低速两类&#xff0c;像UART、I2C、SPI、SDRAM、HDMI、LVDS等等&#xff0c;都被归为低速接口类别&#xff0c;最高线速率不过几百Mbps&#xff0c;使用FPGA的普通IO即可实现数据收发…

LeetCode刷题笔记第145题:二叉树的后序遍历

LeetCode刷题笔记第145题&#xff1a;二叉树的后序遍历 题目&#xff1a; 给定一棵二叉树的根节点 root &#xff0c;返回其节点值的后序遍历 。 想法&#xff1a; 后序遍历的是通过对树经过“左右根”的顺序进行遍历。使用递归的方式&#xff0c;先遍历左子树&#xff0c;…