android 关于自定义View在特殊情况下触发setPressed方法(View源码解析)

文章目录

  • 前言
  • 一、为什么样式会变?
  • 二、调试发现原因并解决
    • 1.找到原因
    • 2.解决
  • 总结


前言

最近在负责一些UI相关的工作,测试给到一个UI的bug,说是搜索框在点击的时候,旁边的’‘X’'变成按压的效果了,我转手就把bug转给负责公控的同事了,因为这个搜索框是公控同事提供的,但是公控大佬不一会就找到我说,我这里都是好的鸭,是不是你哪里没用对,我直接就晕乎了,我左看右看也没干啥鸭,于是开始对线,巴拉巴拉…但是问题还是没有解决,于是有了这篇文章.


一、为什么样式会变?

首先公控大佬给我讲了他是怎么做X的按压效果的,就是说监听了搜索框的onTouchEvent事件,然后当onTouchEvent传入的rect包含了X的时候,将其设置为点按效果,其他时候是不会对这个X控件的样式进行改变的,没办法,我只好将公控同事的源码要来,加上日志调试.

二、调试发现原因并解决

1.找到原因

加了日志发现代码并没有走到公控同事的代码逻辑当中,但是进入onTouchEvent事件时,X控件的样式已经变成点按状态了,而公控同事的demo项目,X控件的样式确实并没有改变,鉴定为G.最后监听setPressed的时候发现在点击控件时,会触发 setPressed = true 事件,随后分析VIEW 源码,定位到如下代码位置:

				case MotionEvent.ACTION_DOWN:.....这里忽略部分代码// Walk up the hierarchy to determine if we're inside a scrolling container.boolean isInScrollingContainer = isInScrollingContainer();// For views inside a scrolling container, delay the pressed feedback for// a short period in case this is a scroll.if (isInScrollingContainer) {mPrivateFlags |= PFLAG_PREPRESSED;if (mPendingCheckForTap == null) {mPendingCheckForTap = new CheckForTap();}mPendingCheckForTap.x = event.getX();mPendingCheckForTap.y = event.getY();postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());} else {// Not inside a scrolling container, so show the feedback right away setPressed(true, x, y);checkForLongClick(ViewConfiguration.getLongPressTimeout(),x,y,TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS);}break;

在View.java的源码当中的onTouchEvent方法的MotionEvent.ACTION_DOWN事件,有一个 isInScrollingContainer的醒目判断,并加上了注释,我们继续看下isInScrollingContainer方法

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)public boolean isInScrollingContainer() {ViewParent p = getParent();while (p != null && p instanceof ViewGroup) {if (((ViewGroup) p).shouldDelayChildPressedState()) {return true;}p = p.getParent();}return false;}

可以看到会判断一个shouldDelayChildPressedState方法,然后返回true,到这里基本可以确定这就是我和公控同事触发的不一致的地方,这是一个ViewGroup的方法,点进去过后注释是这样写的:

Return true if the pressed state should be delayed for children or
descendants of this ViewGroup. Generally, this should be done for
containers that can scroll, such as a List. This prevents the pressed
state from appearing when the user is actually trying to scroll the
content. The default implementation returns true for compatibility
reasons. Subclasses that do not scroll should generally override this
method and return false.

我们机翻一下:如果应延迟此ViewGroup的子代或子代的按下状态,则返回true。通常,这应该针对可以滚动的容器(如List)进行。这防止了当用户实际试图滚动内容时出现按下状态。由于兼容性原因,默认实现返回true。不滚动的子类通常应该覆盖此方法并返回false。

2.解决

到了上面这里,我们基本可以明白,这是因为我们搜索框公控的父布局使用的可滑动的控件,导致进入isInScrollingContainer返回true,并触发了setPressed方法,然后改变了控件的样式 为点按状态,针对这个问题,我们有这几种方式可以解决.

  1. 重写公控的这个控件的setPressed方法,每次都返回false
  2. 重写父布局的shouldDelayChildPressedState方法,使其返回false
  3. 更改公控代码对 这种特殊情况做兼容
    前面两种方法改的快,但是不能确保不出其它问题,因此这个问题最后还是由公控大佬对这种情况做兼容,over

