View绘制体系(一)——从setContentView聊起

View绘制体系(一)——从setContentView聊起

前言

对于Android开发者来说,View的绘制是非常基础且重要的部分,而Activity绘制View的流程,我们都是从setContentView开始去设置我们自定义的布局的,所以我准备从setContentView为起点来聊下View的绘制流程。

setContentView

在Activity中,我们经常会调用到setContentView这个方法来设置对应的布局文件,在这里我想从源码的角度去分析下setContentView内部是如何实现的。需要注意的是,setContentView并没有绘制View,只是创建了View。

我们先来看下Activity类中的setContentView方法:

public void setContentView(@LayoutRes int layoutResID) {
    
    getWindow().setContentView(layoutResID);
    initWindowDecorActionBar();
}
public void setContentView(View view) {
    
    getWindow().setContentView(view);
    initWindowDecorActionBar();
}
public void setContentView(View view, ViewGroup.LayoutParams params) {
    
    getWindow().setContentView(view, params);
    initWindowDecorActionBar();
}

可以看到setContentView的三个重载其内部都是调用的getWindow().setContentView对应参数的三个重载方法,然后调用initWindowDecorActionBar()来初始化标题栏,那么我们就看看getWindow()方法。

public Window getWindow() {
    
    return mWindow;
}

根据上面代码,可以看到mWindowActivity中的一个变量,保存与Activity对应的Window对象,Window是个抽象类,所以我们要找到该对象初始化的地方,在Activity中的attach方法里面:

final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback) {
    
        attachBaseContext(context);
    //...
    mWindow = new PhoneWindow(this, window, activityConfigCallback);
    //...
}

由此可以看到PhoneWindowWindow的实现子类,而ActivitysetContentView实质是调用了PhoneWindowsetContentView方法,那么就来看下这个类,我们先来看下PhoneWindow.setContentView(int layoutResID)这个方法:

public void setContentView(int layoutResID) {
    
    // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
    // decor, when theme attributes and the like are crystalized. Do not check the feature
    // before this happens.
    if (mContentParent == null) {
    
        installDecor();
    } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
    
	    //FEATURE_CONTENT_TRANSITIONS表示开启了动画Transition效果
	    //移除mContentParent中所有的子View
        mContentParent.removeAllViews();
    }

    if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
    
	    //开启Transiton后做相应的处理,不做具体分析
        final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
                getContext());
        transitionTo(newScene);
    } else {
    
	    //一般情况来到这里,加载布局
        mLayoutInflater.inflate(layoutResID, mContentParent);
    }
    mContentParent.requestApplyInsets();
    final Callback cb = getCallback();
    if (cb 
  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值