Android中涉及到的焦点问题,focusable,clickable,enabled

android的focusableInTouchMode和focusable 默认情况下,这是“自动”,它允许框架确定用户是否可以将焦点 移动到视图。如果视图确实如此,则该视图在单击时可以获得焦点,并且可以保持,如果单击另一个未将此属性设置为 true 的视图,则获得焦点。android:focusableInTouchMode = false,默认值,表示只有在焦点模式下,视图才能获取焦点。android:focusableInTouchMode = true,表示用户,可以通过触摸获取焦点。android:focusable=”true” 表示控件可以获取焦点。 阅读详情

先摘抄下stackoverflow上一个启发了我的回答:

try by Changing your code as:


private OnClickListener saveButtonListener = new OnClickListener() {


    @Override
    public void onClick(View v) {
                Text1.clearFocus();
                Text2.clearFocus();
                saveButton.requestFocus(); //or any other View
    }


}
because as doc as about public void clearFocus () :


Called when this view wants to give up focus. If focus is cleared onFocusChanged(boolean, int, android.graphics.Rect) is called.


Note: When a View clears focus the framework is trying to give focus to the first focusable View from the top. Hence, if this View is the first from the top that can take focus, then all callbacks related to clearing focus will be invoked after wich the framework will give focus to this view.
means you must set Focus to other view on button click because Text1 act as first View in your layout


意思就是说,当EditText的clearfocus清除焦点的时候,框架更倾向于把焦点给试图层上的第一个能够获取焦点的view

其实View的属性里有一下配置分别对应不同的事件

android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="true"
android:enabled="true"

android:state_enabled="false"
android:state_pressed="true"
android:state_focused="true"

很熟悉这些东西,比较常用到的地方是在drawable文件下配置一个背景的selector.xml的时候有配置当获得焦点时显示什么背景,按下去什么背景,enabled为false什么背景。

但是开发项目中,我遇到的场景是:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.widget.TitleBar
        android:id="@+id/title_bar"
        android:layout_width="match_parent"
        android:layout_gravity="top"
        android:layout_height="49dp" >

        <TextView
            android:id="@+id/titlebar_save"
            android:layout_width="60dp"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
