Android TvSettings Bug: 密码框无法点击唤起输入法
概述
Android 10 的Box方案, 默认使用的是TvSettings作为系统设置,输入操作的习惯上是使用鼠标,键盘,遥控,日常的场景是没有问题,也不会出现本文中提及的问题。当外接的USB触摸屏后,出现无法点击WIFI密码框换出输入法进行输入密码操作。
问题:


从图1开始添加WIFI,并准备输入密码时,外接的USB触摸屏没有办法点击唤起输入法。
正常的情况应该如下图所示:

过程
在前面的一些文章中,对于无法点击或响应按键操作的问题,一般可以先查查焦点的问题:
View Hierarchy:DecorView@661bdd7[WifiConnectionActivity]android.widget.LinearLayout{abf86c4 V.E...... ........ 0,0-1920,1080}android.view.ViewStub{e3449ad G.E...... ......I. 0,0-0,0 #10201a2 android:id/action_mode_bar_stub}android.widget.FrameLayout{38444e2 V.E...... ........ 0,0-1920,1080 #1020002 android:id/content}android.widget.FrameLayout{51a6073 V.E...... ........ 0,0-1920,1080 #7f0a0229 app:id/wifi_container}androidx.leanback.app.GuidedStepRootLayout{1904b30 V.E...... ........ 0,0-1920,1080 #7f0a0105 app:id/guidedstep_root}android.widget.FrameLayout{878d3a9 V.E...... ........ 0,0-1920,1080 #7f0a0104 app:id/guidedstep_background_view_root}androidx.leanback.widget.NonOverlappingView{9a5cd2e V.ED..... ........ 0,0-1920,1080 #7f0a0103 app:id/guidedstep_background}android.widget.LinearLayout{fb090cf V.E...... ........ 0,0-1920,1080 #7f0a00a0 app:id/content_frame}androidx.leanback.widget.NonOverlappingFrameLayout{966ea5c V.E...... ........ 0,0-1231,1080 #7f0a009f app:id/content_fragment}com.android.tv.settings.connectivity.setup.GuidanceRelativeLayout{b620165 V.E...... ........ 0,0-1231,1080}android.widget.TextView{e458e3a V.ED..... ........ 168,374-1147,447 #7f0a00f1 app:id/guidance_title}android.widget.TextView{fcf6aeb V.ED..... ........ 168,474-1147,503 #7f0a00ef app:id/guidance_description}androidx.leanback.widget.NonOverlappingFrameLayout{aa65048 V.E...... ........ 1231,0-1919,1080 #7f0a0044 app:id/action_fragment_root}androidx.leanback.widget.NonOverlappingView{4f64ee1 V.ED..... ........ 0,0-688,1080 #7f0a0043 app:id/action_fragment_background}androidx.leanback.widget.NonOverlappingLinearLayout{bee5406 VFE...... ........ 0,0-688,1080 #7f0a0042 app:id/action_fragment}android.widget.RelativeLayout{4b7cac7 V.E...... ........ 0,0-688,1080 #7f0a00ff app:id/guidedactions_root}androidx.leanback.widget.NonOverlappingView{ef428f4 G.ED..... ......ID 0,0-0,0 #7f0a00fd app:id/guidedactions_list_background}androidx.leanback.widget.GuidedActionsRelativeLayout{327f81d V.E...... ........ 0,0-688,1080 #7f0a00f3 app:id/guidedactions_content}androidx.leanback.widget.VerticalGridView{90baa92 V.E...... ........ 0,0-348,1080 #7f0a00fb app:id/guidedactions_list}android.widget.LinearLayout{6dc4c63 VFE...C.. ........ 0,103-348,528}android.widget.FrameLayout{2a4e060 V.E...... ........ 0,293-348,365 #7f0a020f app:id/text_input_wrapper}android.widget.EditText{6d0f919 VFED..... ........ 24,0-324,72 #7f0a00fa app:id/guidedactions_item_title}android.widget.CheckBox{535ddde VFED..C.. ........ 14,377-146,425 #7f0a01ac app:id/password_checkbox}androidx.leanback.widget.NonOverlappingView{93d4bbf G.ED..... ......ID 0,0-0,0 #7f0a0102 app:id/guidedactions_sub_list_background}androidx.leanback.widget.VerticalGridView{e7a28c IFE...... ......I. 0,432-688,432 #7f0a0101 app:id/guidedactions_sub_list}android.widget.RelativeLayout{a6f0dd5 V.E...... ........ 688,0-688,1080 #7f0a0100 app:id/guidedactions_root2}androidx.leanback.widget.NonOverlappingView{f3df9ea V.ED..... ......ID 0,0-0,1080 #7f0a00fe app:id/guidedactions_list_background2}androidx.leanback.widget.NonOverlappingFrameLayout{484e4db V.E...... ......ID 0,0-0,1080 #7f0a00f4 app:id/guidedactions_content2}androidx.leanback.widget.VerticalGridView{6b25b78 V.E...... ......ID 0,0-0,1080 #7f0a00fc app:id/guidedactions_list2}
很明显android.widget.EditText{6d0f919 VFED… … 24,0-324,72 #7f0a00fa app:id/guidedactions_item_title} 不可点击.
通过ID找到相关的代码:
$ grep -r "guidedactions_item_title" packages/apps/TvSettings/Settings
packages/apps/TvSettings/Settings/res/layout/setup_text_input_item.xml: android:id="@+id/guidedactions_item_title"
packages/apps/TvSettings/Settings/res/layout/setup_password_item.xml: android:id="@+id/guidedactions_item_title"
packages/apps/TvSettings/Settings/src/com/android/tv/settings/connectivity/util/GuidedActionsAlignUtil.java: androidx.leanback.R.id.guidedactions_item_title);
packages/apps/TvSettings/Settings/src/com/android/tv/settings/util/GuidedActionsAlignUtil.java: androidx.leanback.R.id.guidedactions_item_title);
packages/apps/TvSettings/Settings/res/layout/setup_password_item.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2017 The Android Open Source ProjectLicensed under the Apache License, Version 2.0 (the "License");you may not use this file except in compliance with the License.You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions andlimitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:clipChildren="false"android:clipToPadding="false"android:orientation="vertical"><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/text_input_wrapper"android:layout_width="match_parent"android:layout_height="@dimen/setup_list_item_height"android:layout_alignParentStart="true"android:layout_marginTop="@dimen/setup_action_vertical_offset"android:background="@drawable/setup_text_input_background"android:elevation="@dimen/setup_elevation"android:gravity="start|center_vertical"android:paddingEnd="@dimen/setup_list_item_padding"android:paddingStart="@dimen/setup_list_item_padding"><EditTextandroid:id="@+id/guidedactions_item_title"style="@style/Setup.Action.TextInput"android:layout_width="match_parent"android:layout_height="match_parent"android:focusable="true"android:gravity="center_vertical"android:imeOptions="actionNext|flagNoExtractUi"android:inputType="text"></EditText></FrameLayout><CheckBoxandroid:id="@+id/password_checkbox"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="@dimen/setup_obfuscation_margin_start"android:layout_marginTop="@dimen/setup_obfuscation_margin_top"android:buttonTint="@color/setup_list_item_background_focused"android:buttonTintMode="src_in"android:text="@string/text_obfuscation_toggle_caption" />
</LinearLayout>
@Overridepublic GuidedActionsStylist onCreateActionsStylist() {return new GuidedActionsStylist() {@Overridepublic void onBindViewHolder(ViewHolder vh, GuidedAction action) {super.onBindViewHolder(vh, action);if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) {PasswordViewHolder viewHolder = (PasswordViewHolder) vh;mTextInput = (EditText) viewHolder.getTitleView();mTextInput.setClickable(true);mTextInput.setFocusableInTouchMode(true);mCheckBox = viewHolder.mCheckbox;mCheckBox.setOnClickListener(view -> {updatePasswordInputObfuscation();EnterPasswordFragment.this.openInEditMode(action);});mCheckBox.setChecked(mUserChoiceInfo.isPasswordHidden());updatePasswordInputObfuscation();openInEditMode(action);}}}@Overridepublic int onProvideItemLayoutId() {return R.layout.setup_password_item;}}
增加
mTextInput.setClickable(true);
mTextInput.setFocusableInTouchMode(true);
编译,解决!
另一种尝试
在这之前,尝试过在XML中设置:
<EditTextandroid:clickable="true"android:focusableInTouchMode="true">
结果:无效??
反复确认了layout文件的正确性无果。
从代码中去一个个追查并不现实,取了个巧,自定一个EditText替换了默认的,并重写了setClickable函数,从中打印出调用的堆栈得知,在GuidedActionsStylist.onBindViewHolder中确实调用了。
GuidedActionsStylist 位于androidx中,
packages/apps/TvSettings/Settings/Android.mk
LOCAL_PACKAGE_NAME := TvSettings
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_CERTIFICATE := platform
LOCAL_MODULE_TAGS := optional
LOCAL_PROGUARD_FLAG_FILES := proguard.cfg
LOCAL_PROGUARD_ENABLED := disabledLOCAL_PRIVILEGED_MODULE := trueLOCAL_STATIC_ANDROID_LIBRARIES := \androidx.recyclerview_recyclerview \androidx.preference_preference \androidx.appcompat_appcompat \androidx.legacy_legacy-preference-v14 \androidx.leanback_leanback-preference \androidx.leanback_leanback \androidx.lifecycle_lifecycle-extensions \androidx-constraintlayout_constraintlayout \
对应的jar包路径:
out/target/common/obj/JAVA_LIBRARIES/androidx.leanback_leanback_intermediates/classes.jar
顺便看下源码:
GuidedActionsStylist.java
public ViewHolder(@NonNull View v, boolean isSubAction) {super(v);mContentView = v.findViewById(R.id.guidedactions_item_content);mTitleView = (TextView) v.findViewById(R.id.guidedactions_item_title);mActivatorView = v.findViewById(R.id.guidedactions_activator_item);mDescriptionView = (TextView) v.findViewById(R.id.guidedactions_item_description);mIconView = (ImageView) v.findViewById(R.id.guidedactions_item_icon);mCheckmarkView = (ImageView) v.findViewById(R.id.guidedactions_item_checkmark);mChevronView = (ImageView) v.findViewById(R.id.guidedactions_item_chevron);mIsSubAction = isSubAction;v.setAccessibilityDelegate(mDelegate);}/*** Binds a {@link ViewHolder} to a particular {@link GuidedAction}.* @param vh The view holder to be associated with the given action.* @param action The guided action to be displayed by the view holder's view.* @return The view to be added to the caller's view hierarchy.*/public void onBindViewHolder(ViewHolder vh, GuidedAction action) {vh.mAction = action;if (vh.mTitleView != null) {vh.mTitleView.setInputType(action.getInputType());vh.mTitleView.setText(action.getTitle());vh.mTitleView.setAlpha(action.isEnabled() ? mEnabledTextAlpha : mDisabledTextAlpha);vh.mTitleView.setFocusable(false);vh.mTitleView.setClickable(false);vh.mTitleView.setLongClickable(false);if (BuildCompat.isAtLeastP()) {if (action.isEditable()) {vh.mTitleView.setAutofillHints(action.getAutofillHints());} else {vh.mTitleView.setAutofillHints((String[]) null);}} else if (VERSION.SDK_INT >= 26) {// disable autofill below P as dpad/keyboard is not supportedvh.mTitleView.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO);}}//....}
从上面的代码可以看出,使用了GuidedActionsStylist后,guidedactions_item_title这个ID的控件会被置为不可点击。
刚好就是前面提及的文本输入框,对头!
引用
android:focusable和android:focusableInTouchMode的区别
GuidedActionsStylist
AndroidX GitHub
AOSP AndroidX Contribution Guide
相关文章:
Android TvSettings Bug: 密码框无法点击唤起输入法
概述 Android 10 的Box方案, 默认使用的是TvSettings作为系统设置,输入操作的习惯上是使用鼠标,键盘,遥控,日常的场景是没有问题,也不会出现本文中提及的问题。当外接的USB触摸屏后,出现无法点击…...
Windows, MacOS还是Linux好?
今天我们来聊一个小话题:选操作系统,是哪个好?今天,我以一个介绍者的身份给大家推荐,我就不出什么点子了。 Windows Windows,是一个老牌的操作系统。他的优处和短处和有很多,我们来介绍一下 优…...
Gateway自定义过滤器——全局过滤器
一、什么是全局过滤器🍉 首先,我们要知道全局过滤器其实是特殊路由过滤器(特殊的GatewayFilter),会有条件地作用于所有路由。 为什么要自定义全局过滤器?就好比是看大门的保安大叔,平时主要是做好进出大门外来人员登记…...
Android App的几个核心概念
Application启动 点击桌面图标启动App(如下流程图) 针对以上流程图示: ActivityManagerService#startProcessLocked()Process#start()ActivityThread#main(),入口分析的地方ActivityThread#attach(),这个里面的逻辑很核心 ActivityManagerS…...
window10安装telnet
1、打开控制面板 2、点击程序和功能 3、点击启用或关闭Windows功能 4、选中Telnet客户端,然后点击确定,然后就可以使用telnent 主机 端口来查看本地是否能连通该主机的该端口。...
大厂sql真题讲解(黑马)
2023 http://yun.itheima.com/open/853.html | 面试宝典-如何备战大厂SQL真题 http://yun.itheima.com/open/858.html | 面试宝典–大厂必考知识开窗函数 http://yun.itheima.com/open/864.html | 面试宝典-详解美团SQL真题 http://yun.itheima.com/open/868.html | 图解大…...
SpringBoot整合EasyExcel实现读操作
😊 作者: 一恍过去 💖 主页: https://blog.csdn.net/zhuocailing3390 🎊 社区: Java技术栈交流 🎉 主题: SpringBoot整合EasyExcel实现读操作 ⏱️ 创作时间: 2023年…...
go mod 设置国内源 windows 环境 win10
启用 go module 功能 go env -w GO111MODULEon 配置 goproxy 变量 go env -w GOPROXYhttps://goproxy.cn,direct 下载包就行了,速度飞快 go mod tidy 检测 goproxy 是否配置好 运行 go env | findstr goproxy 查看 goproxy Go module 从 Go v1.12 版本开始存在&a…...
智能决策支持系统实现的关键技术分析
1.模 型 中 的 关 键 因 素 。 在 按 本 模 型 研 究 开 发 系 统 时 ,应 当 着 重 考 虑 以 下 几 个 因 素 : (1)设 备 保 护 需 求 计 划 。 保 护 需 求 包 括 了 人 员 、 物 质 、 财 务 等 各项 因 素 ; (2)考 虑 设 备 运行 及维修的 历史数据。 这是进 行 模 型 选 择…...
OSS对象存储后端实现+Vue实现图片上传【基于若依管理系统开发】
文章目录 基本介绍术语介绍图片上传方式介绍普通上传用户直传应用服务器签名后直传 OSS对象存储后端实现maven配置文件配置类ServiceController 图片上传前端图片上传组件api页面使用组件组件效果 基本介绍 术语介绍 Bucket(存储空间):用于…...
人工智能学习目录
1、人工智能-电脑如何像人一样思考? 从发展历史到人工智能的应用案例,再到人工智能本质是数学问题,从房价预测问题提出损失函数由参数导致,再由损失函数的最优值入手引入梯度下降法,最后到多参数方程的最优求解。 人工…...
Vue单页面实现el-tree el-breadcrumb功能、el-tree右键点击树节点展示菜单功能、树节点编辑节点字段名称功能
(1) 点击el-tree节点 使用el-breadcrumb展示选中树节点及父项数据 重点:handleNodeClick方法、getTreeNode方法 (2) 选择el-breadcrumb-item设置el-tree节点选中 必须设置属性: current-node-key"currentNodeKey" 、 node-key"id" 重点: 设置…...
C++核心编程之函数高级使用
目录 一、函数的默认参数 二、函数占位参数 三、函数重载 四、函数重载-注意事项 一、函数的默认参数 在C中,函数的形参列表中的形参是可以有默认值的 语法:返回值类型 函数名 (参数默认值){} 示例1: #includ…...
如何创建智能合约游戏系统
区块技术的发展,智能合约成为了一个热门话题。智能合约是一种基于区块技术的自动化合约,它可以自动执行合同中规定的条款,从而实现去中心化的信任和价值传递。在游戏领域,智能合约可以让玩家在游戏中实现各种交易和交互࿰…...
如何用rust实现一个异步channel
目录 前言思路实现功能代码实现 测试先引测试版包测试代码结果与分析思考 尾语 前言 使用通信来共享内存,而不是通过共享内存来通信 上面这句话,是每个go开发者在 处理多线程通信时 的座右铭,go甚至把实现这个理念的channel直接焊在编译器里&…...
gitee上传项目到仓库
目录 一些常用的Git命令切换到其他盘符:列出目录下的所有文件:以树状图的形式显示目录下的文件和子目录:返回上一层目录:写的C#代码文件上传到新建的Git仓库中,可以按照以下步骤进行操作:出现的错误: 一些常…...
day27 贪心算法
1.什么是贪心? 比如10张钞票,有1,5,20,100等面额,取五张,如何取得到数额最多的钱?每次取面额最大的那张钞票;就是每个阶段的局部最优;全局最优就是最后拿到的…...
Java实现字符串反转
起因 自己在刷题的过程中,想把一个字符串翻转一下,便写了下面的代码: String str "abcd";str str.reverse();发现行不通,这是为什么呢? 分析 在Java中,字符串是不可变的对象,这意…...
vue - 常见的性能优化
文章目录 vue使用中常见的性能优化1, v-for 遍历避免同时使用 v-if2, 如果需要使用v-for给每项元素绑定事件时 可以使用事件代理**3, 一些数据不做响应式4,一些页面采用keep-alive缓存组件5,第三方UI库按需导入6&#…...
微服务系列文章 之 Nginx服务状态监控的方法
在Nginx的插件模块中有一个模块stub_status可以监控Nginx的一些状态信息,默认安装可能没有这个模块,手动编译的时候加一下即可。 1. 模块安装 先使用命令查看是否已经安装这个模块: [rootihxb123Z nginx]# ./nginx -V (V大写会显示版本号和…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