总结

通过调试和分析源码,我们找到了问题的原因和解决方法。问题是因为在可滑动的父布局中,触发了setPressed方法,导致控件样式变为点按状态。解决方法有重写setPressed方法、重写shouldDelayChildPressedState方法或者对公控代码做兼容处理。选择合适的解决方法,能够解决这个UI bug。

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

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

相关文章

Mysql常用操作DDL数据库、表操作:

SQl DDl-数据库操作 查询 查询所有数据库 show databases; 查询当前数据库 select database(); 创建 create database [if not exists] 数据库名 [default charset 字符集] [collate 排序规则]; 删除 drop database[if exists] 数据库名; 使用 use 数据库名;…

K8s集群中的Pod调度约束亲和性与反亲和性

前言 在 K8s 集群管理中,Pod 的调度约束——亲和性(Affinity)与反亲和性(Anti-Affinity)这两种机制允许管理员精细控制 Pod 在集群内的分布方式,以适应多样化的业务需求和运维策略。本篇将介绍 K8s 集群中…

运维开发详解:现代IT环境的核心角色

随着信息技术的快速发展和互联网应用的广泛普及,运维开发(DevOps)在现代IT环境中扮演着越来越重要的角色。本文将详细探讨运维开发的概念、历史背景、关键实践、工具和未来趋势,旨在为读者提供全面的理解。 什么是运维开发&#…

labview类编程

1.父类的功能是通用功能,所有子类都含有父类的功能,重写会自动执行一次父类的功能。 2.每个子类都用了父类的注册vi,所以在调用的时候,出来的就是子类注册的vi,也就是window.vi。 3.假如要设计一个父类的vi,首先是保存…

手持高速暴力风扇方案32位单片机

RAMSUN一款低成本的暴力无刷风扇方案,集成无刷电机驱动、电池低压保护等功能的同时,保持较低的待机功耗。 手持高速暴力风扇主控芯片MM32SPIN080C高性能的单电机控制 SOC 产品,集成了运动控制所需的专用模拟外设。包括 12 位高精度 ADC、2 路模拟比较器…

Mac 系统 clion 使用 getline 无法读取文件内容

不知道是 mac 的问题还是 clion 的问题&#xff0c;如下面代码 #include <iostream> #include <fstream>using namespace std;int main() {string file_name "1.txt";std::ifstream file(file_name);if (file.is_open()) {std::string line;while (std…

airtest做web端UI自动化实战

安装 官网下载客户端 airtest库安装 pip install airtest pip install pocoui脚本录制 利用airtest客户端录制脚本 web端辅助插件-selenium windows打开: 设置chrome路径 开始调式录制 脚本运行 # -*- coding: utf-8 -*- """ Time &#xff1a; 2024/5/…

龙迅LT86102UXE HDMI 2.0分配两个HDMI 2.0输出,支持标准4K60HZ,内置MCU供电可自动操作

龙迅LT86102UXE描述&#xff1a; Lontium LT86102UXE HDMI2.0分配器具有1&#xff1a;2的分配器&#xff0c;符合HDMI2.0/1.4规范&#xff0c;最大6Gbps高速数据速率&#xff0c;自适应均衡RX输入和预先强调的TX输出&#xff0c;以支持长电缆应用程序&#xff0c;内部TX通道交…

前端开发——炼金术师的画布:JavaScript在图像处理领域的魔法手册【含代码示例】

炼金术师的画布&#xff1a;JavaScript在图像处理领域的魔法手册【含代码示例】 前言&#xff1a;图像处理的魔法基础基本概念&#xff1a;像素的舞蹈Canvas API&#xff1a;前端的画板 图像处理的咒语&#xff1a;基础操作加载与绘制图像魔法变形&#xff1a;图像裁剪色彩魔法…

用大模型搭建一个自己的新闻小助手

