-
布局优化
2015-07-23 17:05:41布局优化1、Include
将 其他的xml文件包含的当前xml文件中来
common_nav.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#000" android:paddingBottom="10dp" android:paddingTop="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:textColor="#FFF" android:layout_alignParentLeft="true" android:text="返回" android:paddingLeft="10dp" android:layout_centerVertical="true" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:textColor="#FFF" android:layout_centerInParent="true" android:text="include优化" android:layout_centerVertical="true" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:textColor="#FFF" android:layout_alignParentRight="true" android:text="前进" android:paddingRight="10dp" android:layout_centerVertical="true" /> </RelativeLayout>
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <include layout="@layout/common_nav"/> </RelativeLayout>
2、merge
目的是通过删减多余或者额外的层级,从而优化整个Android Layout的结构。核心功能就是减少冗余的层次从而达到优化UI的目的!—转载
3、ViewStub
延时加载view
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ViewStub android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout="@layout/common_nav" android:id="@+id/viewStub"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="加载" android:id="@+id/btn" /> </RelativeLayout>
package com.example.administrator.layoutoptimize; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewStub; import android.widget.Button; public class MainActivity extends ActionBarActivity { private boolean inflated = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button)findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ViewStub viewStub = (ViewStub)findViewById(R.id.viewStub); if(!inflated){ inflated = true; viewStub.inflate(); } } }); } }
-
Android布局优化
2018-01-04 16:40:24布局优化渲染基本知识
Android系统每隔16ms就重新绘制一次Activity,也就是说,我们的应用必须在16ms内完成屏幕刷新的全部逻辑操作,即每一帧只能停留16ms。
渲染操作通常依赖于两个核心组件:CPU与GPU:
* 在CPU方面,最常见的性能问题是不必要的布局和失效
* 在GPU方面,最常见的问题是我们所说的过度绘制(overdraw)过度绘制
Overdraw(过度绘制)描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次的UI结构里面, 如果不可见的UI也在做绘制的操作,这就会导致某些像素区域被绘制了多次。这就浪费大量的CPU以及GPU资源。
开启过度绘制检测:设置 -> 开发者选项 -> 调试GPU过度绘制 -> 显示GPU过度绘制
- 蓝色: 意味着overdraw 1倍。像素绘制了两次。大片的蓝色还是可以接受的(若整个窗口是蓝色的,可以摆脱一层)。
- 绿色: 意味着overdraw 2倍。像素绘制了三次。中等大小的绿色区域是可以接受的但你应该尝试优化、减少它们。
- 淡红: 意味着overdraw 3倍。像素绘制了四次,小范围可以接受。
- 深红: 意味着overdraw 4倍。像素绘制了五次或者更多。这是错误的,要修复它们。
如何避免过度绘制
去掉window的默认背景
我们的Activity使用的Theme可能会默认的加上背景色,不需要的情况下可以去掉。
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="windowBackground">null</item> </style>
或者在Activity中进行设置
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getWindow().setBackgroundDrawable(null); }
避免背景色的重复设置
有时候在根布局中设置了背景颜色之后,单独的View,比如TextView就可以不用再设置背景颜色了。
这个主要是结合UI设置,在写布局文件的时候稍加注意就可以避免的clipRect的使用
我们可以通过canvas.clipRect()来 帮助系统识别那些可见的区域。这个方法可以指定一块矩形区域,只有在这个区域内才会被绘制,其他的区域会被忽视。
减少嵌套层次及控件个数
通过Hierarchy Viewer这个方便可视化的工具,可以得到:树形结构总览、布局view、每一个View(包含子View)绘制所花费的时间及View总个数。
备注: Hierarchy Viewer不能连接真机的问题可以通过ViewServer这个库解决;Android的布局文件的加载是LayoutInflater利用pull解析方式来解析,然后根据节点名通过反射的方式创建出View对象实例;
Merge
减少视图层级。 至于为什么要减少视图层级上面已经说过了。
< merge/>标签可用于两种典型情况:
* 布局顶结点是FrameLayout且不需要设置background或padding等属性,可以用merge代替,因为Activity内容试图的parent view就是个FrameLayout,所以可以用merge消除只剩一个。
* 某布局作为子布局被其他布局include时,使用merge当作该布局的顶节点,这样在被引入时顶结点会自动被忽略,而将其子节点全部合并到主布局中。ViewStub
ViewStub称之为“延迟化加载”,不仅可以提高性能,也可以节省内存(初始化对象不被创建)。
App里常见的视图如蒙层、小红点,以及网络错误、没有数据等公共视图,使用频率并不高,如果每一次都参与绘制其实是浪费资源的,都可以借助ViewStub标签进行延迟初始化,仅当使用时才去初始化。<ViewStub android:id="@+id/view_stub" android:layout="@layout/item_layout" android:layout_width="match_parent" android:layout_height="match_parent" />
ViewStub viewStub = (ViewStub)view.findViewById(R.id.view_stub); viewStub.inflate();
include
这玩意儿其实对于布局优化没有多大的作用,但是也是布局中的一个技巧。
主要功能是对布局进行复用SpaceView
Space标签于4.0添加的,继承自View主要用于占位,google官方解释为
Space is a lightweight View subclass that may be used to create gaps between components in general purpose layouts. Space是一个轻量级的View,一般用于分隔组件,布局或者在组件布局之间产生间隔
Android中RelativeLayout和LinearLayout性能分析
直接说结论:
- RelativeLayout会让子View调用2次onMeasure,LinearLayout 在有weight时,也会调用子View2次onMeasure。 所以LinearLayout在没有weight时,效果要更高一点
- RelativeLayout的子View如果高度和RelativeLayout不同,则会引发效率问题,当子View很复杂时,这个问题会更加严重。如果可以,尽量使用padding代替margin。
- 在不影响层级深度的情况下,使用LinearLayout和FrameLayout而不是RelativeLayout。
View优化
从内优化
- 减少View层级
- 去除不必要的背景
- 尽可能减少使用margin,padding,可以在父View中控制。
- 去除不必要的scollbar(onDraw)
- 减少使用渐变(onDraw)
从外优化
- 布局嵌套过于复杂
- View的过度绘制
- View的频繁重新渲染
- UI线程中进行耗时操作
- 冗余资源以及错误逻辑导致加载和执行缓慢
- 频繁触发gc,导致渲染受阻
布局小技巧
viewFillper
android:clipChildren
android:clipToPadding
相关链接
-
Android 布局优化
2018-08-30 18:17:37Android 布局优化,(含 include、Viewstub、merge的用法) -
详解Android布局优化
2020-08-27 18:52:09本篇文章给大家详细分析了Android布局优化的相关知识点以及注意事项,对此有需要的朋友可以参考学习下。 -
性能优化系列——布局优化
2019-05-05 09:25:22布局优化选择合适的布局使用include标签来共享布局使用ViewStub标签来实现布局的延迟加载merge标签的使用布局中背景颜色的设置要慎重尽量使用CompoundDrawable使用Lint检测 这一次我们来说说有关布局优化的问题。...布局优化
这一次我们来说说有关布局优化的问题。布局是非常重要的,写的不好会很影响性能的。布局优化的思路其实很简单,基本上就是减少布局文件的嵌套与减少不必要的绘制。这个问题很容易理解,布局中的层级减少了,就意味着Android系统的绘制时的工作量减少了,那么性能自然就会上来。下面我们就聊一聊布局如何优化。
选择合适的布局
在能满足布局要求的情况下尽量使用消耗性能较低的ViewGroup,比如:如果一个布局既可以使用LinearLayout来布局也可以使用RelativeLayout来布局,这时我们该选择什么呢?首先我们知道越复杂的功能实现起来也越复杂,在源码中也可以看到,RelativeLayout比LinearLayout发杂的多(内部需要考虑水平方向和竖直方向上的依赖,造成两次遍历)。由此我们就能想到,在这种情况下,我们就选择LinearLayout。FrameLayout和LinearLayout一样都是一种简单高效的ViewGroup。但很多时候我们单纯的通过一个LinearLayout或者FrameLayout是无法实现一个布局效果的,需要通过嵌套的方式来完成。这种情况下,不建议使用嵌套,这样很耗费程序的性能,建议使用RelativeLayout或者约束布局来完成。
使用include标签来共享布局
我们在开发时经常遇到好多页面都有相同的布局,这时我们每一个页面都要写一个吗?回答时no,要是都写得话就造成了代码的重复。我们可以将共用的布局抽离出来,独立写成一个XML文件,然后在需要它的页面中使用include标签把它引进来,这样不仅减少了代码量,而且修改起来也非常方便,不需要去每个页面中一个一个的去修改了,只需要修个这一个文件就可以了。使用:
<include layout="@layout/title"/>
< include>标签只支持android:layout_开头的属性,比如android:layout_width,android:layout_height,其他属性暂不支持,但是有一个特例:id属性,如果< include>制定了这个id属性,同时被包含的布局文件的跟布局页包含了id数据,这时会以< include>中的id属性为准。另外需要注意的是:当< include>标签中制定了android:layout_*这样的属性,那么必须要有android:layout_width属性和android:layout_height属性,否则android:layout_*属性是无法生效的。
使用ViewStub标签来实现布局的延迟加载
ViewStub是一种不可视并且大小为0的视图,因此他本身不参与任何的布局和绘制过程,他可以延迟到运行时才填充布局资源。他一般用在:当满足某些条件时某些UI才会展示,在进入一个页面时一般不会展示的情况下,比如网络错误页面,当发生网络错误时我们才展示,正常的情况下我们是不展示的。这时如果我们不使用ViewStub标签,而是直接将网络错误的布局隐藏,这种做法肯定是不好的,它虽然不显示出来,但是它会被inflate并占用资源。如果我们使用ViewStub标签就可以在它需要展示的时候再去填充布局。用法如下
<ViewStub android:id="@+id/net_error_stub" android:inflatedId="@+id/net_error" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout="@layout/net_error" />
其中android:inflatedId的值就是我们在Java代码中调用ViewStub的inflate()或者setVisibility()方法时返回的ID,这个ID就是被填充的View的ID。
merge标签的使用
< merge>标签和< include> 标签一起使用可以减少布局的层级嵌套。由于Activity的ContentView的最外层的布局是FrameLayout,因此,当一个独立的布局文件的最外层是FrameLayout,且这个布局不需要设置android:background或者android:padding等属性时,可以使用< merge>标签来代替< FrameLayout>标签,从而减少一层多余的Framelayout布局。使用一般限定在(使用相同的布局文件)
布局中背景颜色的设置要慎重
如果我们在嵌套的布局中每一层嵌套中都设置背景色,这会造成过度绘制,本来底层布局已经设置过颜色了,你在上层布局中又设置了一边同样的颜色,这时造成的直接结果就是GPU需要渲染这个颜色两边,从而造成了不必要的资源的浪费,降低了应用的性能。
尽量使用CompoundDrawable
如果存在相邻的ImageView和TextView实现的效果,看看能不能将其合并成一个TextView,ImageView中的图片设置成TextView的如下属性之一:drawableTop,drawbaleLeft,drawableRight或者drawableBottom。两者之间的间隔使用drawablePadding来代替。
使用Lint检测
Android Lint不仅可以对代码进行检测,对布局同样能够检测,可以用它来检测布局中哪些地方可以优化
- AndroidLintUseCompoundDrawables:就是CompoundDrawable
- MergeRootFrame:就是merge标签减少布局层次
- TooManyViews:单个布局中存在太多的View,默认情况下,单个布局View的数量最多只能是80个,可以考虑复用布局,减少嵌套等。
- NestedWeights:android:layout_weight属性会使得View控件被测量两次,当一个LinearLayout拥有非0dp值的android:layout_weight属性,这时如果将他嵌套在另一个拥有非0dp值的android:layout_weight属性的LinearLayout,那么这时测量的次数将呈指数级别增加。
- Uselessleaf:一个布局如果既没有子View也没有设置背景,那么它将是不可见的,通常可以移除它。
最后:应用的性能体现在应用代码中的一点一滴
-
Android性能优化之布局优化
2019-04-07 22:27:43Android性能优化之布局优化 前言includemergeViewStub其他的优化方式 ) 前言 Android中布局优化能让我们的界面绘制时间减少,用户感知到的卡顿时间也短,体验感自然而然也就上去了,Android中的布局优化可以从多个...
)前言
Android中布局优化能让我们的界面绘制时间减少,用户感知到的卡顿时间也短,体验感自然而然也就上去了,Android中的布局优化可以从多个方面来入手,include,merge,ViewStub等等一些方面。
include
我们平常在画布局的时候经常碰到一些重复的共性布局,比如说标题栏,导航栏之类的,或者一些按钮之类的,我们在使用的时候重复的写非常麻烦,增加了我们工作量,使用include标签我们就可以避免去写那些无聊的共性代码,其实这个include单独来讲和我们这一篇文章没什么关系,但是他结合merge使用就可以减少一层ViewGroup的包裹,这一个我们在merge中去讲,下面贴出include的用法。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <include android:layout_width="match_parent" android:layout_height="50dp" layout="@layout/base_title_bar"/> </LinearLayout>
merge
merge的存在意义就是为了结合include来减少include引用过来的文件的外层ViewGroup,说白了就是用merge替代ViewGroup,虽然我们使用merge结合include可以达到减少绘制一层ViewGroup的效果,merge的布局是取决于父布局的,父布局是什么,他就是什么,或者我们可以这么理解,下面的代码我们就相当于将base_title_bar.xml中的两个textview直接写入到LinearLayout中,但是这里有个问题,我们的代码有时候include的xml与父布局所要的样式是不一样的,就比如我们当前引入的titlebar是要横向的,但是父布局是纵向的,这时候我们又得去给include外层再加上一层ViewGroup,所以我们在使用merge与include结合的时候要考虑清楚我们共性布局以后可能会使用的场景。
base_title_bar.xml
<?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="out" android:textSize="18sp" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="Title" android:textSize="18sp" /> </merge>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <include android:layout_width="match_parent" android:layout_height="50dp" layout="@layout/base_title_bar"/> </LinearLayout>
ViewStub
ViewStub我们称之为懒加载,需要用到的时候就加载它,但是这里会有一个坑需要注意一下,就是ViewStub在显示之后就无法再隐藏了,因为ViewStub在显示的时候会将自己remove掉,替换成设置的view,这里我们只要记住ViewStub的作用就是一次性的按需加载就行了。我们使用到它的时候再按需加载,达到view在有需要的时候再渲染,以优化性能,下面是使用方法;
坑点:ViewStub中的inflate()只能调用一次,调用多次会报错
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <ViewStub android:id="@+id/viewstub" android:layout_width="match_parent" android:layout_height="50dp" android:layout="@layout/base_title_bar" /> </LinearLayout>
viewStub = (ViewStub) findViewById(R.id.viewstub); //第一种,直接显示,不获取到view if (viewStub != null) { viewStub.setVisibility(View.VISIBLE); } //第二种,显示,并且获取到view if (viewStub != null) { View view = viewStub.inflate();//获取到的是我们要显示出来的view }
其他的优化方式
一些其他的优化方式就是一些细节了,需要我们平时画界面的时候自己多注意注意,并且养成习惯
1.子控件如果和父控件是同样的背景色时,子控件不需要再设定背景色了,用父控件的(能蹭一点是一点)。
2.尽量减少不必要的嵌套,我们上面的include+merge的方式只是其中一种方式,我们平时画界面的时候还是得多注意一下能减少嵌套就减少嵌套(省着点用有限的资源)
3.能用LinearLayout与FrameLayout的时候就不用RelativeLayout,毕竟RelativeLayout控件比LinearLayout与FrameLayout等复杂.
4.合理的借助工具来分析界面是否过度绘制,并且进行合理的避免
-
Android 布局优化方案
2020-12-28 15:45:31在 Android 开发中,UI 布局可以说是每个 App 使用频率很高的,随着 UI 越来越多,布局的重复性、复杂度也会随之增长,这样使得 UI布局的优化,显得至关重要,UI 布局...本篇文章就来总结一下 UI 布局优化的相关技巧。 -
android布局优化
2016-08-12 15:35:50android布局优化 -
android 优化之布局优化
2016-08-08 22:38:46在布局优化中,Androi的官方提到了这三种布局、、,并介绍了这三种布局各有的优势,下面也是简单说一下他们的优势,以及怎么使用,简单复习下。 1、布局重用 标签能够重用布局文件,简单的使用如下: android:...
-
R语言实验素材——ex5.5.xls
-
查看windows属于激活状态
-
Neoway_N58_PCIe_Docs_20201223
-
算法导论二(排序和顺序统计量)——编程大牛的必经之路
-
KeyBoardTest.jar
-
javaweb仓库出入库系统 毕业设计 毕设 源代码 使用教程
-
JAVAEE主流框架之Spring框架实战开发教程(源码+讲义)
-
算法导论(基础知识)——编程大牛的必经之路
-
Python专题精讲 企业级应用日志管理
-
三阶扩展GNL电池模型的研究
-
python3.6.0 Windows32位.txt
-
Tensorflow学习笔记十一——深度强化学习
-
AutoML功能解析
-
线性表和链表的存储和增删改查c++
-
FANUC-机器人操作说明书.pdf
-
全能电子地图下载器3.0(已破).rar
-
你一定要掌握的数据可视化基本设计原则(上)
-
vue+elementui+print.js
-
Qt and Qt Charts
-
变频器软件仅供调试学习.pdf