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.

未完待续。。。。。

上一篇下一篇

猜你喜欢

热点阅读