先摘抄下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中涉及到的焦点问题,focusable,clickable,enabled的更多相关文章

  1. Android 中this、getContext()、getApplicationContext()、getApplication()、getBaseContext() 之间的区别

    : 知之为知之,不知为不知是知也! 使用this, 说明当前类是context的子类,一般是activity application等; this:代表当前,在Activity当中就是代表当前的Act ...

  2. android中ListView点击和里边按钮点击不能同时生效问题解决

    今天遇到一个问题:android中ListView点击和里边button点击不能同时生效问题解决. 原因是: listView 在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值得 ...

  3. Android中如何利用attrs和styles定义控件

    一直有个问题就是,Android中是如何通过布局文件,就能实现控件效果的不同呢?比如在布局文件中,我设置了一个TextView,给它设置了 textColor,它就能够改变这个TextView的文本的 ...

  4. Android中EditText显示明文与密文的两种方式

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 记录输入框显示.隐藏密码的简单布局以及实现方式. 效果图    代码分析 方式一 /**方式一:*/ private void sh ...

  5. 【转】说说Android中的style和theme

    最近在做软件从2.3到4.0的改变的一些工作,其中涉及了一些style和theme相关的东西.上网上查了一些东西,这个一并说说.关于android中style和theme的基本使用,这里就不再赘述了, ...

  6. [转]Android中自定义checkbox样式

    android中自定义checkbox的图片和大小   其实很简单,分三步: 1.在drawable中创建文件checkbox_selector.xml: <?xml version=" ...

  7. 一个demo让你彻底理解Android中触摸事件的分发

    注:本文涉及的demo的地址:https://github.com/absfree/TouchDispatch 1. 触摸动作及事件序列 (1)触摸事件的动作 触摸动作一共有三种:ACTION_DOW ...

  8. Android中onTouch方法的执行过程以及和onClick执行发生冲突的解决办法

    $*********************************************************************************************$ 博主推荐 ...

  9. Android中BroadcastReceiver的两种注册方式(静态和动态)详解

    今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来 ...

随机推荐

  1. Codechef APRIL14 ANUCBC Cards, bags and coins 背包DP变形

    题目大意 有n个数字,选出一个子集,有q个询问,求子集和模m等于0的方案数%1000000009.(n <= 100000,m <= 100,q <= 30) 假设数据很小,我们完全 ...

  2. Codeforces Round #302 (Div. 1) C. Remembering Strings DP

    C. Remembering Strings Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/5 ...

  3. MySQL时间戳与日期互转

    1.UNIX时间戳转换为日期用函数: FROM_UNIXTIME() ); 输出:2006-08-22 12:11:10 2.日期转换为UNIX时间戳用函数: UNIX_TIMESTAMP() sel ...

  4. CentOS6 下编译安装 MySQL 5.6.26

    CentOS6下通过yum安装的MySQL是5.1版的,比较老,所以就想通过源代码安装高版本的5.6.26. 一:卸载旧版本 使用下面的命令检查是否安装有MySQL Server rpm -qa | ...

  5. Advanced Features of Delphi DLLs

    http://www.delphisources.ru/pages/faq/master-delphi-7/content/LiB0104.html Beside this introductory ...

  6. Win8系统108个运行命令 你能记住多少?

    Win8运行命令:程序和功能   取消了开始菜单的Win8让人感觉很不习惯,这才发现原来开始菜单可以做这么多事.不过Win8中的一些快捷键还沿用了Windows一直以来的习惯,比如按下Windows ...

  7. 微信公众平台—— 获取微信服务器IP地址

    微信公众平台—— 获取微信服务器IP地址 const ServerIpUrl = 'https://api.weixin.qq.com/cgi-bin/getcallbackip?&acces ...

  8. 关于目前自己iOS项目使用的插件

    1. VVDocumenter-Xcode 规范注释生成器. 2. RTImageAssets 本项目是一个 Xcode 插件,用来生成 @3x 的图片资源对应的 @2x 和 @1x 版本,只要拖拽高 ...

  9. 【微信小程序】在js中导入第三方js或自己写的js,使用外部js中的function的两种方法 import和require的区别使用方法 【外加:使用第三方js导出的默认function的调用方法】

    如下 定义了一个外部js文件,其中有一个function import lunaCommon from '../lunaCommon.js'; var ctx = wx.getStorageSync( ...

  10. 1503162139-ny-分数拆分

    分数拆分 时间限制:3000 ms  |  内存限制:65535 KB 难度:1 描写叙述 如今输入一个正整数k,找到全部的正整数x>=y,使得1/k=1/x+1/y. 输入 第一行输入一个整数 ...