开发者社区> kk_100> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

onItemClickListener不起作用解决办法2(原创)

简介: 写这边文章之前,犹豫再三,不知道会不会冒犯一位朋友,他给我之前的一篇文章提出的意见。但我声明真心无意,只是想把问题拿出来分析一下,希望获得理解。      listview在android开发中很地方都用到了,通常我们需要定制item里面的视图,就要重写adapter。
+关注继续查看

     写这边文章之前,犹豫再三,不知道会不会冒犯一位朋友,他给我之前的一篇文章提出的意见。但我声明真心无意,只是想把问题拿出来分析一下,希望获得理解。

     listview在android开发中很地方都用到了,通常我们需要定制item里面的视图,就要重写adapter。而item中的控件根据需要来添加。但是如果出现了某些特定的item控件,就可能导致listview 的onItemClickListener不起作用。

    下面是一个范例,说明这种情况。

     首先还是先看代码:

  布局xml文件如下:

View Code

  item布局xml如下:

View Code
<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/iv_photo"
            android:layout_width="45dp"
            android:layout_height="45dp"
           />

        <TableLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1.0"
            android:gravity="center_vertical" >

            <TableRow>

                <TextView
                    android:id="@+id/tv_name"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1.0"
                    android:ellipsize="marquee"                    android:marqueeRepeatLimit="marquee_forever"
                    android:singleLine="true"
                    android:text="xxx"
                     />
            </TableRow>

            <TableRow>

                <TextView
                    android:id="@+id/tv_phoneNum"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:ellipsize="marquee"
                    android:marqueeRepeatLimit="marquee_forever"
                    android:singleLine="true"
                    android:text="xxx"
                  />
            </TableRow>
        </TableLayout>

        <LinearLayout
            android:layout_width="43dp"
            android:layout_height="match_parent"
            android:gravity="left|center_vertical" >

            <ImageButton
                android:id="@+id/ib_call"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_launcher" />
        </LinearLayout>
    </LinearLayout>

注意里面有一个ImageButton。

在activity中设置listview的onItemClickListener,需要做的事情就是当点击item的时候出现log信息,代码如下:

View Code
 listView.setOnItemClickListener(new OnItemClickListener()
        {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id)
            {
                // TODO Auto-generated method stub
                Log.i("mm", " onItemClick ");
                
            }
            
        });

 

以及设置listview的onTouchListener,需要的事情只是当touch的时候MotionEvent的事件,代码如下:

View Code
 listView.setOnTouchListener(new OnTouchListener()
        {
            
            @Override
            public boolean onTouch(View v, MotionEvent event)
            {
                // TODO Auto-generated method stub
                if(event.getAction() == MotionEvent.ACTION_DOWN)
                {
                    Log.i("mm", "MotionEvent.ACTION_DOWN");
                }
                else if(event.getAction() == MotionEvent.ACTION_UP)
                {
                    Log.i("mm", "MotionEvent.ACTION_UP");
                }
                else if(event.getAction() == MotionEvent.ACTION_MOVE)
                {
                    Log.i("mm", "MotionEvent.ACTION_MOVE");
                }
                
                return false;
            }
        });

 

在adapter中设置ImageButton的onClicklistener,需要做的事情只是打出log信息,代码如下:

View Code
holder.iv_call.setOnClickListener(new OnClickListener()
        {
             
             @Override
             public void onClick(View v)
             {
                // TODO Auto-generated method stub
                 Log.i("mm", "holder.iv_call.setOnClickListener ");
             }
       });

 

好了,以上都做完了,接下来运行工程。出现界面以后,我们来使劲的点item位置(除了imageButton),

结果log中没有出现打印的

Log.i("mm", " onItemClick ");
接下来拖动item看看touch事件
打出log如下:
11-07 08:42:27.793: I/mm(540): MotionEvent.ACTION_MOVE
11-07 08:42:28.681: I/mm(540): MotionEvent.ACTION_MOVE
11-07 08:42:28.832: I/mm(540): MotionEvent.ACTION_MOVE
11-07 08:42:28.992: I/mm(540): MotionEvent.ACTION_UP

 大家可以看到没有action_down事件,也就是没有了点击事件,一个完整的touch是down--move--move--up,而这里没有了,这是为什么呢?

再点击imagButton,看看打印信息:

11-07 08:44:31.131: I/mm(540): holder.iv_call.setOnClickListener 

    出现了我们期望的打印信息。

    在这里总结一下上面问题出现背景,item中有ImageButton,其余和平常使用listview一样的.当点击item时,onItemClickListener不起作用,ontouchListener中motionEvent.down消失了,事件只有点击item中的imagButton起作用。

    我们分析一下,当item出现了imageButton时,onItemClickListener不起作用,而在Touch中没有了down事件,首先说明onItemClickListener处理的和MotionEvent的down事件有关,然后问题的关键是这个down事件去了哪里呢?

    经过排查当item中有Checkable类以及Button类控件的时候,item的焦点会被子项获得,此时这些子控件会将焦点获取到,所以常常当点击item时变化的是子控件,item本身的点击没有响应。从而导致onItemClickListener不起作用。

    已经得知了问题导致的原因就是因为item没有获得焦点,焦点被子项拿走了,那么怎么解决这类问题?本人认为处理的途径无非就是通过设置子项不能获得焦点,同时item要获得焦点。  

    这里采用的方法,要用到两个属性:

