菜鸟教程
Android知识体系总结之Android部分之Android中的布局篇
布局 | 介绍 | 常用属性 |
---|---|---|
LinearLayour 线性布局 |
LinearLayout容器中的组件一个挨一个排列,通过控制android:orientation属性,可控制各组件是横向排列还是纵向排列 | orientation:布局中组件排列方式 gravity:该组件所包含的子元素的对齐方式(horizontal/vertical) layout_gravity:该组件在父容器里的对齐方式 layout_width:布局的宽度(wrap_content(布局实际大小)/match_parent(填满父容器)) layout_height:布局的高度(参数同上) layout_weight:布局的权重(需要相应设置layout_height/width=0dp) |
RelativeLayout 相对布局 |
相对布局可以让子控件以其兄弟控件或父控件为参考按照其相对位置进行布局,适用于复杂的嵌套布局 | 1. 根据父容器定位,如layout_alignParentLeft\Right\Top\Bottom(左\右\顶部\底部对齐)layout_centerHorizontal\Vertical\InParent(水平\垂直\整体居中) 2. 根据兄弟组件定位,如layout_toLeftOf\RightOf\above\below(参考组件左\右\上\下方)layout_alignTop\Bottom\Left\Right(顶部\底部\左\右对齐) 3. margin:偏移,设置该组件与父容器的边距 4. padding:填充,设置组件内部元素间的边距 |
TableLayout 表格布局 |
TableLayout继承自Linearout,本质上仍然是线性布局管理器。表格布局采用行、列的形式来管理UI组件 每个TableLayout都是由一个或多个TableRow组成的,一个TableRow就代表TableLayout的一行 (不声明行数、列数。tablerow的个数为表格的行数,tablerow中组件个数为该行的列数) |
android:collapseColumns:设置需要被隐藏的列的序号 android:shrinkColumns:设置允许被收缩的列的列序号 android:stretchColumns:设置运行被拉伸的列的列序号 android:layout_column=“2”:表示的就是跳过第二个,直接显示到第三个格子处(从1开始计算) android:layout_span=“4”:表示合并4个单元格,也就说这个组件占4个单元格 |
FrameLayout 帧布局 |
帧布局或叫层布局,从屏幕左上角按照层次堆叠方式布局,后面的控件覆盖前面的控件。帧布局为每个加入其中的组件创建一个空白的区域(称为一帧),每个子组件占据一帧,这些帧会根据gravity属性执行自动对齐 | android:foreground:设置改帧布局容器的前景图像 android:foregroundGravity:设置前景图像显示的位置 |
GridLayout 表格布局 |
GridLayout把整个容器划分为rows × columns个网格,每个网格可以放置一个组件。提供了setRowCount(int)和setColumnCount(int)方法来控制该网格的行和列的数量 | android:orientation:子组件排列方式 android:layout_gravity:子组件对齐方式 android:rowCount:设置网格布局行数 android:columnCount:设置网格布局列数 android:layout_row:设置该组件位于第几行 android:layout_columnL设置该组件位于第几列 |
AbsoluteLayout 绝对布局(过时) |
ConstraintLayout则是使用约束的方式来指定各个控件的位置和关系的,它有点类似于RelativeLayout,但远比RelativeLayout要更强大。
ConstraintLayout非常适合使用可视化方式编写界面(而不适合用XML书写),且ConstraintLayout可以有效地解决布局嵌套过多的问题(复杂的布局总会伴随着多层的嵌套,而嵌套越多,程序的性能也就越差)
Android新特性介绍:ConstraintLayout完全解析
Overdraw:描述的是屏幕上的某个像素在同一帧时间内被绘制了多次。在多层次的UI结构里面,如果不可见的UI也在做绘制的操作,就会导致某些像素区域被绘制了多次,浪费大量的CPU以及GPU资源。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/titlebar_bg">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/gafricalogo" />
FrameLayout>
在应用中使用titlebar布局文件,我们通过标签,布局文件如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/app_bg"
android:gravity="center_horizontal">
<include layout="@layout/titlebar"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
android:padding="10dp" />
...
LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_wrap"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<include
android:id="@+id/layout_import"
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="@layout/include_text" />
LinearLayout>
(1)单独使用include标签的嵌套布局,下面是嵌套布局的include_text.xml文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:text="Hello World!"
android:layout_height="match_parent" />
LinearLayout>
通过hierarchyviewer我们可以看到主布局View树的部分层级结构如下图:
(2)merge与include标签组合使用的布局,下面是嵌套布局的include_text.xml文件:
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Hello World!"/>
merge>
通过hierarchyviewer我们可以看到主布局View树的部分层级结构如下图:
对比截图就可以发现上面的四层结构,现在已经是三层结构了。当我们使用标签的时候,系统会自动忽略merge层级,而把TextView直接放置与平级。
在开发过程中,经常会遇到这样一种情况,有些布局很复杂但是却很少使用。例如条目详情、进度条标识或者未读消息等,这些情况如果在一开始初始化,虽然设置可见性View.GONE,但是在Inflate的时候View仍然会被Inflate,仍然会创建对象,由于这些布局又相当复杂,所以会很消耗系统资源。
定义ViewStub布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_wrap"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ViewStub
android:id="@+id/stub_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inflatedId="@+id/image_import"
android:layout="@layout/layout_image" />
LinearLayout>
layout_image.xml文件如下
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/layout_image">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
LinearLayout>
加载ViewStub布局文件:
动态加载ViewStub所包含的布局文件有两种方式,方式一使用使用inflate()方法,方式二就是使用setVisibility(View.VISIBLE)。
ViewStub一旦visible/inflated,此时ViewStub所指向的布局文件(layout_image.xml)替换掉当前的ViewStub控件,它自己就不在是View试图层级的一部分了。所以后面无法再使用ViewStub来控制布局。
private ViewStub viewStub;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main2);
viewStub = (ViewStub) findViewById(R.id.stub_image);
//viewStub.inflate();//方式一
viewStub.setVisibility(View.VISIBLE);//方式二
ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.setImageResource(R.drawable.image);
}
布局文件映射两种方式 | setContentView() | inflate() |
---|---|---|
调用 | setContentView(R.layout.main) |
View view = inflate.inflate(R.layout.main,null); |
作用 | 将XML布局文件直接显示UI | 将XML布局文件转换为一个View对象 |