背景 信息快速增长的时代&#xff0c;及时获取到有价值的资讯是一件很必要的事情。已经有各类新闻app和获取信息的渠道了&#xff0c;为什么还需要在构建一个小助手来获取新闻资讯呢&#xff1f;其实原因很简单各类新闻app服务的是具体一类人群&#xff0c;个人和人群还是有偏…

kafka-消费者组-发布订阅测试

文章目录 1、发布订阅测试1.1、创建消费者4并指定组 my_group21.2、列出所有的消费者组1.3、查看 my_group2 组的详细信息1.4、发送第六条消息accomplish1.4.1、查看 my_group1 组的详细信息1.4.2、查看 my_group2 组的详细信息 1、发布订阅测试 接着上一篇点对点博客测试 kafk…

LabVIEW控制Trio控制器

将LabVIEW与Trio控制器结合&#xff0c;可以实现对复杂运动系统的控制和监测。以下是详细的方法和注意事项&#xff1a; 一、准备工作 软件安装&#xff1a; 安装LabVIEW开发环境&#xff0c;确保版本兼容性。 安装Trio控制器的相关驱动程序和软件&#xff0c;如Trio Motion …

出现 Transaction rolled back because it has been marked as rollback-only 解决方法

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 用户反馈的Bug如下所示: Transaction rolled back because it has been marked as rollback-only截图如下: 浏览器终端同样显示: 2. 原理分析 错误表明,在事务的生命周期内,遇到了某个异常或条件,导致该事务被标记…

Shell编程中的循环语句和函数

一、for循环语句 当面对各种列表重复任务时&#xff0c;使用简单的if语句已经难以满足需求&#xff0c;这时就需要for循环语句。for语句的结构为&#xff1a; for 变量 in 取值列表 do 命令序列 done 使用for循环语句时&#xff0c;需要指定一个变量及取值列表&#xff0c;针对…

2、python环境的安装-mac系统下

打开官网&#xff0c;downloads下边有macOS&#xff0c;点击&#xff1a; 选择最新版本&#xff0c;点击&#xff0c;进入下边的页面&#xff0c;一直往下滑&#xff0c;看到files中有个macOS的版本&#xff0c;点击下载 点击下载后是pkg的安装包&#xff0c;点击安装。 一步步…

鸿蒙OS开发:【一次开发,多端部署】(app市场首页)项目

一多应用市场首页 介绍 本示例展示了应用市场首页&#xff0c;页面中包括Tab栏、运营横幅、精品应用、精品游戏等。 本示例使用一次开发多端部署中介绍的自适应布局能力和响应式布局能力进行多设备&#xff08;或多窗口尺寸&#xff09;适配&#xff0c;保证应用在不同设备或…

蓝桥杯第1022题 玩具蛇 基础DFS C++ Java

题目 思路和解题方法 问题理解&#xff1a;此题要求找出将一条由16节正方形构成的玩具蛇放入4x4的方格中的不同方式数。每节蛇可以是直线或直角转弯&#xff0c;且蛇的形状需要完全覆盖盒子里的16个格子&#xff0c;每个格子仅被蛇的一个部分占据。 状态表示&#xff1a;使用一…

爷爷看了都会,打工人必备的摸鱼AI神器!免费!

去年&#xff0c;AI技术无疑成为了最为引人注目的焦点&#xff0c;层出不穷的创新应用令人目不暇接。尽管许多人对这股AI热潮的持久性持怀疑态度&#xff0c;但现实却用事实给予了最有力的反驳。AI所展现出的强大生产力&#xff0c;足以令人刮目相看。 而今年以来&#xff0c;…

springboot链接kafka异步发送消息

<dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId></dependency> spring:kafka:bootstrap-servers:- ip:端口producer:retries: 0acks: 1batch-size: 16384properties:linger:ms: 100buff…

centos 记录用户登陆ip和执行命令

centos 记录用户登陆ip和执行命令 在/etc/profile 文件末尾添加如下代码&#xff1a; #!/bin/bash USER_IPwho -u am i 2>/dev/null | awk {print $NF} | sed -e s/[()]//g HISTDIR/usr/share/.history if [ -z "$USER_IP" ]; then USER_IPhostname fi…