ListView Item点击不生效的处理办法

一.初遇问题

在做项目的过程中遇到了一个问题,有一个可以显示两个TextView外加一个RadioButton 的ListView,然后给ListView 设置了OnItemClickListener,

mListView.setOnItemClickListener(mOnItemClickListener);

点击Listview的列表确没有任何反应,onItemClick方法中的log也没有打印。

二.分析原因

是什么导致ListView的Item点击事件失效呢?

首先我们的Item中有一个可以点击的RadioButton,大家都知道RadioButton可以点击,可以点击就涉及到焦点的获取,诸如 ImageButton、CheckBox、RadioButton之类的控件本身在初始化的时候就赋予了焦点,我们来看一下ImageButton的构造函数    

public ImageButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        setFocusable(true);
    }

    /**
     * Set whether this view can receive the focus.
     *
     * Setting this to false will also ensure that this view is not focusable
     * in touch mode.
     *
     * @param focusable If true, this view can receive the focus.
     *
     * @see #setFocusableInTouchMode(boolean)
     * @attr ref android.R.styleable#View_focusable
     */
    public void setFocusable(boolean focusable) {
        if (!focusable) {
            setFlags(0, FOCUSABLE_IN_TOUCH_MODE);
        }
        setFlags(focusable ? FOCUSABLE : NOT_FOCUSABLE, FOCUSABLE_MASK);
    }

setFlags的代码比较长这里就不再贴出来,感兴趣的同学可以自行查阅,总之这类子控件初始化后会被赋予焦点,从而抢夺父容器的焦点导致父容器点击失效。

三.解决办法

当查阅相关api可以发现

ViewGroup的api中有一个setDescendantFocusability的api涉及到了ViewGroup的焦点处理。

void setDescendantFocusability(int focusability)

Set the descendant focusability of this view group.

该方法的参数是int类型的值,我们往回看会看到三个跟焦点相关的int类型的常量

int FOCUS_AFTER_DESCENDANTS

This view will get focus only if none of its descendants want it.

int FOCUS_BEFORE_DESCENDANTS

This view will get focus before any of its descendants.

int FOCUS_BLOCK_DESCENDANTS

This view will block any of its descendants from getting focus, even if they are focusable.

三个常量的大致意思是

FOCUS_AFTER_DESCENDANTS:当前Viewgroup只有在它的所有子控件都不需要焦点时才获得焦点。

FOCUS_BEFORE_DESCENDANTS:当前ViewGroup将先于其子控件而获得焦点。

FOCUS_BEFORE_DESCENDANTS:当前ViewGroup将会拦截其子控件的焦点,即使它的子控件可以自动获得焦点。

显而易见我们这里的RadioButton是自动获取焦点的类型,所以我们只要在这里给我们的item设置setDescendantFocusability(ViewGroup. FOCUS_BEFORE_DESCENDANTS)就可以解决我们的item无法点击的问题了。

当然我们也可以在布局文件中设置来解决此问题。

相关的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.

Constant Value Description
beforeDescendants 0 The ViewGroup will get focus before any of its descendants.
afterDescendants 1 The ViewGroup will get focus only if none of its descendants want it.
blocksDescendants 2 The ViewGroup will block its descendants from receiving focus.

This corresponds to the global attribute resource symbol descendantFocusability.


我们只需要在Item布局的根节点加上 android:descendantFocusability=”blocksDescendants”属性就可以了。

四.总结

遇到问题时除了Google上直接搜资料之外,时间不紧急的话最好还是多查阅Google的原版文档,多看看相关的源码逻辑,肯定会受益匪浅。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值