android:descendantFocusability用法简析-ListView与Button、RadioButton焦点冲突问题
2016-05-10 23:11
741 查看
》android:descendantFocusability用法简析
开发中很常见的一个问题,项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现了,可能会发生点击每一个item的时候没有反应,无法获取的焦点。原因多半是由于在你自己定义的Item中存在诸如ImageButton,Button,CheckBox等子控件(也可以说是Button或者Checkable的子类控件),此时这些子控件会将焦点获取到,所以常常当点击item时变化的是子控件,item本身的点击没有响应。
这时候就可以使用descendantFocusability来解决啦,API描述如下:
Defines the relationship between the ViewGroup and its descendants when looking for a View to take focus.
Must be one of the following constant values.
![](http://img.my.csdn.net/uploads/201210/17/1350460358_5684.jpg)
该属性是当一个为view获取焦点时,定义viewGroup和其子控件两者之间的关系。
属性的值有三种:
beforeDescendants:viewgroup会优先其子类控件而获取到焦点
afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点
blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点
通常我们用到的是第三种,即在Item布局的根布局加上android:descendantFocusability=”blocksDescendants”的属性就好了,至此listview点击的灵异事件告一段落。心得:遇到不会不懂的地方除了网上查询资料之外,也可以多多去尝试每种属性的作用,多阅读官方文档(我始终觉得还是读原文的比翻译的理解的会更好)。
----------------------
》ListView与RadioButton的焦点问题:
public class TopicsListAdapter<T> extends BaseAdapter<T> {
private LayoutInflater mInflater;
private String mTopicType;// 话题的类型,当传进来的为话题类型为3时,则显示Button
// record the current checked radio number
private int checkedPosition = -1;
HashMap<String, Boolean> states = new HashMap<String, Boolean>();// 用于记录每个RadioButton的状态,并保证只可选一个
public TopicsListAdapter(Context context, String topicType) {
super(context);
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mTopicType = topicType;
}
@SuppressWarnings("unchecked")
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHodler viewHolder = null;
if (convertView != null) {
viewHolder = (ViewHodler) convertView.getTag();
} else {
convertView = mInflater.inflate(R.layout.item_listview_topic, null);
if (mList.get(position) != null) {
viewHolder = new ViewHodler();
convertView.setTag(viewHolder);
}
}
TopicsItemBean itembeans = (TopicsItemBean) mList.get(position);
if (!StringUtils.isEmpty(itembeans.getTopicName())) {
viewHolder.mTopicNameTv = (TextView) convertView
.findViewById(R.id.topic_name);
viewHolder.mTopicNameTv.setText(itembeans.getTopicName());
}
if (!StringUtils.isEmpty(itembeans.getBrowse())) {
viewHolder.mTopicPageviewTv = (TextView) convertView
.findViewById(R.id.topic_pageview);
viewHolder.mTopicPageviewTv.setText(itembeans.getBrowse() + "次预览");
}
// TODO
final RadioButton radioBtn = (RadioButton) convertView
.findViewById(R.id.radio_select_btn);
viewHolder.mRadioBtn = radioBtn;
if (!StringUtils.isEmpty(mTopicType) && mTopicType.equals("3")) {// 显示Button
viewHolder.mRadioBtn.setVisibility(View.VISIBLE);
} else {// 不显示
// viewHolder.mRadioBtn.setVisibility(View.GONE);
}
LogUtil.v("getView", itembeans.getTopicName());
viewHolder.mRadioBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 重置,确保最多只有一项被选中
for (String key : states.keySet()) {
states.put(key, false);
}
states.put(String.valueOf(position), radioBtn.isChecked());
LogUtil.v("RadioBtn.setOnClickListener", "position="+position);
//所选中话题的TopicId,TopicName,TopicBrower
TopicsItemBean aBean = (TopicsItemBean) mList.get(position);
StringBuilder builder = new StringBuilder();
builder.append(aBean.getTopicId()).append(",");
builder.append(aBean.getTopicName()).append(",");
builder.append(aBean.getBrowse());
SharePrefUtils.setTopicData(mContext, builder.toString());
LogUtil.v("RadioBtn.setOnClickListener", "topicData="+builder.toString());
notifyDataSetChanged();
}
});
boolean res = false;
if (states.get(String.valueOf(position)) == null
|| states.get(String.valueOf(position)) == false) {
res = false;
states.put(String.valueOf(position), false);
} else {
res = true;
}
viewHolder.mRadioBtn.setChecked(res);
return convertView;
}
@Override
public long getItemId(int position) {
return position;
}
public class ViewHodler {
TextView mTopicNameTv;
TextView mTopicPageviewTv;
RadioButton mRadioBtn;
}
}
RadioButton文字点击效果:
<?xml version="1.0" encoding="utf-8">
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#FFFFFF" android:state_checked="false" android:state_enabled="true" android:state_pressed="true"/>
<item android:color="#FFFFFF" android:state_checked="true" />
<item android:color="#E87A90" android:state_checked="false" />
</selector>
-----------
》Android ListView OnItemLongClick和OnItemClick事件内部细节分享以及几个比较特别的属性--http://blog.sina.com.cn/s/blog_783ede030101bnm4.html
http://www.cnblogs.com/xiaoQLu/p/3857249.html
》ListView与RadioButton组合——自定义单选列表
开发中很常见的一个问题,项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现了,可能会发生点击每一个item的时候没有反应,无法获取的焦点。原因多半是由于在你自己定义的Item中存在诸如ImageButton,Button,CheckBox等子控件(也可以说是Button或者Checkable的子类控件),此时这些子控件会将焦点获取到,所以常常当点击item时变化的是子控件,item本身的点击没有响应。
这时候就可以使用descendantFocusability来解决啦,API描述如下:
android:descendantFocusability
Defines the relationship between the ViewGroup and its descendants when looking for a View to take focus.Must be one of the following constant values.
![](http://img.my.csdn.net/uploads/201210/17/1350460358_5684.jpg)
该属性是当一个为view获取焦点时,定义viewGroup和其子控件两者之间的关系。
属性的值有三种:
beforeDescendants:viewgroup会优先其子类控件而获取到焦点
afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点
blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点
通常我们用到的是第三种,即在Item布局的根布局加上android:descendantFocusability=”blocksDescendants”的属性就好了,至此listview点击的灵异事件告一段落。心得:遇到不会不懂的地方除了网上查询资料之外,也可以多多去尝试每种属性的作用,多阅读官方文档(我始终觉得还是读原文的比翻译的理解的会更好)。
----------------------
》ListView与RadioButton的焦点问题:
public class TopicsListAdapter<T> extends BaseAdapter<T> {
private LayoutInflater mInflater;
private String mTopicType;// 话题的类型,当传进来的为话题类型为3时,则显示Button
// record the current checked radio number
private int checkedPosition = -1;
HashMap<String, Boolean> states = new HashMap<String, Boolean>();// 用于记录每个RadioButton的状态,并保证只可选一个
public TopicsListAdapter(Context context, String topicType) {
super(context);
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mTopicType = topicType;
}
@SuppressWarnings("unchecked")
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHodler viewHolder = null;
if (convertView != null) {
viewHolder = (ViewHodler) convertView.getTag();
} else {
convertView = mInflater.inflate(R.layout.item_listview_topic, null);
if (mList.get(position) != null) {
viewHolder = new ViewHodler();
convertView.setTag(viewHolder);
}
}
TopicsItemBean itembeans = (TopicsItemBean) mList.get(position);
if (!StringUtils.isEmpty(itembeans.getTopicName())) {
viewHolder.mTopicNameTv = (TextView) convertView
.findViewById(R.id.topic_name);
viewHolder.mTopicNameTv.setText(itembeans.getTopicName());
}
if (!StringUtils.isEmpty(itembeans.getBrowse())) {
viewHolder.mTopicPageviewTv = (TextView) convertView
.findViewById(R.id.topic_pageview);
viewHolder.mTopicPageviewTv.setText(itembeans.getBrowse() + "次预览");
}
// TODO
final RadioButton radioBtn = (RadioButton) convertView
.findViewById(R.id.radio_select_btn);
viewHolder.mRadioBtn = radioBtn;
if (!StringUtils.isEmpty(mTopicType) && mTopicType.equals("3")) {// 显示Button
viewHolder.mRadioBtn.setVisibility(View.VISIBLE);
} else {// 不显示
// viewHolder.mRadioBtn.setVisibility(View.GONE);
}
LogUtil.v("getView", itembeans.getTopicName());
viewHolder.mRadioBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 重置,确保最多只有一项被选中
for (String key : states.keySet()) {
states.put(key, false);
}
states.put(String.valueOf(position), radioBtn.isChecked());
LogUtil.v("RadioBtn.setOnClickListener", "position="+position);
//所选中话题的TopicId,TopicName,TopicBrower
TopicsItemBean aBean = (TopicsItemBean) mList.get(position);
StringBuilder builder = new StringBuilder();
builder.append(aBean.getTopicId()).append(",");
builder.append(aBean.getTopicName()).append(",");
builder.append(aBean.getBrowse());
SharePrefUtils.setTopicData(mContext, builder.toString());
LogUtil.v("RadioBtn.setOnClickListener", "topicData="+builder.toString());
notifyDataSetChanged();
}
});
boolean res = false;
if (states.get(String.valueOf(position)) == null
|| states.get(String.valueOf(position)) == false) {
res = false;
states.put(String.valueOf(position), false);
} else {
res = true;
}
viewHolder.mRadioBtn.setChecked(res);
return convertView;
}
@Override
public long getItemId(int position) {
return position;
}
public class ViewHodler {
TextView mTopicNameTv;
TextView mTopicPageviewTv;
RadioButton mRadioBtn;
}
}
RadioButton文字点击效果:
<?xml version="1.0" encoding="utf-8">
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#FFFFFF" android:state_checked="false" android:state_enabled="true" android:state_pressed="true"/>
<item android:color="#FFFFFF" android:state_checked="true" />
<item android:color="#E87A90" android:state_checked="false" />
</selector>
-----------
》Android ListView OnItemLongClick和OnItemClick事件内部细节分享以及几个比较特别的属性--http://blog.sina.com.cn/s/blog_783ede030101bnm4.html
http://www.cnblogs.com/xiaoQLu/p/3857249.html
》ListView与RadioButton组合——自定义单选列表
相关文章推荐
- ArrayAdapter简单适配器用法Android
- 【Android布局】在程序中设置android:gravity 和 android:layout_Gravity属性
- Android (shape,gradient)使用总结 (2
- Android学习之获取系统应用信息列表的实现
- android关于fragment的构造函数用法建议
- Android获取LayoutInflater对象的方法总结
- Android开发笔记之图片的颜色处理
- android关于RandomAccessFile
- Android JSON原生解析的几种思路,以号码归属地,笑话大全,天气预报为例演示
- Android JSON原生解析的几种思路,以号码归属地,笑话大全,天气预报为例演示
- android关于getLayoutParams()方法源码译文(部分)
- Android中的Activity
- js与android代码的交互
- Android NDK日志输出
- Android Studio报错@integer/google_play_services_version').
- java Android SDK安装与环境变量配置以及开发第一个Android程序
- Android入门学习——Retrofit+MVP模式学习
- android选取本地图片及关于图片压缩上传问题
- 五步搞定Android开发环境部署——非常详细的Android开发环境搭建教程
- android 屏幕适配