作为一个Android开发者,动态加载布局是我们经常能够遇到的,而说到这又不得不遇到很容易混淆的infalte,现在我们就通过案例来进行分析,清楚了之后后面开发才不疑惑,也能够优化布局。
1.注意下Inflate的方法参数
从下面方法就可发现,即便你是调用2个参数的,程序依旧会判断执行最下面的inflate()三个参数的方法,用来依据执行是否黏贴上root视图。
public View inflate(XmlPullParser parser, @Nullable ViewGroup root) {
return inflate(parser, root, root != null);
}
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot)
2. 先看第一个例子
主活动下xml,背景粉色
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/llRoot"
android:background="@color/colorAccent"
tools:context="com.example.mydairytestproject.MainActivity">
</LinearLayout>
要加载的布局 背景白色
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#fff"
android:layout_height="match_parent">
<Button
android:text="加载布局"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
Java代码:
LinearLayout llRoot = findViewById(R.id.llRoot);
LayoutInflater.from(this).inflate(R.layout.view_inflate,llRoot,true);
运行效果:
结论: 当有设置父布局为rootView并且粘附到父布局时,即相当于把view_inflate加在父布局层级下
2. 进行Java代码修改
View inflateView = LayoutInflater.from(this).inflate(R.layout.view_inflate, null);
llRoot.addView(inflateView);
运行效果:
结论:该种方式是不设置父布局,将该视图添加进去,但是view_infalte最外层的视图高度失效
3.进阶一下
我们大概了解了Inflate的用法了,也知道是否粘附会带来的效果了。
思考一下我们的RecyclerView和ListView 是否我们在写Item布局的时候在顶层布局高度设置为 match_parent或者是固定的xxdp呢,我们会发现哈哈怎么就一点效果都没呢,是的,这就是上面我们总结的使用 addView会产生根节点高度失效的情况,那么可以预见的是其实RecyclerView亦或是ListView控件都会讲我们的这个item添加上去的,这是需要我们去洞悉的。
布局优化:
我们可以使用merge布局来优化层级,如下例子所示
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/llRoot"
android:background="@color/colorAccent"
tools:context="com.example.mydairytestproject.MainActivity">
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android ="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:parentTag="android.widget.RelativeLayout"
>
<Button
android:text="加载布局"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</merge>
RelativeLayout rlRoot = findViewById(R.id.llRoot);
LayoutInflater.from(this).inflate(R.layout.view_inflate,rlRoot,true);
运行效果:
使用merge标签可以减少布局的层级来达到优化布局的效果,我们应该尽量让层级少一点,这样的效果才会是优秀的。
4. 补充:
View inflate = LayoutInflater.from(this).inflate(R.layout.view_inflate, rlRoot, false);
rlRoot.addView(inflate);
// 等价于
// LayoutInflater.from(this).inflate(R.layout.view_inflate, rlRoot,true);
/*
view_inflate 根高度失效
View inflate = LayoutInflater.from(this).inflate(R.layout.view_inflate, null);
rlRoot.addView(inflate);
*/
/* 如前面所示例: 根高度有效*/
View inflate = LayoutInflater.from(this).inflate(R.layout.view_inflate, rlRoot,false);
rlRoot.addView(inflate);
当然了,又粘附父布局又把子布局添加给父布局,系统会告知你先移除再添加View的
layoutParams
Java代码控制控件的属性
// addRule 设置设置对应ID的属性...
private void resetCenter() {
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT,RelativeLayout.TRUE);
mBtnCenter.setLayoutParams(layoutParams);
}
如何将布局保存入png图像内
// 将可是组件保存在png图片中
View view = getLayoutInflater().inflate(R.layout.activity_location,null);
view.setDrawingCacheEnabled(true);
// 获得宽高...
view.measure(0,0);
view.layout(0,0,view.getMeasuredWidth(),view.getMeasuredHeight());
try {
Bitmap bitmap = view.getDrawingCache();
// 获得bitmap对象了
}catch (Exception e){
}