android onitemclicklistener不起作用,Android 中ListView setOnItemClickListener点击无效原因分析...

前言

最近在做项目的过程中,在使用listview的时候遇到了设置item监听事件的时候在没有回调onItemClick 方法的问题。我的情况是在item中有一个Button按钮。所以不会回调。上百度找到了解决办法有两种,如下:

1、在checkbox、button对应的view处加android:focusable=”false”

android:clickable=”false” android:focusableInTouchMode=”false”

2、在item最外层添加属性 android:descendantFocusability=”blocksDescendants”

网上大多数帖子的理由是:当listview中包含button,checkbox等控件的时候,android会默认将focus给了这些控件,也就是说listview的item根本就获取不到focus,所以导致onitemclick时间不能触发。

由于自己想去验证一下,所有有了这篇文章。好了下面开始

我们为ListView设置的onItemClickListener是在何处回调的?

要搞清楚这个问题,我们先从 android事件分发机制开始说起,事件分发机制网上有大神写了一些特别详细和优秀的文章,在这里就只做简要介绍了:

事件分发重要的三个方法

public boolean dispatchTouchEvent(MotionEvent ev)

该方法用来进行事件分发,在事件传递到当前View的时候调用,返回结果受到当前View的onTouchEvent和下级View的dispatchTouchEvent方法的影响。

public boolean onInterceptTouchEvent(MotionEvent ev)

该方法在上一个方法dispatchTouchEvent中调用,返回结果表示是否拦截当前事件,默认返回false,也就是不拦截。

public void onTouchEvent(MotionEvent event)

在 dispatchTouchEvent方法中调用,该方法用来处理点击事件,返回结果表示是否消耗当前事件。

当点击事件触发之后的流程

72a62c00681e6a7fc14662d827520239.png

了解事件分发机制之后,我们在setOnItemClick之后肯定需要进行事件处理,上面说到事件拦截默认是不拦截,所以我们猜想会到ListView的onTouchEvent方法中去处理ItemClick事件。去找你会发现ListView没有onTouchEvent方法。那我们再去他的父类AbsListView去找。还真有:

@Override

public boolean onTouchEvent(MotionEvent ev) {

if (!isEnabled()) {

// A disabled view that is clickable still consumes the touch

// events, it just doesn't respond to them.

return isClickable() || isLongClickable();

}

if (mPositionScroller != null) {

mPositionScroller.stop();

}

if (mIsDetaching || !isAttachedToWindow()) {

// Something isn't right.

// Since we rely on being attached to get data set change notifications,

// don't risk doing anything where we might try to resync and find things

// in a bogus state.

return false;

}

startNestedScroll(SCROLL_AXIS_VERTICAL);

if (mFastScroll != null && mFastScroll.onTouchEvent(ev)) {

return true;

}

initVelocityTrackerIfNotExists();

final MotionEvent vtev = MotionEvent.obtain(ev);

final int actionMasked = ev.getActionMasked();

if (actionMasked == MotionEvent.ACTION_DOWN) {

mNestedYOffset = 0;

}

vtev.offsetLocation(0, mNestedYOffset);

switch (actionMasked) {

case MotionEvent.ACTION_DOWN: {

onTouchDown(ev);

break;

}

case MotionEvent.ACTION_MOVE: {

onTouchMove(ev, vtev);

break;

}

case MotionEve

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值