Android布局优化
2018-05-31 本文已影响9人
圈圈猫
在Android开发中写布局虽然说小白的事情,但是不要想当然,有些时候布局复杂和树的深度会影响到整个app的体验,一旦布局深了,就容易影响view的绘制。所以google还是很良心的给我们提供了几种优化方案,说实话因为之前写的布局都不太复杂,都没怎么用到过这些标签,今天写个demo方便记忆,顺便写个笔记。
1、Merge标签
1、layout_merge.xml页面
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="10dp"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="16dp"
android:layout_toRightOf="@+id/iv_image"
android:text="火箭vs勇士"
android:textSize="20sp" />
<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/title"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_toRightOf="@+id/image"
android:text="库三丰再次雄伟,然则我登依旧迷离啊"
android:textSize="12sp" />
</merge>
2、引用merge标签布局
activity_main.xml
<?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"
tools:context=".MainActivity"
android:id="@+id/data">
<include layout="@layout/layout_merge"/>
</RelativeLayout>
merge标签和include配合可以起到分离布局产生多余嵌套,它的主要作用是为了防止在引用布局文件时产生多余的布局嵌套。Android渲染需要消耗时间,布局越复杂,性能就越差。
注意:
当我们在代码中用inflate方式加载merge标签布局的时候,attachToRoot一定要设置成true。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout m = findViewById(R.id.data);
View inflate = LayoutInflater.from(this).inflate(R.layout.layout_merge, m, false);
}
}
运行报错:
Caused by: android.view.InflateException: <merge /> can be used only with a valid ViewGroup root and attachToRoot=true
at android.view.LayoutInflater.inflate(LayoutInflater.java:458)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at com.example.my.myproject.MainActivity.onCreate(MainActivity.java:19)
2、viewstub
viewstub是view的子类,他是一个轻量级view,隐藏的没有尺寸的view,只有设置了View.visible或者调用inflate()才会填充布局,占用资源极少。
当ViewStub被设置成可见,或者它的inflate() 方法被调用的时候,布局资源才会被填充,然后ViewStub本身就会被填充起来的布局资源替换掉
1、activity_main.xml
<?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"
tools:context=".MainActivity"
android:id="@+id/data">
<!--<include layout="@layout/layout_merge"/>-->
<ViewStub
android:id="@+id/vs"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout="@layout/layout_view_stub"/>
</RelativeLayout>
2、layout_view_stub.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="哈哈地方啊"/>
</LinearLayout>
3、MainActivity.java
package com.example.my.myproject;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewStub;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// RelativeLayout m = findViewById(R.id.data);
// View inflate = LayoutInflater.from(this).inflate(R.layout.layout_merge, m, false);
ViewStub stub = findViewById(R.id.vs);
//方式一:
// View inflate = stub.inflate();
//方式二:
stub.setVisibility(View.VISIBLE);
}
}
注意:
viewstub不能使用merga标签,因为merga标签需要添加parentview 并且attachedView = true才不会报错。
visibility和inflate两句代码不能共存,因为inflate方法只能调用一次,而setVisibility实际上会间接调用inflate.
未完待续。。。。。