一:

android:focusable="false"

这个属性的具体介绍可以i看我上一篇文章,设置的目的在于使得某个控件不能获得焦点。

二:

android:descendantFocusability="blocksDescendants"

这个属性用来设置子项焦点的处理先后顺序。

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.

android:beforeFocusability      viewgroup在子项处理之前获得焦点

android:afterFocusability            viewGroup在子项处理之后获得焦点

android:blocksFocusability          viewGroup阻止子项获得焦点

 

上面就是说子项焦点能力,定义了viewgroup和它的子元素处理的关系,这关系是指当一个view在获得焦点的时候,值必须是下面的常量之一。

       那么,我们肯定imageButton不能获得焦点,因此添加ImageButton属性 focusable="false",同时我们希望item中子项不能获得焦点,所以要把给android:descendantFocusability="blocksDescendants"属性添加到imageButton的父元素即可,简单的做可以设置item的根节点上。

      以上作完后,我们在测试一下。

     点击item,出现以下log:

11-07 09:48:19.671: I/mm(1077): MotionEvent.ACTION_DOWN
11-07 09:48:19.751: I/mm(1077): MotionEvent.ACTION_UP
11-07 09:48:19.952: I/mm(1077):  onItemClick 

   touch事件有了,ItemClick也有有了,

    再次imageButton,出现以下log:

11-07 09:50:01.673: I/mm(1077): holder.iv_call.setOnClickListener 

    说明点击ImageBUtton也获得点击事件。    

    以上完美的解决问题了。

    总结:本次出现的onItemClickListener不能响应的原因是在item中有button类(子类)或者checkable类(子类)控件导致了item的焦点在子项的控件上,处理的办法就是将子项的控件焦点去掉,同时在item中xml设置阻止子项获得焦点的属性,即可解决尚需问题

   综述: 出现onItemClickListener不能响应,原因可能有多种,本人总结了有两种情况,一种是isEnable中返回值为false导致不能点击和选择,一种是因为item中有了checkable或者button类(子类)控件导致了item的焦点失去,从不能响应。因此需要仔细分析,问题导致的具体原因,才更好的解决问题。

    最后:感谢上一篇文章中给我给意见的同学。

   欢迎转载,但请标明出处,谢谢

 

 




 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
神奇的bug,解决方法就是试试...
神奇的bug,解决方法就是试试...
0 0
如何禁止小白查看网页源代码的简单操作
如何禁止小白查看网页源代码的简单操作
0 0
vs2013没有代码提法的一种解决办法
把这两个勾去掉,然后关掉vs再打开,最后重新勾选上就行了。学习交流群:364976091
265 0
程氏CMS去掉静态页面的隐藏性版权方法
程氏CMS去掉静态页面的隐藏性版权方法 实例如图:因为之前自己找了好久都没找到这俩代码写在那个文件夹的,经过跟csqq8讨论了也没有得到结果,今天突然发现,原来这些代码都经过base64加密,用加密码写进去的,所以导致我搜索的时候搜索不到实质显示的代码,我们打开文件 app/models/csdjskins.
525 0
onItemClickListener不起作用解决办法2(原创)
写这边文章之前,犹豫再三,不知道会不会冒犯一位朋友,他给我之前的一篇文章提出的意见。但我声明真心无意,只是想把问题拿出来分析一下,希望获得理解。      listview在android开发中很地方都用到了,通常我们需要定制item里面的视图,就要重写adapter。
773 0
onItemClickListener不起作用解决办法(原创)
最近写了一个项目,界面使用的是帧布局,里面放置了listview显示联系人,以及右侧有对联系人的字母索引定位。 结果在对联系人listview设置onItemClickListener时,发现竟然不起作用。
652 0
【原创】关于环境变量修改出错解决办法
今天闲的无事在网上查了一些资料就是关于jdk安装后到底哪些变量是必须加的,哪些是可加可不加的,结果找到这篇文章说是这三项必须加,如下图: 当是抱着试试的心理,照着加到root用户下的.
521 0
Lumaqq点不出的解决办法
如果要在Linux上面用QQ使用Lumaqq是个不错的选择,我就是使用的Lumaqq的2006测试版,Lumaqq有时候会发生点不出的错误这个时候 你可以删除 $home/.
350 0
+关注
kk_100
移动开发专家
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载