美文网首页
View绘制流程(五) - view状态

View绘制流程(五) - view状态

作者: 世道无情 | 来源:发表于2019-02-12 14:27 被阅读0次

    1. 视图状态


    1>:enable:是否可用,setEnable(),true可用,false不可用,区别在于不可用的view不能响应 onTouch;
    2>:focused:是否获取焦点,如EditText,focuseable && focuseable in touch mode 成立,可以获取焦点;
    3>:selected:是否选中,setSelected(),true选中,false未选中;
    4>:pressed:是否按下,setPressed(),true按下,false未按下;

    2. 源码分析


    对于pressed:手指按下,pressed=true,
    view.drawableStateChanged__getDrawableState__onCreateDrawableState__
    drawable.setState__onStateChange
    StateListDrawable.onStateChange__selectDrawable

    手指按下后,pressed=true,会调用 view.drawableStateChanged

       protected void drawableStateChanged() {
            // 获取当前 view 状态的 int[] 数组
            final int[] state = getDrawableState();
            boolean changed = false;
    
            // 把 mBackground 赋值给 Drawable ,mBackground 就是自己在drawable下边创建的 selector文件
            final Drawable bg = mBackground;
            if (bg != null && bg.isStateful()) {
                // 获取当前 view 的状态的 int[] 数组后,调用 setState() 更新状态
                changed |= bg.setState(state);
            }
        }
    
    
        public final int[] getDrawableState() {
            // 首先判断当前view状态 是否发生变化,如果没有改变,就直接返回当前view状态
            if ((mDrawableState != null) && ((mPrivateFlags & PFLAG_DRAWABLE_STATE_DIRTY) == 0)) {
                return mDrawableState;
            } else {
                // 如果当前view状态改变了,调用 onCreateDrawableState() 获取最新状态,
                // 所有状态会以 int[] 数组返回
                mDrawableState = onCreateDrawableState(0);
                mPrivateFlags &= ~PFLAG_DRAWABLE_STATE_DIRTY;
                return mDrawableState;
            }
        }
    
    
        public boolean setState(@NonNull final int[] stateSet) {
            // 用 Arrays.equals()判断 view状态的int[] 数组是否发生变化,如果变化就调用 onStateChange,
            // 如果没有变化,就返回 false , Drawable 中的 onStateChange 只返回false,没有任何逻辑,
            // 因为 mBackground 是通过 selector创建的,而通过 selector创建的 drawable对象 是
            // StateListDrawable实例对象,这里的 onStateChange() 就是 StateListDrawable 的 onStateChange
            if (!Arrays.equals(mStateSet, stateSet)) {
                mStateSet = stateSet;
                return onStateChange(stateSet);
            }
            return false;
        }
    
    
        @Override
        protected boolean onStateChange(int[] stateSet) {
            // indexOfStateSet:获取当前 view对应的 Drawable 下标
            int idx = mStateListState.indexOfStateSet(stateSet);
            // selectDrawable:把下标传入,此方法 就会把当前 view 背景设置为 当前状态对应的图片
            return selectDrawable(idx) || changed;
        }
    

    分析上边源码:
    1>:一个view 手指按下,pressed=true,会调用 view.drawableStateChanged,在此方法中:

    • 首先判断当前view状态,如果没有变化,直接返回当前view状态;如果变了,获取当前 view 状态的 int[] 数组;
    • 然后 把 mBackground赋值给 Drawable对象,然后调用 setState();
      2>:在 setState 中,判断 view状态的int[] 数组是否变化,如果变化,调用 onStateChange,如果没有变,返回 false;
      3>:Drawable 中的 onStateChange 只返回 false,没有任何逻辑,因为 mBackground 是通过 selector 创建的,而通过 selector创建的 drawable对象 是 StateListDrawable 实例,所以 Drawable中的 onStateChange其实就是 调用 StateListDrawable中的 onStateChange;
      4>:在 onStateChange中: indexOfStateSet() 获取当前 view 对应的 Drawable 下标, selectDrawable 把当前 view 背景设置为 当前状态对应的图片;

    相关文章

      网友评论

          本文标题:View绘制流程(五) - view状态

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