<span style="white-space:pre">	</span>    android:focusable="true"
        android:focusableInTouchMode="true"
            android:background="@drawable/titlebar_btn_bg_selector"
            android:gravity="center"
            android:text="保存"
            android:textColor="@color/common_white"
            android:textSize="17sp" />
    </com.widget.TitleBar>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="49dp"
        android:scrollbars="none" >

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

            <RelativeLayout
                android:id="@+id/account_head_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingBottom="25dp"
                android:paddingLeft="12dp"
                android:paddingRight="12dp"
                android:paddingTop="25dp" >

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:text="头像"
                    android:textColor="@color/black_333333"
                    android:textSize="16sp" />
                
                <ImageView
                    android:id="@+id/ico_set_arrow"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:background="@color/transparent"
                    android:src="@drawable/ico_set_arrow"
                    android:layout_centerVertical="true"
                    android:layout_marginLeft="12dp"/>
                <com.widget.RoundedImageView
                    android:id="@+id/account_head"
                    android:layout_width="76dp"
                    android:layout_height="76dp"
                    android:layout_centerVertical="true"
                    android:layout_toLeftOf="@id/ico_set_arrow"
                    android:scaleType="centerCrop"
			        android:src="@drawable/default_head" />
            </RelativeLayout>


                <include
	                style="@style/setting_dividing_line_style"
	                android:layout_width="match_parent"
	                android:layout_height="1.5dp"
	                android:layout_marginLeft="12dp"
	                android:layout_marginRight="12dp"
	                android:layout_marginTop="10dp"
	                layout="@layout/widget_horizontal_dividing_line" />
                
                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="50dp"
                    android:paddingLeft="12dp"
                    android:paddingRight="20dp" >

                    <TextView
                        style="@style/setting_item_text_style"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentLeft="true"
                        android:layout_centerVertical="true"
                        android:text="昵称" />
                    
                    <LinearLayout android:layout_width="0dp"
			            android:layout_height="0dp"
			            android:focusable="true"
			            android:focusableInTouchMode="true">
			            <requestFocus />
			        </LinearLayout>

                    <com.widget.CustomInputBox
                        android:id="@+id/account_nickname"
                        android:layout_width="120dp"
                        android:layout_height="match_parent"
                        android:singleLine="true"
                        android:paddingTop="5dp"
                        android:gravity="center_vertical"
                        android:layout_alignParentRight="true"
                        android:layout_centerVertical="true"
                        android:background="@color/transparent" />
                </RelativeLayout>

                <include
                    style="@style/setting_dividing_line_style"
                    android:layout_width="match_parent"
                    android:layout_height="0.5dp"
                    android:layout_marginLeft="12dp"
                    android:layout_marginRight="12dp"
                    layout="@layout/widget_horizontal_dividing_line" />

                <RelativeLayout
                    android:id="@+id/account_sex_layout"
                    android:layout_width="match_parent"
                    android:layout_height="50dp"
                    android:paddingLeft="12dp"
                    android:paddingRight="20dp" >

                    <TextView
                        style="@style/setting_item_text_style"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentLeft="true"
                        android:layout_centerVertical="true"
                        android:text="性别" />

                    <TextView
                        android:id="@+id/account_sex"
                        style="@style/account_item_text_style"
                        android:layout_width="80dp"
                        android:layout_height="match_parent"
                        android:gravity="center_vertical|right"
                        android:layout_alignParentRight="true"
                        android:layout_centerVertical="true"
                        android:text="保密" />
                </RelativeLayout>
                
                <include
                    style="@style/setting_dividing_line_style"
                    android:layout_width="match_parent"
                    android:layout_height="0.5dp"
                    android:layout_marginLeft="12dp"
                    android:layout_marginRight="12dp"
                    layout="@layout/widget_horizontal_dividing_line" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="40dp"
                android:orientation="vertical"
                android:paddingRight="0dp"
                android:paddingBottom="20dp" >

                <TextView
                    style="@style/setting_item_text_style"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="12dp"
                    android:text="个性签名" />

                <include
                    style="@style/setting_dividing_line_style"
                    android:layout_width="match_parent"
                    android:layout_height="0.5dp"
                    android:layout_marginLeft="12dp"
                    android:layout_marginRight="0dp"
                    android:layout_marginTop="10dp"
                    layout="@layout/widget_horizontal_dividing_line" />

                <EditText
                    android:id="@+id/account_description"
                    style="@style/account_item_text_style"
                    android:hint="用一段话介绍自己..."
                    android:gravity="top"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="20dp"
                    android:layout_marginRight="20dp"
                    android:layout_marginTop="10dp"
                    android:paddingBottom="10dp"
                    android:background="@color/transparent"
                    android:ellipsize="end"
                    android:maxLines="3"
                    android:minLines="3" />
            </LinearLayout>
        </LinearLayout>
    </ScrollView>

</FrameLayout>

上面是我的layout,就一个比较简单的用户编辑,头部保存的textview设置了android:focusable="true"
            android:focusableInTouchMode="true"这两个属性,导致当按edittext获取焦点弹出软键盘后,编辑按保存的时候没有调用这个textview的setonclicklistener里面的onclick方法。

一直想不明白为什么,然后看到“当EditText的clearfocus清除焦点的时候,框架更倾向于把焦点给试图层上的第一个能够获取焦点的view”这句话,其实是那些能够获取焦点的view。

这里的头部保存的textview其实不是在top上的,个人觉得不是。因为当我把头部的focus两个属性设为false后是可以点击到的。(PS:默认的android:focusable="false" android:focusableInTouchMode="false"这两个属性是为false)。

这里我的推断是:当你为view配置了focusable属性后,同时也setOnclickListener了,如果其他的EditText获取焦点后,然后你点击能够focusable的view的时候发现这个view的onClick方法无法得到回调。也就是说focus和setOnClick其实是两个互相矛盾的操作,android系统默认如果这个view已经focus获得焦点了,就不应该执行onClick。


看系统源码也能多少猜测到

static class ListenerInfo {
        /**
         * Listener used to dispatch focus change events.
         * This field should be made private, so it is hidden from the SDK.
         * {@hide}
         */
        protected OnFocusChangeListener mOnFocusChangeListener;

        /**
         * Listeners for layout change events.
         */
        private ArrayList<OnLayoutChangeListener> mOnLayoutChangeListeners;

        /**
         * Listeners for attach events.
         */
        private CopyOnWriteArrayList<OnAttachStateChangeListener> mOnAttachStateChangeListeners;

        /**
         * Listener used to dispatch click events.
         * This field should be made private, so it is hidden from the SDK.
         * {@hide}
         */
        public OnClickListener mOnClickListener;

        /**
         * Listener used to dispatch long click events.
         * This field should be made private, so it is hidden from the SDK.
         * {@hide}
         */
        protected OnLongClickListener mOnLongClickListener;

