1、抽象布局标签
(1) <include>标签 include标签经常使用于将布局中的公共部分提取出来供其它layout共用,以实现布局模块化。这在布局编写方便提供了大大的便利。
以下以在一个布局main.xml中用include引入还有一个布局foot.xml为例。main.mxl代码例如以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?
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
=
“match_parent”
>
<
ListView
android
:
id
=
“@+id/simple_list_view”
android
:
layout_width
=
“match_parent”
android
:
layout_height
=
“match_parent”
android
:
layout_marginBottom
=
“@dimen/dp_80”
/
>
<
include
layout
=
“@layout/foot.xml”
/
>
<
/
RelativeLayout
>
当中include引入的foot.xml为公用的页面底部,代码例如以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?
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 = “match_parent” >
< Button
android : id = “@+id/button”
android : layout_width = “match_parent”
android : layout_height = “@dimen/dp_40”
android : layout_above = “@+id/text” / >
< TextView
android : id = “@+id/text”
android : layout_width = “match_parent”
android : layout_height = “@dimen/dp_40”
android : layout_alignParentBottom = “true”
android : text = “@string/app_name” / >
< / RelativeLayout >
<include>标签唯一须要的属性是layout属性,指定须要包括的布局文件。能够定义android:id和android:layout_*属性来覆盖被引入布局根节点的相应属性值。
注意又一次定义android:id后。子布局的顶结点i就变化了。
(2) <viewstub>标签 viewstub标签同include标签一样能够用来引入一个外部布局。不同的是。viewstub引入的布局默认不会扩张,即既不会占用显示也不会占用位置,从而在解析layout时节省cpu和内存。 viewstub经常使用来引入那些默认不会显示,仅仅在特殊情况下显示的布局,如进度布局、网络失败显示的刷新布局、信息出错出现的提示布局等。
以下以在一个布局main.xml中增加网络错误时的提示页面network_error.xml为例。main.mxl代码例如以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?
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 = “match_parent” >
……
< ViewStub
android : id = “@+id/network_error_layout”
android : layout_width = “match_parent”
android : layout_height = “match_parent”
android : layout = “@layout/network_error” / >
< / RelativeLayout >
当中network_error.xml为仅仅有在网络错误时才须要显示的布局,默认不会被解析,演示样例代码例如以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?
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 = “match_parent” >
< Button
android : id = “@+id/network_setting”
android : layout_width = “@dimen/dp_160”
android : layout_height = “wrap_content”
android : layout_centerHorizontal = “true”
android : text = “@string/network_setting” / >
< Button
android : id = “@+id/network_refresh”
android : layout_width = “@dimen/dp_160”
android : layout_height = “wrap_content”
android : layout_below = “@+id/network_setting”
android : layout_centerHorizontal = “true”
android : layout_marginTop = “@dimen/dp_10”
android : text = “@string/network_refresh” / >
< / RelativeLayout >
在java中通过(ViewStub)findViewById(id)找到ViewStub。通过stub.inflate()展开ViewStub,然后得到子View。例如以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private
View
networkErrorView
;
private
void
showNetError
(
)
{
// not repeated infalte
if
(
networkErrorView
!=
null
)
{
networkErrorView
.
setVisibility
(
View
.
VISIBLE
)
;
return
;
}
ViewStub
stub
=
(
ViewStub
)
findViewById
(
R
.
id
.
network_error_layout
)
;
networkErrorView
=
stub
.
inflate
(
)
;
Button
networkSetting
=
(
Button
)
networkErrorView
.
findViewById
(
R
.
id
.
network_setting
)
;
Button
refresh
=
(
Button
)
findViewById
(
R
.
id
.
network_refresh
)
;
}
private
void
showNormal
(
)
{
if
(
networkErrorView
!=
null
)
{
networkErrorView
.
setVisibility
(
View
.
GONE
)
;
}
}
在上面showNetError()中展开了ViewStub,同一时候我们对networkErrorView进行了保存,这样下次不用继续inflate。
这就是后面第三部分提到的降低不必要的infalte。
viewstub标签大部分属性同include标签相似。
上面展开ViewStub部分代码
ViewStub
stub
=
(
ViewStub
)
findViewById
(
R
.
id
.
network_error_layout
)
;
networkErrorView
=
stub
.
inflate
(
)
;
也能够写成以下的形式
View
viewStub
=
findViewById
(
R
.
id
.
network_error_layout
)
;
viewStub
.
setVisibility
(
View
.
VISIBLE
)
;
// ViewStub被展开后的布局所替换
networkErrorView
=
findViewById
(
R
.
id
.
network_error_layout
)
;
// 获取展开后的布局
效果一致,仅仅是不用显示的转换为ViewStub。通过viewstub的原理我们能够知道将一个view设置为GONE不会被解析,从而提高layout解析速度。而VISIBLE和INVISIBLE这两个可见性属性会被正常解析。
(3) <merge>标签 在使用了include后可能导致布局嵌套过多。多余不必要的layout节点。从而导致解析变慢,不必要的节点和嵌套可通过hierarchy viewer(以下布局调优工具中有详细介绍)或设置->开发人员选项->显示布局边界查看。
merge标签可用于两种典型情况: a. 布局顶结点是FrameLayout且不须要设置background或padding等属性,能够用merge取代,由于Activity内容试图的parent view就是个FrameLayout,所以能够用merge消除仅仅剩一个。 b. 某布局作为子布局被其它布局include时,使用merge当作该布局的顶节点,这样在被引入时顶结点会自己主动被忽略。而将其子节点所有合并到主布局中。
以(1) <include>标签的演示样例为例,用hierarchy viewer查看main.xml布局例如以下图:
能够发现多了一层不是必需的RelativeLayout,将foot.xml中RelativeLayout改为merge,例如以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?
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” >
< Button
android : id = “@+id/button”
android : layout_width = “match_parent”
android : layout_height = “@dimen/dp_40”
android : layout_above = “@+id/text” / >
< TextView
android : id = “@+id/text”
android : layout_width = “match_parent”
android : layout_height = “@dimen/dp_40”
android : layout_alignParentBottom = “true”
android : text = “@string/app_name” / >
< / merge >
执行后再次用hierarchy viewer查看main.xml布局例如以下图:
这样就不会有多余的RelativeLayout节点了。
2、去除不必要的嵌套和View节点 (1) 首次不须要使用的节点设置为GONE或使用viewstub (2) 使用RelativeLayout取代LinearLayout 大约在Android4.0之前。新建project的默认main.xml中顶节点是LinearLayout,而在之后已经改为RelativeLayout,由于RelativeLayout性能更优,且能够简单实现LinearLayout嵌套才干实现的布局。 4.0及以上Android版本号可通过设置->开发人员选项->显示布局边界打开页面布局显示,看看是否有不必要的节点和嵌套。4.0下面版本号可通过hierarchy viewer查看。
3、降低不必要的infalte (1) 对于inflate的布局能够直接缓存。用所有变量取代局部变量。避免下次需再次inflate 如上面ViewStub演示样例中的
if
(
networkErrorView
!=
null
)
{
networkErrorView
.
setVisibility
(
View
.
VISIBLE
)
;
return
;
}
(2) ListView提供了item缓存。adapter getView的标准写法。例如以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Override
public
View
getView
(
int
position
,
View
convertView
,
ViewGroup
parent
)
{
ViewHolder
holder
;
if
(
convertView
==
null
)
{
convertView
=
inflater
.
inflate
(
R
.
layout
.
list_item
,
null
)
;
holder
=
new
ViewHolder
(
)
;
……
convertView
.
setTag
(
holder
)
;
}
else
{
holder
=
(
ViewHolder
)
convertView
.
getTag
(
)
;
}
}
/**
* ViewHolder
*
* @author trinea@trinea.cn 2013-08-01
*/
private
static
class
ViewHolder
{
ImageView
appIcon
;
TextView
appName
;
TextView
appInfo
;
}
关于ListView缓存原理可见Android ListView缓存机制 。
4、其它点 (1) 用SurfaceView或TextureView取代普通View SurfaceView或TextureView能够通过将画图操作移动到还有一个单独线程上提高性能。
普通View的绘制过程都是在主线程(UI线程)中完毕,假设某些画图操作影响性能就不好优化了,这时我们能够考虑使用SurfaceView和TextureView。他们的画图操作发生在UI线程之外的还有一个线程上。 由于SurfaceView在常规视图系统之外。所以无法像常规试图一样移动、缩放或旋转一个SurfaceView。
TextureView是Android4.0引入的,除了与SurfaceView一样在单独线程绘制外。还能够像常规视图一样被改变。
(2) 使用RenderJavascript RenderScript是Adnroid3.0引进的用来在Android上写高性能代码的一种语言。语法给予C语言的C99标准,他的结构是独立的,所以不须要为不同的CPU或者GPU定制代码代码。
(3) 使用OpenGL画图 Android支持使用OpenGL API的高性能画图,这是Android可用的最高级的画图机制,在游戏类对性能要求较高的应用中得到广泛使用。 Android 4.3最大的改变,就是支持OpenGL ES 3.0。相比2.0。3.0有很多其它的缓冲区对象、添加了新的着色语言、添加多纹理支持等等,将为Android游戏带来更出色的视觉体验。
(4) 尽量为全部分辨率创建资源
降低不必要的硬件缩放。这会降低UI的绘制速度,可借助Android asset studio
5、布局调优工具 (1) hierarchy viewer hierarchy viewer能够方便的查看Activity的布局,各个View的属性、measure、layout、draw的时间,假设耗时较多会用红色标记。否则显示绿色。
hierarchy viewer.bat位于<sdk>/tools/文件夹下。
使用可见:Using Hierarchy Viewer , 演示样例图例如以下:
(2) layoutopt layoutopt是一个能够提供layout及其层级优化提示的命令行,在sdk16以后已经被lint代替,在Windows->Show View->Other->Android->Lint Warnings查看lint优化提示
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/115994.html 原文链接:https://javaforall.cn
【正版授权,激活自己账号】:
Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】:
官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...