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