View的 isFocusableInTouchMode() 默认是 false, 需调用 setFocusableInTouchMode(true) 才为true
要让 button 等 view 调用 requestFocus 方法起作用, 需要 isFocusableInTouchMode() 为true才行。

setFocusable(false) 会到导致 isFocusable() 和 isFocusableInTouchMode() 都为false,
要设为true只能分别调用 setFocusable(true) 和 setFocusableInTouchMode(true)

只能有一个View得到焦点,其他的View将失去焦点.

Selected
可以有多个View同时处于 Selected状态。

View 的 setSelected方法,会调用 dispatchSetSelected 向子View传递 select状态。

public void setSelected(boolean selected) {
if (((mPrivateFlags & SELECTED) != 0) != selected) {
mPrivateFlags = (mPrivateFlags & ~SELECTED) | (selected ? SELECTED : 0);
if (!selected) resetPressedState();
invalidate();
refreshDrawableState();
dispatchSetSelected(selected);
}
}

ViewGroup 的 dispatchSetSelected 方法。

public void dispatchSetSelected(boolean selected) {
final View[] children = mChildren;
final int count = mChildrenCount;
for (int i = 0; i < count; i++) {
children[i].setSelected(selected);
}
}

Selector

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/black" android:state_selected="true"/>
<item android:drawable="@drawable/white"/>
</selector>

ViewGroup 有多个重载的 addView方法
在xml布局文件里面添加的子View,是通过下面这个重载方法加到ViewGroup中的。

public void addView(View child, ViewGroup.LayoutParams params);

利用上述机制,可以简单的实现一个类似 TabWidget 的 tab 切换容器,支持用 selector 改变 tabView 和 tabView 子 View 的背景.

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout; public class TabContainer extends LinearLayout {
private int mCurrentTab = -1; public TabContainer(Context context, AttributeSet attrs) {
super(context, attrs);
} public void setCurrentTab(int index) {
if (getChildCount() == 0) {
return;
} if (index >= 0 && index <= getChildCount() - 1) {
getChildAt(index).performClick();
}
} @Override
public void addView(View child, int index, android.view.ViewGroup.LayoutParams params) {
super.addView(child, index, params); child.setOnClickListener(mOnClickListener);
child.setSelected(false);
} private View.OnClickListener mOnClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
int index = indexOfChild(v);
if (index != mCurrentTab) {
if (mCurrentTab >= 0) {
getChildAt(mCurrentTab).setSelected(false);
}
getChildAt(index).setSelected(true);
mCurrentTab = index; if (mOnTabSelectChangeListener != null) {
mOnTabSelectChangeListener.onTabSelectChanged(index, v);
}
}
}
}; private OnTabSelectChangeListener mOnTabSelectChangeListener; public void setOnTabSelectChangeListener(OnTabSelectChangeListener listener) {
mOnTabSelectChangeListener = listener;
} public interface OnTabSelectChangeListener {
public void onTabSelectChanged(int index, View tab);
}
}

View 的 focus 和 selected 状态, TabContainer实现的更多相关文章

  1. Android监听view的attached或detached状态

    我们在开发中,希望监听View的attached或detached状态,来进行比如eventbus的注册与解注册的操作,非常的方便实用. 可以使用系统给我们提供的listener,代码使用如下: mV ...

  2. iOS之UIButton的normal和selected状态切换

    1.问题? 改变播放器按钮状态,发现从selected切回到normal状态时候,中间会切换normal-selected-normal的图片? 2.原因…… normal-->selected ...

  3. jquery去掉或者替换字符,设置指定options为selected状态

    <html> <body> <div><select id="queryYear">                 <opt ...

  4. VMware View 要求操作句柄的状态错误

    win10系统安装的VMware-viewclient,版本是

  5. View Focus的处理过程及ViewGroup的mFocused字段分析

    通过上篇的介绍,我们知道在对KeyEvent的处理中有非常重要的一环,那就是KeyEvent在focus view的path上自上而下的分发, 换句话说只有focus的view才有资格参与KeyEve ...

  6. android中正确保存view的状态

    英文原文: http://trickyandroid.com/saving-android-view-state-correctly/ 转载此译文须注明出处. 今天我们聊一聊安卓中保存和恢复view状 ...

  7. Android view状态保存

    为什么我们需要保存View的状态? 这个问题问的好!我坚信移动应用应该帮助你解决问题,而不是制造问题. 想象一下一个非常复杂的设置页面: 这并不是从一个移动应用的截图(这不是典型的win32程序吗.. ...

  8. View的onSaveInstanceState和onRestoreInstanceState过程分析

    为什么要介绍这2个方法呢?这是因为在我们的开发中最近遇到了一个很诡异的bug.大体是这样的:在我们的ViewPager中 有2页的root view都是ScrollView,我们在xml里面都用了an ...

  9. Qt Model/View(官方翻译,图文并茂)

    http://doc.trolltech.com/main-snapshot/model-view-programming.html 介绍 Qt 4推出了一组新的item view类,它们使用mode ...

随机推荐

  1. c++ boost (递归)遍历目录

    c++ 终于有办法跨平台访问文件系统了,虽然还是要借助boost.不多说,上代码 /** visitdir.cpp **/#include <iostream> #include < ...

  2. centos单用户模式修改ROOT密码

    首先启动的时候的时候,需要进入单用户模式(进入单用户模式的前提是系统引导器能正常工作),单用户模式是不需要输入密码,并且(进入单用户模式,没有开启网络服务,不支持远程连接 )网上说可以通过GRUB ( ...

  3. commitizen-规范commit-message

    安装指南 安装commitizen sudo npm install -g commitizen 配置 cd到.git所在目录 commitizen init cz-conventional-chan ...

  4. IBM Domino 9 出现 Domino Designer 您正在试图升级多用户安装。请获取正确的安装包以完成升级。 解决方案

    如果网上搜索的其他方法解决不了,那么我的这个方法可以试一下. 出现的场景: 先装好了Notes,后准备装Designer. 在装Designer解压包之后,出现下面的错误,不能安装: 您正在试图升级多 ...

  5. phpMyAdmin上传文件大小限制

    今日偶然要导一张数据表至mysql数据库中,但发现文件为2.9M,导入失败. 看一下返回的错误原因为文件超过2M的大小限制,郁闷. 找了一下“越狱”的方法,需要修改php.ini和phpmyadmin ...

  6. Mongodb在Windows 7下的安装及配置

    第一步 下载MongoDB: 下载mongodb的windows版本,有32位和64位版本,根据操作系统情况下载,下载地址:http://www.mongodb.org/downloads 解压缩至指 ...

  7. ArcGIS图层介绍

    什么是图层 图层是用来在 ArcGIS 产品套件中显示地理数据集的机制.每个图层代表一种数据集(可以是地图服务.图形或是矢量数据),并指定该数据集是如何描绘使用一组属性的. 包含一个地图控件的每个应用 ...

  8. MSP430 IO 使用

    MSP430内部上拉下拉使用注意——IO口测高低电平     MSP430单片机IO口用来检测高低电平时,是不需要外部上拉下拉的,因为其内部有上拉和下拉.在用作高低电平检测时,需要开启上拉或下拉.   ...

  9. C语言拾遗

    1. 没C++那么恶心的const C语言中的const修饰符用于修饰一个变量是const属性的.被C语言的const修饰的变量具有只读属性,并且不能被修改. const修饰的变量 != 常量,con ...

  10. 0x00到0xFF二进制数值中1的的个数

    似乎有点无聊耶~~~~~(>_<)~~~~ #include <stdio.h> , , , , , , , , , , , , , , , }; ] = { , , , , ...