在Android中,要实现复杂的界面布局,必定少不了嵌套与UI元素的组合;然而在复杂的组合中,总会出现这样那样的问题,更是造成布局的层次过深,对于渲染的效率造成不小的影响。
以下记录一些小小的建议,便于查阅。(持续更新...)
1、推荐使用RelativeLayout替代LineaLayout
android五种布局中,我们最常使用一般都是LinearLayout或RelativeLayout;偶尔也会使用FrameLayout.
线性布局优势:
简单的布局中可以更轻易的构建预期效果,不需要进行位置参照
线性布局缺点:
1、层次过深: 为了实现复杂的布局效果,线性布局实现的主要方式就是嵌套,不同层次的嵌套很容易造成不必要的层次过深问 题,过深的布局层次使得程序进行布局渲染的时间大幅度增加;5.0版的API对布局层次也做了较深的要求。
2、不够灵活: 线性布局的对齐方式存在诸多讲究,相比于相对布局的绝对对齐方式来说,线性布局的对齐,跟线性布局的排列 方向有着很深的关系,且复杂的布局嵌套使得线性布局的对齐更面临一个严峻的挑战。
综上所述,简单的布局,即本身不需要多少嵌套效果就可以实现的页面,线性布局相对简单。但是复杂的布局结构,推荐使用 相对布局替代线性布局。
2、图文组合,推荐使用drawableTop、drawableLeft等属性替代直接使用ImageView+TextView组合形式
在布局中,很容易遇到图文的组合形式,往往图文的内容还需要进行居中处理。这种情况下使用drawableXXX属性比使用
ImageView + TextView组合,要减少两级布局层次,可以大幅度提高渲染速度。如下
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 二级嵌套 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:oriention="horizontal">
<!-- 三级嵌套 -->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/image" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="文字" />
</LinearLayout>
</RelativeLayout>
以下不需要嵌套,直接用drawableLeft属性解决即可
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="文字"
android:drawableLeft="@drawable/image" >
3、 LinearLayout对齐
1、LinearLayout中,对齐方式有两种:gavity与layout_gravity
1)gravity以当前布局为参照,内部控件的对齐方式 ,如TextView相对于布局居中,则布局需要添加gravity
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:oriention="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
2)layout_gravity以父布局为参照,当前控件的对齐方式 ,如TextView相对于布局居中,则TextView需要添 加 layout_gravity
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:oriention="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</LinearLayout>
2、LinearLayout的对齐方式与LinearLayout的orientation属性相关
1)如果orientation=“horizontal”, 那么内部的组件设置垂直居中有效,可设置top与bottom对齐
2)如果orientation=“vertical”, 那么内部的组件设置水平居中有效,可设置left与right对齐
综上所述,LinearLayout的对齐方式,在LinearLayout的排列方向的垂直方向有效。所以在对齐处理上,推荐相对布局
4、ScrollView高度适应下的全屏充满
scrollview一般是根据子组件的高度来定义自己高度的,有时候我们需要scrollview充满全屏,则需要设置
android:fillViewport="true"
5、重复布局的抽离 - include
在开发UI时,我们难免会遇到大量相同的布局,比如在3个不同的页面中,我们都需要添加轮播图的UI,那么同样的布局添加三 遍会降低我们工作效率,也造成了代码冗余;这里我们就需要用include实现
1)首先,我们需要将相同的布局提取出来,新建一个xml文件,比如include_lunbo
2) 其次,我们需要在用到的地方进行声明与添加,如下:
<include
android:id=“@+id/include”
android:layout_width="wrap_content"
android:layout_height="wrap_content"
layout="@layout/include_lunbo">
3) include标签的使用,就当是一个LinearLayout,可以设置padding或margin等
4)调用,查看include_lunbo文件的跟布局,比如跟布局是LinearLayout;可以将include当成一个LinearLayout获取
LinearLayout mInclude = (LinearLayout)findViewById(R.id.include);
include中的控件可以通过include获取
ImageView image = mInclude.findViewById(R.id.xxx);
6、重复样式的抽离 - style
在开发UI时,遇到相同布局的重复调用,我们可以通过include将相同的布局抽离出来,独立为一个xml文件;那么如 果是相同控件的重复使用,我们需要把相同的属性抽离出来,新加为一个style样式,方便统一调用。
比如一个App中,我们往往需要添加很多个提交按钮,所以我们可以把公共属性抽离为一个样式,如
<style name="CommonSubmitButtonStyle">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginLeft">@dimen/common_submitButton_marginLeft</item>
<item name="android:layout_marginRight">@dimen/common_submitButton_marginRight</item>
<item name="android:background">@drawable/selector_submit_button_bg</item>
<item name="android:gravity">center</item>
<item name="android:textColor">@color/white</item>
<item name="android:textSize">@dimen/common_submitButton_textSize</item>
</style>
样式的抽离与使用,可以使App形成统一的组件风格,也可以有效的缩减代码量与效率。
7、LinearLayout空白填充
在UI开发中,我们偶尔会遇到这种情况,很简单的布局:上面一个WebView, 下面一个Button,Button始终停留在页面底 部,
那么很多人就说了,这还不简单,在RelativeLayout中设置alignParentBottom不就行了。但是如果我说Button需要跟在 WebView下面随WebView滚动呢?先把这个例子说明白
1) 上面:webview 下面: Button
2) Button随WebView一起滚动
3) WebView如果超过一屏,则Button在最下面;但是WebView如果不满半屏,这时候Button紧跟在WebView下面也很 丑,这就需要此时将Button放到屏幕底部
以上这种情况,处理起来也不简单,有可能相当费神,下面来分析下这个问题
1)Button要跟随在WebView之后,一起滚动。如果只是Linearlayout排列,WebView过大则Button被顶出屏幕;如果 WebView过小,则Button在屏幕中,况且WebView的高度是很难确定的。
解决:采用网络大众的路径,ScrollVIew与WebView嵌套
2)ScrollVIew的子布局只能有一个,这个布局用RelativeLayout效果是不好的,最好是LinearLayout。这样的话可以实现 Button随WebView一起滚动。如果WebView超出屏幕,那么这么做还算可以,如果WebView不足一屏幕呢?
3)解决WebView不足一屏幕,且Button位于屏幕底部,我们需要根据WebView的高度与Button高度在两者之间填充一块空白
解决:通过Linearlayout的layout_weight属性,使得这快空白可以动态的改变自身高度,从而完美的达到这种效果。
<com.umai.taok.widgets.view.WrappedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadingEdge="vertical"
android:fillViewport="true"
android:scrollbars="none" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.umai.taok.widgets.view.ScrolledWebView
android:id="@+id/cash_detail_imgcon_web"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- 加入填充空白,来适应剩余高度 -->
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<!-- 通过include定义的Button -->
<include
android:id="@+id/cash_detail_bottom_share"
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="@layout/include_cs"
android:visibility="gone" />
</LinearLayout>
</com.umai.taok.widgets.view.WrappedScrollView>