setDescendantFocusability

作者: iSuperRed | 来源:发表于2018-03-22 15:53 被阅读366次
    努力学习.png

    1 简介

    setDescendantFocusability(int focusability)ViewGroup 的方法,其作用是设置 ViewGroup 的子View获取焦点的能力。

    科普一下英文单词

    descendant 
    英[dɪˈsendənt]  美[dɪˈsɛndənt]  复数:[descendants] 
    
    n. 后裔; 后代; (由过去类似物发展来的) 派生物; 弟子; 
    adj.下降的; 祖传的; |
    
    [例句]They are descendants of the original English and Scottish settlers.
    他们是最初的英格兰和苏格兰定居者的后代。
    

    2 实现

    setDescendantFocusability(int focusability) 的具体实现代码如下所示:

    /**
       * Set the descendant focusability of this view group. This defines the relationship
       * between this view group and its descendants when looking for a view to
       * take focus in {@link #requestFocus(int, android.graphics.Rect)}.
       *
       * @param focusability one of {@link #FOCUS_BEFORE_DESCENDANTS}, {@link #FOCUS_AFTER_DESCENDANTS},
       *   {@link #FOCUS_BLOCK_DESCENDANTS}.
       */
      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);
      } 
    

    setDescendantFocusability(int focusability) 方法可以传入的参数只有三种,
    分别为:FOCUS_BEFORE_DESCENDANTSFOCUS_AFTER_DESCENDANTSFOCUS_BLOCK_DESCENDANTS ,从源码中也能看出来,除了这三种参数,传入其它参数会抛出非法参数异常。

    FOCUS_BEFORE_DESCENDANTS

    该参数表明 ViewGroup 自身先处理焦点,如果没有处理则分发给子View进行处理。

    FOCUS_AFTER_DESCENDANTS

    该参数表明子View优先处理焦点,如果所有的子View都没有处理,则 ViewGroup 自身再处理。

    FOCUS_BLOCK_DESCENDANTS

    该参数表明 ViewGroup 自身处理焦点,不会分发给子View处理。
    而这三种参数实际上是在 requestFocus(int direction, Rect previouslyFocusedRect) 方法中起作用的,如下源码所示。

        /**
         * {@inheritDoc}
         *
         * Looks for a view to give focus to respecting the setting specified by
         * {@link #getDescendantFocusability()}.
         *
         * Uses {@link #onRequestFocusInDescendants(int, android.graphics.Rect)} to
         * find focus within the children of this group when appropriate.
         *
         * @see #FOCUS_BEFORE_DESCENDANTS
         * @see #FOCUS_AFTER_DESCENDANTS
         * @see #FOCUS_BLOCK_DESCENDANTS
         * @see #onRequestFocusInDescendants(int, android.graphics.Rect) 
         */
        @Override
        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);
            }
        }
    
    

    如果想让 RecyclerView 的子View优先获取焦点的话,就可以在布局中添加下面这一行代码。

    android:descendantFocusability="afterDescendants"
    

    或者在Java代码中添加下面这一行代码。

    mRecyclerView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
    

    相关文章

      网友评论

        本文标题:setDescendantFocusability

        本文链接:https://www.haomeiwen.com/subject/jiyaqftx.html