android:descendantFocusability用法简析-ListView与Button、RadioButton焦点冲突问题

》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组合——自定义单选列表 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值