        /**
         * Listener used to build the context menu.
         * This field should be made private, so it is hidden from the SDK.
         * {@hide}
         */
        protected OnCreateContextMenuListener mOnCreateContextMenuListener;

        private OnKeyListener mOnKeyListener;

        private OnTouchListener mOnTouchListener;

        private OnHoverListener mOnHoverListener;

        private OnGenericMotionListener mOnGenericMotionListener;

        private OnDragListener mOnDragListener;

        private OnSystemUiVisibilityChangeListener mOnSystemUiVisibilityChangeListener;

        OnApplyWindowInsetsListener mOnApplyWindowInsetsListener;
    }

这个是class  View里面的一个内部类,观察发现有clicklistener,focuschangelistener等,所以其实不要把focus和click混为一滩。


PS:如果有不同观点,欢迎留言交流









Android AlertDialog 深度解析:Context、主题、协程与无障碍实战指南 AlertDialog 表面是轻量级弹窗组件,实则是 Android UI 生命周期管理的关键枢纽。其核心依赖 Context 绑定机制,决定 Dialog 是否随 Activity 销毁而自动释放;主题继承链控制 Material Design 2/3 下的深色适配、圆角与按钮样式;Kotlin 协程需绑定 lifecycleScope 避免 onDestroy 后 NPE;Accessibility 支持则关乎 TalkBack 焦点顺序与 contentDescription 合规性。这些底层原理共同 阅读详情

相关推荐

第 25 章:View 系统与输入事件分发

LayoutInflater 运行时将 XML 布局资源转换成 View 对象,连接 res/layout 下声明式 XML 和内存中程序视图树。来源:frameworks/base/core/java/android/view/LayoutInflater.java (第 74 行)...创建自定义 View 需要理解并实现正确的回调方法。默认 onMeasure 实现 wrap_content 会填满父容器;自定义 View 需要正确处理测量模式。@Override// 固有尺寸像素。

dengfuma的专栏 536

android focusable 什么作用,Android中focusable属性的妙用——底层按钮的实现

看到百威啤酒的客户端主界面的按钮,感觉比较新奇,先看下图片:注意图中我画的箭头,当时鼠标点击的黑色圈圈的位置,然后按钮出现了按下的效果(×××的描边)刚开始看到这种效果很是好奇,不知道是怎么实现的,后来仔细一想,应该是整个啤酒罐是一张图片(ImageView),该图片是布局在三个按钮之上,然后就是最关键的地方,把图片设置为不可获取焦点,也就是android:focusable="false" ,就...

weixin_39847887的博客 2472

Android focusable属性的作用

当我们写代码的时候总会发现有的控件获取不到焦点,那是因为ImageButton,Button等都是抢占焦点的控件 android:focusable=”true” 这行的意思就是说可以获取焦点 android:focusable=”false” 这行就是不可获取焦点 可以根据需求来写要不要获取焦点。 焦点的作用:假如某控件没有焦点,相当于你点不到那个控件。不能对其进行监听操作等。 应用场景: 在我们实现底部导航功能时,可以给想应的导航栏控件设置获取焦点的属性,提高用户体验度。 ......

路宇的博客 4195

android:focusable=“true“ 导致有背景阴影

之前做一个TV项目的时候,Android系统版本是9.0,需要遥控器做选中效果,需要给控件设置 android:focusable=“true” 属性,才能选中,但是会有一个灰色背景,去掉灰色背景方法如下: 我的style如下: <style name="BaseDialogStyle" parent="Theme.AppCompat.Dialog"> <item name="android:windowFrame">@null</item>

weixin_43820591的博客 1375

Android中focusable属性的妙用—底层按钮的实现

Android中focusable属性的妙用—底层按钮的实现

PyTorch复现PSMNet踩坑全记录:从环境配置到KITTI数据集训练

本文详细记录了使用PyTorch复现CVPR经典立体匹配模型PSMNet的全过程,从环境配置到KITTI数据集训练,特别针对2023年主流软硬件环境中的常见问题提供解决方案。文章重点介绍了PSMNet的金字塔池化模块和堆叠沙漏结构,帮助研究者和工程师快速实现工业级深度估计,节省大量试错时间。

weixin_30897233的博客 328

Android ListView中Checkbox和view(RelativeLayout)的监听冲突问题解决

ListView的item中写有RelativeLayout包含着Checkbox和其它的控件,由于要求点击RelativeLayout监听,Checkbox在里面只是显示文字而已,所以导致Checkbox抢夺RelativeLayout的焦点,点击Checkbox区域RelativeLayout没有点击响应,只需在Checkbox里添加下面的四个属性即可: android:clickab...

