文章目录
Android布局管理器
布局管理器可以管理安卓的应用界面里的各种组件,根据运行平台管理组件的大小、位置等。所有布局管理器都是ViewGrop的子类,所有可以调用addView方法向布局管理中添加组件,布局管理器可以进行嵌套。
线性布局管理器(LinearLayout)
LinearLayout可以控制组件横向/纵向排列。线性布局不会换行,组件一个挨着一个排列,如果组件的长、宽太大可能会导致其余的组件不被显示。
布局还是推荐在XML中进行设置,虽然也可以是代码来操作,但相比较而言还是有些不方便。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TestButton1">
</Button>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TestButton2">
</Button>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TestButton3">
</Button>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TestButton4">
</Button>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TestButton5">
</Button>
</LinearLayout>
在这个布局中写了5个按钮只正常显示了3个,还有2个没有被正常显示。
常用操作
XML属性 | 方法 | 说明 |
---|---|---|
android:orientation | setOrientation(int) | 设置布局管理器内组件的排列方式:horizontal(水平排列)、vertical(垂直排列)。 |
android:baselineAligned | setBaselineAligned(boolean) | 该属性设为false,将会组织该布局管理器与子元素的基线对齐 |
android:divider | setDividerDrawable(Drawable) | 设置垂直布局时两个按钮的分割线 |
android:gravity | setGravity(int) | 设置布局管理器内组件的对齐方式。该属性支持top、bottom、left、right、center_vertical、fill_vertical、center_horizontal、fill_horizontal、center、fill、clip_vertical、clip_horizontal几种,也可以同时指定多种对齐方式的组合,通过位或运算进行组合。 |
android:measureWithLargestChild | setMeasureWithLargestChildEnabled(boolean) | 当该属性设为ture时,所有带权的子元素都会具有最大元素的最小尺寸。 |
由于LinearLayout包括的所有子元素都受LinearLayout.layoutParams控制,因此LinearLayout包含的都有以下的XML属性。
XML属性 | 说明 |
---|---|
android:layout_gravity | 指定该子元素在LinearLayout中的对齐方式 |
android:layout_weight | 指定该子元素在LinearLayout中所占的权重 |
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="TestButton1">
</Button>
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="TestButton2">
</Button>
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="TestButton3">
</Button>
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="TestButton4">
</Button>
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="TestButton5">
</Button>
</LinearLayout>
表格布局(TableLayout)
TableLayout继承了LinearLayout,所有其本质依然是线性布局。表格布局采用了行、列的形式来管理UI组件。在表格布局不需要明确声明包含几行几列,而是通过TableRow、其他组件来控制表格行数和列数。需要注意的是,在表格布局中列的宽度有该列中最宽的那个段元个决定,整个表格布局取决于父容器额宽度(默认总是占满父容器本身)。
在表格布局管理器中,可以为单元格设置以下3种行为方式:
- Shrinkable:如果某个列被设为Shrinkable,那么该列的所有单元格的宽度可以被收缩,以保证该表格能适应父容器的宽度。
- Stretchable:如果某个列被设置为Stretchable,那么该列的所有单元格的宽度可以被拉伸,以保证组件能完全填满表格空余空间。
- Collapsed:如果某个列被设为Collapsed,那么该列所有的单元格会被隐藏。
TableLayout继承了LinearLayout,所有TableLayout完全可以支持的全部XML属性。除此之外,TableLayout还支持以下属性:
XML属性 | 相关方法 | 说明 |
---|---|---|
android:collapseColumns | setColumnCollapsed(int,boolean) | 设置需要被隐藏的列序号。多个序列号之间用逗号隔开 |
android:shrinkColumns | setShrinkAllColumns(boolean) | 设置允许被收缩的列的列序号。多个列序号之间用逗号隔开 |
android:stretchColumns | setStretchAllColumns(boolean) | 设置允许被拉伸的列的列序号。多个列序号之间用逗号隔开 |
帧布局(FrameLayout)
帧布局直接继承了ViewGroup组件,帧布局容器为每个加入其中的组件创建一个空白的区域(称谓一帧),每个子组件占据一帧,这些帧都会根据gravity属性执行自动对齐。
FrameLayout常用操作
XML属性 | 相关方法 | 说明 |
---|---|---|
android:foreground | setForeground(Drawable) | 设置该帧布局容器的前景图像 |
android:foregroundGravity | setForegroundGravity(int) | 定义绘制前景图像的gravity属性 |
帧布局示例程序1
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:width="400dp"
android:height="400dp"
android:background="#ff0000">
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:width="350dp"
android:height="350dp"
android:background="#aaf0f0">
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:width="300dp"
android:height="300dp"
android:background="#0ff0f0">
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:width="250dp"
android:height="250dp"
android:background="#ffff00">
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:width="200dp"
android:height="200dp"
android:background="#00ff00">
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:width="150dp"
android:height="150dp"
android:background="#0000ff">
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:width="100dp"
android:height="100dp"
android:background="#ff00ff">
</TextView>
</FrameLayout>
帧布局示例程序2
MianActivity.java
在刚才的xml文件种添加View的id,并在colors.xml中添加自己喜欢的颜色。
package com.kong.layouttest;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;
import java.sql.Time;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
int count=0;
//定义颜色数组
int colorArray[]={R.color.colorAccent,R.color.colorGreen, R.color.colorBlue,
R.color.colorGreen, R.color.colorRed,R.color.colorYellow,R.color.colorPrimaryDark};
//定义视图数组
int viewArray[]={R.id.view1,R.id.view2,R.id.view3,
R.id.view4,R.id.view5,R.id.view6,R.id.view7};
TextView textView[]=new TextView[viewArray.length];
//消息处理函数
Handler handler=new Handler()
{
//当接收到消息时的动作
public void handleMessage(Message message)
{
if(message.what==0x123)
{
for(int i=0;i<viewArray.length;++i)
{
textView[i].setBackgroundResource(colorArray[(i+count)%colorArray.length]);
}
++count;
}
//调用父类方法
super.handleMessage(message);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
//调用父类的方法
super.onCreate(savedInstanceState);
setContentView(R.layout.framelayout);
//给每个View赋值
for(int i=0;i<viewArray.length;++i)
{
textView[i]=findViewById(viewArray[i]);
}
//创建一个定时器,其中的参数为线程
new Timer().schedule(new TimerTask() {
@Override
public void run() {
//发送消息
handler.sendEmptyMessage(0x123);
}
},0,300);
}
}
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#6200EE</color>
<color name="colorPrimaryDark">#3700B3</color>
<color name="colorAccent">#03DAC5</color>
<color name="colorRed">#ff0000</color>
<color name="colorGreen">#00ff00</color>
<color name="colorBlue">#0000ff</color>
<color name="colorYellow">#ffff00</color>
</resources>
这样就可以一个动态的颜色变化的效果
相对布局(RelativeLayout)
相对布局内子组件的位置总司相对兄弟组件、父容器来决定,因此这种布局方式被成为相对布局。如果A组件的位置是由B组件的位置决定的,Android要求先定义B组件,再定义A组件。
- android:gravity
相关方法:setGravity(int) 设置该布局容器内各子组件的对齐方式 - andRoid:ignoreGravity
相关方法:setIgnoreGravity(int) 设置那个组件不受gravity属性的影响
同时为了控制布局容器中各个子组件的布局分布,RelativeLayout提供了一个内部类:RelativeLayout:LayoutParams,该类提供了大量的XML属性来控制RelativeLayout布局容器中子组件的布局分布。
XML属性(设置boolean值) | 说明 |
---|---|
android:layout_centerHorizontal | 控制该子组件是否位于布局容器的水平居中 |
android:layout_centerVertical | 控制该子组件是否位于布局容器的垂直居中 |
android:layout_centerInParent | 控制该子组件是否位于布局容器的中央位置 |
android:layout_alignParentBottom | 控制该子组件是否与布局容器底端对齐 |
android:layout_alignParentLeft | 控制该子组件是否与布局容器的左边对齐 |
android:layout_alignParentRight | 控制该子组件是否与布局容器的右边对齐 |
android:layout_alignParentTop | 控制该子组件是否与布局容器顶端对齐 |
XML属性(设置ID值) | 说明 |
---|---|
android:layout_toRightOf | 控制该子组件位于给出ID组件的右侧 |
android:layout_toLeftOf | 控制该子组件位于给出ID组件的左侧 |
android:layout_above | 控制该子组件位于给出ID的上方 |
android:layout_below | 控制该子组件位于给出Id的下方 |
android:layout_alignTop | 控制该子组件与给出ID组件的上边界对齐 |
android:layout_alignBottom | 控制该子组件与给出ID组件的下边界对齐 |
android:layout_alignLeft | 控制该子组件与给出IF组件的左边界对齐 |
android:layout_alignRight | 控制该子组件与给出ID组件的右组件对齐 |
示例程序
利用相对布局是实现心型九宫格
<?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">
<!--以第9张组件为中心进行相对布局-->
<TextView
android:id="@+id/view9"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:background="@drawable/p9">
</TextView>
<TextView
android:id="@+id/view2"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_toLeftOf="@id/view9"
android:layout_centerVertical="true"
android:background="@drawable/p2">
</TextView>
<TextView
android:id="@+id/view6"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_toRightOf="@id/view9"
android:layout_centerVertical="true"
android:background="@drawable/p6">
</TextView>
<TextView
android:id="@+id/view4"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_below="@id/view9"
android:layout_centerHorizontal="true"
android:background="@drawable/p4">
</TextView>
<TextView
android:id="@+id/view8"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_above="@id/view9"
android:layout_centerHorizontal="true"
android:background="@drawable/p8">
</TextView>
<TextView
android:id="@+id/view1"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_above="@id/view2"
android:layout_alignParentLeft="true"
android:background="@drawable/p1">
</TextView>
<TextView
android:id="@+id/view3"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_below="@id/view2"
android:layout_alignParentLeft="true"
android:background="@drawable/p3">
</TextView>
<TextView
android:id="@+id/view5"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_below="@id/view6"
android:layout_alignParentRight="true"
android:background="@drawable/p5">
</TextView>
<TextView
android:id="@+id/view7"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_above="@id/view6"
android:layout_alignParentRight="true"
android:background="@drawable/p7">
</TextView>
</RelativeLayout>
网格布局(GridLayout)
网格布局时Android4.0之后新增的布局管理器,因此需要在Android4.0之后的版本才可以使用。网格布局的作用类似于HTML中的table标签,他把整个容器划分为rowsXColumns个网格,每个网格可以放置一个组件,除此之外,也可以设置一个组件横跨几行几列。其中通过setRowCount(int)和setColumnCount(int)方法控制在网格的行数量和列数量。
XML属性 | 相关方法 | 说明 |
---|---|---|
android:alignmentMode | setAlignmentMode(int) | 设置该布局管理器采用的对齐模式 |
android:columnCount | setColumnCount(int) | 设置该网格的列数量 |
android:columnOrderPreserved | setColumnOrderPreserved(boolean) | 设置该网格容器是否保留列序号 |
android:rowCount | setRowCount(int) | 设置该网格的行数量 |
android:rowOrderPreserved | setRowOrderPreserved(boolean) | 设置该网格容器是否保留行序号 |
android:useDefaultMargins | setUseDefaultMargins(boolean) | 设置该布局管理器是否使用默认的页边距 |
为了控制GridLayout布局容器中个子组件的布局分布,GridLayout提供了一个内部类:GridLayout.LayoutParams,该类提供了大量的XML属性来控制GridLayout布局容器中子组件的布局分布。
XML属性 | 说明 |
---|---|
android:layout_column | 设置该子组件在GridLayout的第几行 |
android:layout_columnSpan | 设置该子组件在GridLayout横向上跨几行 |
android:layout_gravity | 设置该子组件采用何种方式占据该网格的空间(setGravity(int)) |
android:layout_row | 设置该子组件在GridLayout的第几行 |
android:layout_rowSpan | 设置该子组件在GridLayout纵向上跨几行 |
除了上述的几种布局之外,android还提供了一种绝对布局的方式,绝对布局时不建议使用的,因为它的布局不会根据设备的不同的而改变。
android中常用的布局单位
- PX(像素):每个像素对应屏幕上的一个点
- dip/dp(device independent pixels,设备独立像素):一种基于屏幕密度的抽象单位。在每英寸160点的显示器上,1dp=1px,但随着屏幕密度的改变,dp于px的换算会发生改变,在编程中一遍建议使用dp。
- sp(scaled Pixels,比例像素):主要处理字体的大小,可以根据用户的字体大小首选项进行缩放。
- in(英寸):标准长度单位
- pt(磅):1磅=1/72英寸