前面我们分别介绍了Android中的事件分发和视图绘制的核心流程。也掺杂着setContentView介绍了下,今天我们简单扼要专门分析下,希望有个更直观、清晰的认识。(趁这几天不太忙,多多总结…)

1、LayoutInflater的inflate(params …)参数

LayoutInflater 根据注释,意思是“把一个xml文件实例化成一个View对象”。
平时经常会使用两种写法获取LayoutInflater的实例,虽说归根结底还是一种。
1、

LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

2、

LayoutInflater layoutInflater = LayoutInflater.from(context);

其实两者一样,2是1的简化版,看源码。

LayoutInflater.javapublic static LayoutInflater from(Context context) {    LayoutInflater LayoutInflater =            (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);    if (LayoutInflater == null) {        throw new AssertionError("LayoutInflater not found.");    }    return LayoutInflater;}

比如,在Activity中的快速使用。

LayoutInflater.from(this).inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)。

第一个参数resource,是表示要加载的布局文件。
第二个参数root,表示加载的resource是否需要一个父布局。
第三个参数attachToRoot,表示resource是否加载在父布局中。
对于attachToRoot有几种情况

  1. root 为null时,attachToRoot将不会起作用
  2. root 不为null,attachToRoot为true时,给resource一个root父布局,并且resource中的layout_width等参数生效。
  3. root 不为null,attachToRoot为false时,root不生效,只是将resource加载成一个View,但含有layout属性,即子视图的layout属性生效。
  4. 没有attachToRoot参数时,root !=null时,attachToRoot默认为true。
public View inflate(XmlPullParser parser, @Nullable ViewGroup root) {    return inflate(parser, root, root != null);}

2、inflate使用

根据上面的参数分析,我们试着去用示例验证下。毕竟这样才不容易忘记,理解也更深入。
btn_layout.xml

<?xml version="1.0" encoding="utf-8"?><Button xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="200dp"    android:layout_height="200dp"    android:orientation="vertical"    android:text="button">Button>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/main_layout"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.hds.viewdraw.MainActivity">    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/app_name"/>LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        LinearLayout mainLayout = (LinearLayout) findViewById(R.id.main_layout);        View view = LayoutInflater.from(this).inflate(R.layout.btn_layout, null);        mainLayout.addView(view);    }}

1、根据上述代码的运行结果是,Button的布局并没有根据指定的200dp展示,是linearLayout的vertical的默认子布局layoutparams:width=match_parent,height=wrap_content。

2、MainActivity改为

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        LinearLayout mainLayout = (LinearLayout) findViewById(R.id.main_layout);        View view = LayoutInflater.from(this).inflate(R.layout.btn_layout, mainLayout,false);        mainLayout.addView(view);    }}

button设置的layout生效,button被linearlayout以addView的形式加载。

3、对于2中当前的情况,有种简单写法,直接加载到root中,结果都一样。

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        LinearLayout mainLayout = (LinearLayout) findViewById(R.id.main_layout);        LayoutInflater.from(this).inflate(R.layout.btn_layout, mainLayout,true);    }}

3、setContentView

下面是针对目前内容的简化代码(真正伪代码,真实可不是这样子的啊),着重过程、理解关系。

public class Activity extends XXX,Window.Callback,XXX {       private Window mWindow;    final void attach(Context context, ActivityThread aThread,XXX,            Window window) {        mWindow = new PhoneWindow(this, window);        mWindow.setCallback(this);    }    public void setContentView(@LayoutRes int layoutResID) {        getWindow().setContentView(layoutResID);        initWindowDecorActionBar();    }    public Window getWindow() {        return mWindow;    }}
public class PhoneWindow extends Window XXX{    private LayoutInflater mLayoutInflater;    // This is the top-level view of the window, containing the window decor.    private DecorView mDecor;    public PhoneWindow(Context context) {        super(context);        mLayoutInflater = LayoutInflater.from(context);    }    @Override    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();        }        mLayoutInflater.inflate(layoutResID, mContentParent);    }    private void installDecor() {        mForceDecorInstall = false;        if (mDecor == null) {            mDecor = generateDecor(-1);        } else {            mDecor.setWindow(this);        }        if (mContentParent == null) {            mContentParent = generateLayout(mDecor);        }               }    protected DecorView generateDecor(int featureId) {        return new DecorView(context, featureId, this, getAttributes());    }       protected ViewGroup generateLayout(DecorView decor) {        return (ViewGroup)findViewById(ID_ANDROID_CONTENT);    }}

DecorView extends FrameLayout,所以是一个ViewGroup,且里面嵌套有个id为content的FrameLayout布局。

由上,setContentView(layoutResID)就是在contentView的基础上,使用mLayoutInflater.inflate(layoutResID, mContentParent)把layoutResID加载成一个View,直接添加到mContentParent中了。

更多相关文章

  1. .Net程序员玩转Android开发---(12)ListView显示数据
  2. Android动态加载jar、apk的实现
  3. Android源码阅读分析:从Activity开始(二)——加载布局
  4. Android(安卓)H5和App交互以及打开图库上传图片并显示
  5. 浅谈Android开机启动速度优化(含应用程序启动速度优化)
  6. One省电卫士 - Android内核级省电App
  7. Android(安卓)WebView实现离线加载功能
  8. mybatisplus的坑 insert标签insert into select无参数问题的解决
  9. Python技巧匿名函数、回调函数和高阶函数

随机推荐

  1. Android -- MVP,MVC,MVVM
  2. android 检测网络状态
  3. Android Ticks: display text vertically
  4. android 游戏OpenGL学习笔记1
  5. A first hand look at building an Andro
  6. singleLine 过时
  7. Android双缓冲技术 .
  8. Android(安卓)建立AIDL的步骤
  9. Android Random随机数
  10. Android在WebView中注入Js代码