Android视图状态及重绘流程
2016-06-18 22:41
417 查看
当手指按在视图上的时候,视图的状态就已经发生了变化,此时视图的pressed状态是true.每当视图状态有发生翻遍的时候,就会回调View的drawableStateChanged()方法。
mBGDrawable会在setBackgoundDrawable()方法中会将传入的 Drawable对象赋值给mBGDrawable。本地布局文件通过android:background属性指定的selector文件,效果等同于调用setBackgroundResourse()方法.
接下来drawableStateChanged()方法会调用getDrawableState()方法来获取视图状态
在这里首先会判断当前视图的状态是否发生了改变,如果没有改变就直接返回当前的视图状态,如果发生了改变就调用onCreateDrawableState()方法来获取最新的视图状态。视图的所有状态会以一个整型数组的形式返回。
这里会调用Arrays.equals()方法来判断视图状态的数组是否发生了变化,如果发生了变化则调用onStateChange()方法,否则就直接返回false。但你会发现,Drawable的onStateChange()方法中其实就只是简单返回了一个false
在这里会判断当前视图的状态是否发生了改变,如果没有改变就直接返回当前的视图状态,如果发生了改变就调用onCreateDrawableState()方法来获取最新的视图状态。
调用视图的invalidate()方法后确实会走到performTraversals()方法中,然后重新执行绘制流程。
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()方法中,然后重新执行绘制流程。
相关文章推荐
- android studio 能在真机上启动程序,不能在模拟器上启动(模拟器能启动,adb也能识别)
- Android自定义view的基本流程
- android studio的简单介绍及安装
- android环境配置
- ANROID动态加载技术系列索引
- 探索View的生命周期方法
- ActionBar的使用问题
- android5.0StateListAnimator
- gridView中的子控件无法铺满父布局
- Android实现卫星菜单(一)自定义属性及重写onMeasure、onLayout方法
- Android 采用get方式提交数据到服务器
- Android创建前台运行的Service
- [Android] LayoutInflater 详解
- 一步步追踪Android输入事件(二)
- Android中ListView的使用(三)----- 提升ListView运行效率
- 解决报错问题 Error inflating class android.support.design.widget.NavigationView
- Android中ListView的使用(二)----- 定制ListView的界面
- 安卓里RecyclerView的拖拽滑动列表
- 仿小米联系人
- android 广播(二)