android 焦点问题
1.引言
一直以来对焦点问题都是模模糊糊的只知道用android:focusableInTouchMode, android:focusable="true"。但是对他们并不是很理解.所以准备来彻彻底底的搞清楚android 里面的焦点问题。
2.正题
查看android api里面对focus的描述:
Paste_Image.png结论
setFocusable(true):表示此 View仅仅是能获得焦点。
焦点的移动是采用给定方向上找到最近邻居的算法。
view..requestFocus()请求获得焦点
结论:
对于触摸能力的设备,一旦用户触摸屏幕,设备将进入触摸模式。从这一刻起,只有isfocusableintouchmode()为true的View 将能得到焦点,如文本编辑控件。可触摸的View,如按钮,不会占用焦点;他们只会触发Click监听。
3.试验测试
3.1 测试1
xml样式如下:很平常的LinearLayout布局。
Paste_Image.pngMainActivity:
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
if (b) {
Log.d(ss,"+++++++++++++++++++++++++++++edit获取焦点");
}
}
});
button.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
if (b) {
Log.d(ss,"+++++++++++++++++++++++++++++button获取焦点");
}
}
});
edit1.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
if (b) {
Log.d(ss,"+++++++++++++++++++++++++++++edit1获取焦点");
}
}
});
textView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
if (b) {
Log.d(ss,"+++++++++++++++++++++++++++++text获取焦点");
}
}
});
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "click", Toast.LENGTH_SHORT).show();
}
});
正常情况下的结果(Button下面的输入框获取了焦点):
Paste_Image.png3.2 测试2
修改button的xml:添加android:focusableInTouchMode="true"
<Button
android:id="@+id/button"
android:text="焦点测试"
android:focusableInTouchMode="true"
android:layout_marginTop="15dp"
android:layout_width="match_parent"
android:layout_height="60dp"/>
结果:
Paste_Image.png由上俩个例子总结:
button默认是:android:focusableInTouchMode=“false”的
EditText默认是:android:focusableInTouchMode=“true”的
同时也验证了上面的话:焦点的移动是采用给定方向上找到最近邻居的算法。
3.3.分析ListView item点击不了的原因
都知道当listview的item 由button,checkbox,edit的时候 ,点击item是无法获取onitemclick的监听的。
OnItemClickListener的监听的调用者是AbsListView。AbsListView继承AdapterView。
当child能获取到焦点或者child的子View中有能获取到焦点的View。那么是不能执行performClick。performClick实际上就是调用的adapter的onitemClick事件。
我们知道input类型的控件,通过测试验证了,Button,EditView,CheckBox等控件都是可以获取到焦点的存在。故而不是执行performClick
验证:item的布局只有一个TextView,因此能响应onItemClick事件。但是假如加入了focusable=“true”。他是否还能响应呢?结果是不能响应的。
gif.gif