》android:descendantFocusability用法简析
开发中很常见的一个问题,项目中的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.
该属性是当一个为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组合——自定义单选列表