Android学习笔记8 界面编程之基础必备
这篇是Android用户界面编程系列学习总结的第一篇,写的比较基础,但却是我们在平常开发中必须要了解的内容,包括基本控件相关内容,几种常见布局,Android布局中的尺寸单位之间的关系等等,在此基础上之后几天将推出这个系列的后续几篇。
一、概述
二、基础控件
三、六大布局
四、常见尺寸单位
五、总结
一、概述
UI,即用户界面,User Interface。因为Android应用大多是运行于手机上的程序,这种程序给用户的第一印象就是界面,所以有必要给用户提供一个良好的图形用户界面。Android本身为我们提供了非常丰富的用户界面控件,借助于这些控件,我们可以很方便地进行界面开发。面对如此之多的控件,最重要的还是熟练使用这些控件的同时学习这些控件的实现原理,只有这样,才能开发出更多的自定义控件,实现更多更好的效果。
二、基础控件
这部分主要简单介绍下基础控件的一些内容,不过具体如何使用这些控件这里不作介绍,因为如果要介绍的话内容实在太多,具体使用的时候大家可以参考官方文档或者相关教程。
1. TextView
2. ImageView
3. ProgressBar
上面列出了三种控件,分别是显示文字的TextView,显示图片的ImageView以及进度条ProgressBar,相信大家都用过。我们知道Android提供了相当多的控件,但是理清这么多控件之间的关系,达到触类旁通,举一反三的目的才是最主要的。
1、TextView
TextView继承结构图
首先我们可以看到上面这张TextView继承结构图,我把关键的东西标了出来,可以看到我们平时经常使用的Button、EditText还有CheckBox等控件都是TextView的直接或者间接子类。
2、ImageView
ImageView继承结构图
3、ProgressBar
ProgressBar继承结构图
从上面几张图可以看到,Android对于如此多的控件是采用层层继承扩展来实现的,从最开始的View到ViewGroup再到之后的各种常用控件及布局,我们在学习这些控件的同时,理清这其中的关系,往往效率能提高不少。
View继承关系
三、六大布局
上面简单介绍了Android基础控件部分的内容,在Android界面设计的过程中,我们会用到各式各样的控件,比如用户点击的按钮Button,用户输入信息的EditText,展示一张图片的ImageView,那么如何在界面上放置这些控件,灵活地组织这些控件,使它们能够构成一个完整友好的界面呢?
A layout defines the visual structure for a user interface, such as the UI for anactivity orapp widget.
正如官方文档的介绍,布局的作用主要是定义用户界面的可视化结构的。当我们在Android Studio中新建好一个普通的项目时,通常会看到一个定义好的布局文件,最外面是一个相对布局RelativeLayout,里面包含一个显示文字为Hello World!的TextView。我们在切换到Design试图下,可以拖动其它控件到布局的任意位置。如果我们在一开始把布局的RelativeLayout修改成LinearLayout,那么观察拖动后的控件位置发现它们都在一个方向上。
Android主要有六种布局,下面逐一介绍。
1、RelativeLayout
2、LinearLayout
3、TableLayout
4、FrameLayout
5、GridLayout
6、AbsoluteLayout
1、RelativeLayout
相对布局是一个用相对位置来展示其中的控件的视图组合。比如在编辑用户登录界面时,我们可以用android:layout_toRightOf设置EditText位于TextView的右边,有需要的话,我们可以设置一个控件在另一个控件的任意位置,上下左右都可以。
我自己在平时的开发中,相对布局用的并不多,主要是感觉有时拖动这些控件的时候不注意的话容易乱,当然熟能生巧,相信熟练的话这些都不是问题。下面是个简单的例子。
<?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">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="112dp"
android:text="账号"
android:textSize="20sp" />
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/textView"
android:hint="邮箱或手机号码"
android:textSize="15sp" />
</RelativeLayout>
2、LinearLayout
线性布局是把其中的控件放置在同一个方向上的视图组合,分为垂直方向放置和水平方向放置两种。我们可以通过属性android:orientation来指定线性布局的方向。
相对来说,我自己在使用的时候线性布局用的比较多,控制简单,很方便。下面是个简单的例子。
<?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:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="账号"
android:textSize="20sp" />
<EditText
android:id="@+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:hint="邮箱或手机号码"
android:textSize="15sp" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="密码"
android:textSize="20sp" />
<EditText
android:id="@+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="输入密码"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
3、TableLayout
表格布局,用行、列的形式来管理布局里的UI控件,每个表格布局通常包含多个TableRow(表格行),每次向TableLayout里添加一个TableRow,就相当于增加一行,每次向TableRow里添加一个控件,那么这个控件就是一列。如果直接往TableLayout添加一个控件,那么这个控件就占据一行。
TableLayout是继承自LinearLayout的布局,所以结合线性布局使用起来十分方便。TableLayout在使用过程中主要有几个关键点,可以通过shrinkColumns属性设置某列可以被收缩,可以通过stretchColumns属性设置某列可以被拉伸,可以通过collapseColumns属性设置某列隐藏,为下面是个简单的例子:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:collapseColumns="0"
android:orientation="vertical"
android:shrinkColumns="1"
android:stretchColumns="2">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="你好0" />
<TableRow>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="你好1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="你好2" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="你好3" />
</TableRow>
</TableLayout>
4、FrameLayout
帧布局,为加入其中的控件依次创建一个空白区域(即帧),每个子控件占据一帧,有种控件一个个叠加的效果。
在动态添加Fragment时,常常会用到帧布局。
<?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="300dp"
android:layout_height="300dp"
android:background="#0000ff" />
<TextView
android:layout_width="250dp"
android:layout_height="250dp"
android:background="#00ff00" />
<TextView
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#ff0000" />
<TextView
android:layout_width="150dp"
android:layout_height="150dp"
android:background="#bbbbbb" />
</FrameLayout>
5、GridLayout
网格布局,它把整个布局划分成固定行乘以固定列的网格,每个网格里可以放置一个控件,此外,它还能控制一个控件横跨多少行,纵跨多少列。
需要注意的是,网格布局是Android 4.0,即Api 14新增的布局,所以要注意应用支持的版本,4.0以前如果要使用应该要导入相应的库。下面是个GridLayout使用的例子。
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="4"
android:rowCount="3">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_columnSpan="4" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</GridLayout>
6、AbsoluteLayout
绝对布局,因为绝对布局是直接指定一个控件的绝对位置,大部分情况下都不会去使用这个布局,了解即可。
四、常见尺寸单位
在布局文件的编写过程中,我们常常这样设置一个控件的高度:
android:layout_height="50dp"
有时,我们这样为TextView里的字体设置大小
android:textSize="20sp"
可以看到上面两部分,设置控件高度用到的单位是dp,设置字体大小用到的单位是sp,Android中还有几个常见的单位,它们之间的联系与换算方式是什么呢?这里做个简单介绍。
dp,即dip,Density-independent pixel,一种基于屏幕物理密度的抽象单位,使用dp单位是适配不同屏幕的最简单的方案。在每英寸 160 点的显示器上,1dp=1px 。当运行在屏幕密度高的设备上时,画1dp所用的像素就高一点,否则就低一点。dp到px转换的比例会随屏幕密度变化,但是不是完全按比例来的。
px: pixels(像素),与屏幕的真实像素一致,这个尺寸单位不建议使用,因为不同设备的屏幕尺寸差别很大,每个设备上每英寸的像素点的数量都可能不同并且屏幕的像素也有差异。
pt: point,是一个标准的长度单位,1pt=1/72英寸,用于印刷业,简单易用。
sp: Scale-independent Pixels,规模无关像素, 主要用于字体显示, google 的建议,TextView 的字号最好使用 sp 做单位,查看TextView的源码可知 Android 默认使用 sp 作为字号单位。
关于单位之间换算:
- dp与px换算公式:
pixs =dips * (densityDpi/160).
dips=(pixs乘以160)/densityDpi
- dp与px转换的方法:
public static int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
-
dip和px 的关系:
QVGA: density=0.75; densityDpi=120; QVGA(240 X 320)
HVGA: density=1.0; densityDpi=160; HVGA(320 X 480)
VGA: density=1.0; densityDpi=160; VGA(480 X 640)
WVGA: density=1.5; densityDpi=240; WVGA(480 X 800)
WQVGA:density=2.0; densityDpi=120; WQVGA(240 X 400)
五、总结
用户界面常用的一些,也是最基本的总结就是这些了,还有很多东西需要大家自己去学习。