Android视图状态及重绘流程

当手指按在视图上的时候,视图的状态就已经发生了变化,此时视图的pressed状态是true.每当视图状态有发生翻遍的时候,就会回调View的drawableStateChanged()方法。

protected void drawableStateChanged() {  
    Drawable d = mBGDrawable;  
    if (d != null && d.isStateful()) {  
        d.setState(getDrawableState());  
    }  
}  

mBGDrawable会在setBackgoundDrawable()方法中会将传入的 Drawable对象赋值给mBGDrawable。本地布局文件通过android:background属性指定的selector文件,效果等同于调用setBackgroundResourse()方法.

public void setBackgroundResource(int resid) {  
    if (resid != 0 && resid == mBackgroundResource) {  
        return;  
    }  
    Drawable d= null;  
    if (resid != 0) {  
        d = mResources.getDrawable(resid);  
    }  
    setBackgroundDrawable(d);  
    mBackgroundResource = resid;  
}  

接下来drawableStateChanged()方法会调用getDrawableState()方法来获取视图状态
在这里首先会判断当前视图的状态是否发生了改变,如果没有改变就直接返回当前的视图状态,如果发生了改变就调用onCreateDrawableState()方法来获取最新的视图状态。视图的所有状态会以一个整型数组的形式返回。

public final int[] getDrawableState() {  
    if ((mDrawableState != null) && ((mPrivateFlags & DRAWABLE_STATE_DIRTY) == 0)) {  
        return mDrawableState;  
    } else {  
        mDrawableState = onCreateDrawableState(0);  
        mPrivateFlags &= ~DRAWABLE_STATE_DIRTY;  
        return mDrawableState;  
    }  
} 

这里会调用Arrays.equals()方法来判断视图状态的数组是否发生了变化,如果发生了变化则调用onStateChange()方法,否则就直接返回false。但你会发现,Drawable的onStateChange()方法中其实就只是简单返回了一个false

public boolean setState(final int[] stateSet) {  
    if (!Arrays.equals(mStateSet, stateSet)) {  
        mStateSet = stateSet;  
        return onStateChange(stateSet);  
    }  
    return false;  
}  

在这里会判断当前视图的状态是否发生了改变,如果没有改变就直接返回当前的视图状态,如果发生了改变就调用onCreateDrawableState()方法来获取最新的视图状态。

@Override  
protected boolean onStateChange(int[] stateSet) {  
    int idx = mStateListState.indexOfStateSet(stateSet);  
    if (DEBUG) android.util.Log.i(TAG, "onStateChange " + this + " states "  
            + Arrays.toString(stateSet) + " found " + idx);  
    if (idx < 0) {  
        idx = mStateListState.indexOfStateSet(StateSet.WILD_CARD);  
    }  
    if (selectDrawable(idx)) {  
        return true;  
    }  
    return super.onStateChange(stateSet);  
}  

View的视图重绘

ViewRoot是继承字Handler的,调用sendEmptyMessage()方法出的消息,还在ViewRoot的handleMessage()方法中接收到。

public void handleMessage(Message msg) {  
    switch (msg.what) {  
    case DO_TRAVERSAL:  
        if (mProfile) {  
            Debug.startMethodTracing("ViewRoot");  
        }  
        performTraversals();  
        if (mProfile) {  
            Debug.stopMethodTracing();  
            mProfile = false;  
        }  
        break;  
    ......  
}  

调用视图的invalidate()方法后确实会走到performTraversals()方法中,然后重新执行绘制流程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值