Android 布局优化

https://www.cnblogs.com/hoolay/p/6248514.html

 https://www.jianshu.com/p/9cb604a917f9

1、首先是善用相对布局Relativelayout

  在RelativeLayout和LinearLayout同时能够满足需求时,尽量使用RelativeLayout,这一点可以从我们MainActivity默认布局就可以看出,默认是RelativeLayout,因为可以通过扁平的RelativeLayout降低LinearLayout嵌套所产生布局树的层级。一般情况下用LinearLayout的时候总会比RelativeLayout多一个View的层级。

那么怎么来优化或者看到一目了然的层级树呢?别担心,Android自带了工具,下面就介绍下Hierarchy View的简单使用吧。
  为了考虑安全问题,真机上不好尝试,虽然也有办法可以解决,但是现在模拟器还是挺快的,也不用折腾那么多了,就可以直接用模拟器来实现好了,接着模拟器运行app,打开需要获取view层级的那个界面。
  然后依次点击菜单Tools -> Android -> Android Device Monitor。


打开Android Device Monitor后,选中Hierarchy View,然后通过Hierarchy View来获取当前的View的分级图。

  
  接着我们就可以来看一下两个分级的不同了。这里主要截取两个不同的地方:
  首先是LinearLayout:


  接着是RelativeLayout:


 很明显的可以看出来RelativeLayout比LinearLayout少了一个层级,当然渲染的时间也是大大减少了。

2.include标签

include标签常用于将布局中的公共部分提取出来,比如我们要在activity_main.xml中需要上述LinearLayout的数据,那么就可以直接include进去了。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.jared.layoutoptimise.MainActivity">
 
    <include layout="@layout/item_test_linear_layout" />
     
</RelativeLayout>

3.merge标签

merge标签是作为include标签的一种辅助扩展来使用,它的主要作用是为了防止在引用布局文件时产生多余的布局嵌套。
  Android渲染需要消耗时间,布局越复杂,性能就越差。如上述include标签引入了之前的LinearLayout之后导致了界面多了一个层级。


  这个时候用merge的话,就可以减少一个层级了,代码如下:

<?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/iv_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:src="@mipmap/ic_launcher" />
 
    <TextView
        android:id="@+id/tv_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="这个是MergeLayout"
        android:textSize="16sp" />
 
    <TextView
        android:id="@+id/tv_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_title"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:layout_toRightOf="@+id/iv_image"
        android:text="这个是MergeLayout,这个是MergeLayout"
        android:textSize="12sp" />
 
</merge>

activity_main就可以直接include了。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.jared.layoutoptimise.MainActivity">
 
    <include layout="@layout/item_merge_layout" />
 
</RelativeLayout>

然后看下层级:

 4.Constaintlayout

用Constaintlayout的话最多就两个层级了,不像Relative和Linear一样一层嵌套一层的。

5.ViewStub

https://blog.csdn.net/qq_32059827/article/details/70882499

 

通过Android:layout来引入需要的布局

默认状态是没有加入内存的

 ViewStub的优点

它是一个轻量级的View,是一个看不见的,不占布局位置,占用资源非常小的控件。我们可以在ViewStub下指定要加载的布局并指定布局id,当我们需要该布局显示的时候,只需要调用ViewStub的inflate()即可。或者setVisibility();

ViewStub的缺点

ViewStub的inflate()只能调用一次,多次调用会有异常抛出。也就是说我们只能对ViewStub加载的布局控制一次,若想多次控制该布局,需要使用View的可见性来控制。但是ViewStub的setVisibility()和View的可见性达到的效果是一样的,并且setVisibility()可以多次调用。

    最后我在重申一遍ViewStub的使用背景,对view的显示只有一次控制的时候,ViewStub是最好的选择,节省资源。若想多次调用,用View的可见性来实现,用ViewStub的setVisibility()也行。

在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个View或某个布局。那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE,然后在代码中动态的更改它的可见性。这样的做法的优点是逻辑简单而且控制起来比较灵活。但是它的缺点就是,耗费资源。虽然把View的初始可见View.GONE但是在Inflate布局的时候View仍然会被Inflate,也就是说仍然会创建对象,会被实例化,会被设置属性。也就是说,会耗费内存等资源

推荐的做法是使用android.view.ViewStub,ViewStub 是一个轻量级的View,它一个看不见的,不占布局位置,占用资源非常小的控件。可以为ViewStub指定一个布局,在Inflate布局的时候,只有 ViewStub会被初始化,然后当ViewStub被设置为可见的时候,或是调用了ViewStub.inflate()的时候,ViewStub所向 的布局就会被Inflate和实例化,然后ViewStub的布局属性都会传给它所指向的布局。这样,就可以使用ViewStub来方便的在运行时,要还 是不要显示某个布局。

1.ViewStub之所以常称之为“延迟化加载”,是因为在教多数情况下,程序 无需显示ViewStub所指向的布局文件,只有在特定的某些较少条件下,此时ViewStub所指向的布局文件才需要被inflate,且此布局文件直 接将当前ViewStub替换掉,具体是通过viewStub.infalte()或 viewStub.setVisibility(View.VISIBLE)来完成; --------------------- 本文来自 杨道龙 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_32059827/article/details/70882499?utm_source=copy

原文地址:https://www.cnblogs.com/volvane/p/9716487.html