shenggaofei的博客 522

量化爬虫实战:手把手教你搞定同花顺问财的hexin-v参数(附JS逆向思路与Cookie Hook技巧)

本文详细解析了如何通过JS逆向技术获取同花顺问财平台的`hexin-v`参数,包括Cookie Hook技巧和完整解决方案架构。从环境搭建到参数定位,再到生成逻辑逆向,手把手教你突破数据获取限制,为量化交易提供可靠数据支持。

weixin_42557803的博客 398

关于listview 的setOnItemClickListener失效问题

当adapter中包含CheckBox,或者一些带有按钮性质的view时,listview.setOnItemClickListener事件就会被拦截通过设置view失去焦点即可: android:clickable="false" android:enabled="false" android:focusable="false"

风晴 368

2.数字芯片时序正确的前提—Max-transition

芯片物理设计中最基本的Max-transition检查

weixin_43868998的博客 5426

初探802.11协议(6)——Wi-Fi 6新特性简介

Wi-Fi 6新机制(特性)介绍

FanFF的博客 1522

View.toString()输出含义

'F' : '.');第二个: . 不能获取焦点,F--可以获取焦点, ((mViewFlags & FOCUSABLE) == FOCUSABLE?'F' : '.');第四个:((mViewFlags&DRAW_MASK) == WILL_NOT_DRAW?'.' : 'D');是否会执行onDraw()方法。'R' : '.');'H' : '.');'V' : '.');'X' : '.');'E' : '.') 是否已启用?'S' : '.');'L' : '.');'C' : '.');

qq_35741614的博客 207

BlockUI专栏目录

BlockUI是一个设计NX对话框的工具,是官方推荐使用的对话框制作方法,能够与NX自身风格相统一,并且在实际开发中经常被使用。BlockUI可以帮助用户快速创建NX对话框,支持多种控件类型,如按钮、文本框、标签等。通过使用BlockUI,用户可以轻松地自定义对话框的布局、样式和交互行为。此外,BlockUI还提供了一些高级功能,如动态更新、条件显示和事件处理等,以帮助用户创建更加复杂和灵活的对话框。本专栏讲述了使用BlockUI制作NX对话框的方法,介绍了每个控件的功能,并且分享一些常用操作的源码。

王牌飞行员_里海的博客 1632

Android TV应用开发实战:从零构建家庭健康数据看板

在物联网与智能家居生态蓬勃发展的背景下,大屏设备正经历智能化重塑,成为家庭场景下的核心交互入口。其技术本质是构建基于Android TV等系统的应用生态,通过适配的交互逻辑与后端服务集成,实现品牌与用户的高频连接。从技术原理看,这要求开发者深入理解TV特有的焦点管理、Leanback设计规范及横屏优化等核心概念。其技术价值在于为品牌开辟了高粘性的家庭服务触达渠道,覆盖健康管理、影音娱乐等多元场景。本文以构建“家庭健康数据看板”为例,系统演示了从环境搭建、界面适配到数据对接的完整开发流程,为开发者提供可落地的

weixin_34414196的博客 376

【图像拼接】源码精读:Parallax-Tolerant Unsupervised Deep Image Stitching(UDIS++)

注:Pytorch代码。【图像拼接论文精读】专栏对应文章【图像拼接】论文精读:Parallax-Tolerant Unsupervised Deep Image Stitching(UDIS++)配合对应的文章阅读,效果更佳!注:请重点关注代码段中的注释!!!有一些讲解的东西直接写在代码段的注释中了,同时多关注红色字体和绿色字体!!!我认为深度学习方法和传统方法有很多相似之处。比如:深度学习中的损失函数和传统方法中的对齐项、失真项等其实原理相同,只是求解方式不同。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 7272

39、FIPA ACL:多代理系统中的标准化通信

本文详细介绍了FIPA ACL(Agent Communication Language)的基本概念、言语行为理论基础以及其在多代理系统(MAS)中的应用。文章涵盖了FIPA ACL的消息格式、信息交流流程、实现与优化方法,并通过智能调度系统的实例展示了其实际应用效果。此外,还探讨了FIPA ACL面临的挑战及未来发展方向,如通信延迟优化、本体简化、安全性增强等。

k8s6orchestrator的博客 381

安卓开发新利器:Sesame Preview语音模式深度解析与实践指南

