• 使用PullToRefreshListView时遇到Item点击事件失效问题 解决方法


    最近在自己的项目中使用到了以下开源项目:

    https://github.com/nanchen2251/pullToRefreshDemo

    相关介绍博客如下:

    http://www.cnblogs.com/liushilin/p/5687491.html

    使用这个小项目做了一个可以上下拉的小程序,不过遇到了一个问题,就是在使用的时候无法为里面的  list_item  写点击事件,准确的说是写完点击事件后也不能用。

    后来发现了这个文章:

    https://blog.csdn.net/u014360817/article/details/49795271

    发现了文中是使用  descendantFocusability  这个属性来进行修正的。

    对于  descendantFocusability  这个属性并不是十分的了解,于是在网上继续搜索,发现这个属性在Android编程中还是比较常见的一个设置,这个设置主要是用来保证  ListView  在点击的时候可以获取到焦点。

    在下面文章中对于这个属性给了一些解释:

      https://www.cnblogs.com/eyu8874521/archive/2012/10/17/2727882.html

    以下给出原文内容:

    ===============================================================

    开发中很常见的一个问题,项目中的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点击的灵异事件告一段落。心得:遇到不会不懂的地方除了网上查询资料之外,也可以多多去尝试每种属性的作用,多阅读官方文档(我始终觉得还是读原文的比翻译的理解的会更好)。

    以上文字转于:https://www.cnblogs.com/eyu8874521/archive/2012/10/17/2727882.html

    ===============================================================

    文章https://blog.csdn.net/android_gogogo/article/details/53376178

    给出了一个布局layout文件作为示列,以下引自该列:

    <ListView  
                        android:descendantFocusability="blocksDescendants"  
                        android:focusable="false"  
                        android:divider="@drawable/leftxian1"  
                        android:id="@+id/flfg_content"  
                        android:layout_width="match_parent"  
                        android:layout_height="wrap_content"  
                         />

    listview item 中textview:

        <TextView  
                android:focusable="true"  
                android:padding="5dp"  
                android:gravity="center_vertical"  
                android:textColor="@color/black"  
                android:id="@+id/text_law"  
                android:layout_weight="1"  
                android:layout_width="0dp"  
                android:layout_height="wrap_content" ></TextView>  

    值得注意的是,文章:https://www.cnblogs.com/larrylawrence/p/5617038.html

    给出了  属性设置为  android:descendantFocusability="blocksDescendants"  的时候应该注意的其它问题:

    原文如下:

    ===============================================================

    值得注意的是,ListView中的控件不能设置clickable="true",否则会无视父控件的blockDescendants。

    可参考:

    https://segmentfault.com/q/1010000005800016

    同理,如果一个cardview里面有个listview,这个listview如果设置了clickable="true",遮住cardview的部分也是无法响应的。

    ===============================================================

     http://flysnow.iteye.com/blog/1762556

    中给出了更详尽的解释,如下:

    Android ViewGroup.setDescendantFocusability函数

    这个函数是在ViewGroup里定义的,主要用于控制child View获取焦点的能力,比如是否阻止child View获取焦点。

    他有三个常量可供设置

    1. FOCUS_BEFORE_DESCENDANTS ViewGroup本身先对焦点进行处理,如果没有处理则分发给child View进行处理
    2. FOCUS_AFTER_DESCENDANTS 先分发给Child View进行处理,如果所有的Child View都没有处理,则自己再处理
    3. FOCUS_BLOCK_DESCENDANTS ViewGroup本身进行处理,不管是否处理成功,都不会分发给ChildView进行处理

    Setdescendantfocusability(int focusability)代码

        public void setDescendantFocusability(int focusability) {  
                switch (focusability) {  
                    case FOCUS_BEFORE_DESCENDANTS:  
                    case FOCUS_AFTER_DESCENDANTS:  
                    case FOCUS_BLOCK_DESCENDANTS:  
                        break;  
                    default:  
                        throw new IllegalArgumentException("must be one of FOCUS_BEFORE_DESCENDANTS, "  
                                + "FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS");  
                }  
                mGroupFlags &= ~FLAG_MASK_FOCUSABILITY;  
                mGroupFlags |= (focusability & FLAG_MASK_FOCUSABILITY);  
            }  

    可以看到,只有这三个常量可以设置,不是这三个常量会抛出异常的。

    设置后,会在requestFocus(int direction, Rect previouslyFocusedRect) 方法里根据设置进行相应的处理。来看下实现

    Requestfocus(int direction, rect previouslyfocusedrect)代码

        public boolean requestFocus(int direction, Rect previouslyFocusedRect) {  
                if (DBG) {  
                    System.out.println(this + " ViewGroup.requestFocus direction="  
                            + direction);  
                }  
                int descendantFocusability = getDescendantFocusability();  
          
                switch (descendantFocusability) {  
                    case FOCUS_BLOCK_DESCENDANTS:  
                        return super.requestFocus(direction, previouslyFocusedRect);  
                    case FOCUS_BEFORE_DESCENDANTS: {  
                        final boolean took = super.requestFocus(direction, previouslyFocusedRect);  
                        return took ? took : onRequestFocusInDescendants(direction, previouslyFocusedRect);  
                    }  
                    case FOCUS_AFTER_DESCENDANTS: {  
                        final boolean took = onRequestFocusInDescendants(direction, previouslyFocusedRect);  
                        return took ? took : super.requestFocus(direction, previouslyFocusedRect);  
                    }  
                    default:  
                        throw new IllegalStateException("descendant focusability must be "  
                                + "one of FOCUS_BEFORE_DESCENDANTS, FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS "  
                                + "but is " + descendantFocusability);  
                }  
            }  

     =========================================================================

    文章

    https://segmentfault.com/q/1010000005800016

    给出了其它的几种解决方法,个人觉得还是有可能搞定,不过由于个人客观因素所限制并没有给出具体实现验证,下面给出其中内容:

    参考:
    https://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent)

  • 相关阅读:
    Python并行编程(七):线程同步之事件
    Python并行编程(六):线程同步之条件
    Python并行编程(五):线程同步之信号量
    Python并行编程(四):线程同步之RLock
    Python并行编程(三):线程同步之Lock
    UML关系总结——画uml图、流程图、软件结构图、类图、顺序图的方法
    2020,你好!
    字符串和多维数组
    排序算法
    查找技术
  • 原文地址:https://www.cnblogs.com/devilmaycry812839668/p/8862730.html
Copyright © 2020-2023  润新知