在安卓应用开发与测试领域,提升效率始终是开发者关注的核心。传统的UI调试往往依赖手动操作与代码刷新,流程繁琐。语音识别与自然语言处理技术的成熟,为开发工具交互带来了新的可能。其技术价值在于通过非接触式指令,实现高自由度的交互触发,将开发者从重复的机械操作中解放出来,专注于视觉反馈与逻辑验证。这一特性在UI微调、动画调试及无障碍功能测试等场景下尤为实用。以近期备受关注的Sesame Preview工具为例,其创新的“语音模式”正是这一思路的工程实践,它允许开发者通过语音指令直接操控预览界面,为快速原型验证提供

weixin_34186128的博客 361

YOLOv8 Neck改进:BiFPN双向特征金字塔网络解析与实践

本文详细介绍了如何在YOLOv8中集成BiFPN双向特征金字塔网络,包括原理解析、代码实现、配置文件修改和性能分析。BiFPN通过双向特征融合和加权特征机制,显著提升了多尺度目标检测的性能。希望通过本文的讲解,大家能够深入理解BiFPN的工作原理,并成功将其应用到自己的目标检测项目中。如果你有任何问题或建议,欢迎在评论区留言讨论!在下一篇文章中,我们将探讨YOLOv8的其他改进技术,包括注意力机制、新的损失函数等,敬请期待!

QQ_778132974的博客 991

Android TextInputLayout 原理与生产级实践指南

TextInputLayout 是 Android 中实现语义化、可访问、响应式文本输入的核心组件,其本质是 Material Design 3 规范下对输入状态管理的抽象封装。它通过 TextInputEditText 与 TextInputLayout 的协同机制,统一处理浮动标签动画、错误反馈、焦点响应、辅助文本联动及动态主题适配等关键能力。相比传统 EditText,它将 UI 行为(如 hint 上浮、边框变色)与业务逻辑解耦,天然支持深色模式、无障碍服务和 Material You 动态配色。在

weixin_33928137的博客 390

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

APP自动化测试-4. App控件交互

简单介绍元素的操作方法和元素的属性元素的属性可以通过方法返回,也可以使用get_attribute(“属性名称”)进行获取。

gzytester的博客 283

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

深入解析Android事件分发机制:从原理到滑动冲突实战

在Android应用开发中,UI交互的流畅性直接关系到用户体验,其底层核心是事件分发机制。这一机制基于责任链模式,通过`dispatchTouchEvent`、`onInterceptTouchEvent`和`onTouchEvent`三个核心方法,将用户的触摸事件在View树中层层传递与处理。理解其原理对于实现复杂的自定义控件和优化交互至关重要。在实际工程实践中,嵌套滑动场景下的滑动冲突是常见挑战,开发者需要掌握根据滑动距离与方向判断拦截时机的技巧,或运用更现代的NestedScrolling接口进行协作

weixin_33860553的博客 416

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

android focusable 什么作用,问题:android:focusable和android:focusableInTouchMode的区别

由于要做日历开发渐进教程(5),而(5)中要完成一个功能:点击任意一天时,高亮显示目标日期。这个功能显然需要用到focus实现,然后就去查。有focusable和focusableInTouchMode,现在搞明白了一些,写下自己的理解,希望你能帮助大家吧。通过搜索,在stackoverFlow上找到了两个答案,基本解决了我的疑惑。关于焦点是什么的问题?类似非触屏手机时代,需要使用键盘的上下左右去...

weixin_39974030的博客 1126

Android中设置焦点的过程

Android中设置焦点时,首先要让这个控件有获取焦点的能力,在XML文件中通过给控件添加android:focusable="true"属性来表明该控件有获得焦点的权利。然后在页面使用时,需要哪个控件获得焦点就在代码中使用requestFocus()方法来强制要求该控件获取焦点。   以上是普通控件获取焦点的方法。但是在某些情况下比如像GridVIew等控件我们不需要让这一个整体获取焦点,而是让

饿了,吃包子 3365

Android中关于获取焦点的那些事:focusable属性的应用。

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言例如:1.可以获取焦点。2.禁止获取焦点总结 前言 有时候我们做Android开发的时候需要控制控件是否可以获取焦点,这时候我们就可以用到其中的focusable属性。 例如: 1.可以获取焦点。 将focusable属性设置为true即可,代码如下(示例): <Button android:id="@+id/bnt1" android:layout_width="180dip"

qq_36817479的博客 2399
上一篇: Android Studio创建库项目及引用
下一篇: Gradle版本冲突
fancylovejava
博客等级 码龄16年 1052粉丝 184原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值