Android笔记之Android基本控件与布局

前言

以后想要混移动端,还是要好好学学Android的。找了一些视频,感觉mars老师讲的不错,通俗易懂,条理清晰,非常适合入门。于是把视频中学习到的东西整理出来,方便以后复习。

内容

Android历史

Android的发展史可以参考百度百科

Android开发环境的搭建

我的Android开发环境是翻墙直接在安卓官网上下的。用的是Android Studio1.4版本;sdk文档是安卓6.0;Java是1.8版。这部分网上教程很多,也很简单。

Activity的概念

Activity是指app的某个界面,比如QQ的消息是一个Activity,跳转到联系人,又是一个Activity;在跳到空间动态又是一个Activity。如果后台有个东西下好了,弹出来一个窗口说东西下好了,那也是一个Activity。如果将网站比作安卓系统,那么一个Activity就好比一个网页。

文本框与按钮的使用

Activity启动流程


要启动一个activity,Android系统会先读取AndroidManifest.xml文件,找到默认的activity,生成activity的对象,调用activity中的onCreate()方法。onCreate方法读取activity_main.xml文件,然后在activity上显示内容。

Activity布局文件之间的关系


1、所有res文件夹中的.xml文件都会在gen文件夹的R.Java文件中生成ID;
2、R.layout.activity_main是布局文件的id。
3、SetContenView函数的作用是让当前的activity去显示在R.layout.activity_main布局文件中所定义的内容;
4、Activity显示的内容取决于activity_main.xml文件。

在Activity当中获取代表控件对象


activity_main.xml文件里的布局代码是写死的,怎样显示的就怎样显示,写好了就不能更改。那么和客户互动的、实时变化的属性是怎么弄的呢?答案是用Java写的。在对应的Activity类中,实例化对应的属性,然后对类的实例化进行修改。

View初步

View的基本概念

Activity布局中所用到的控件统统都是View,比如:文本、按钮、单选等等;
View类是所有控件的父类;

在Activity当中获取代表View的对象

设置View的属性

为View设置监听器

什么是监听器:监控着控件的状态变化。
设置监听器的一般步骤:
1、 获取代表控件的对象
2、 定义一个类,实现监听器接口
3、 生成监听器对象
4、 为控件绑定监听器对象

控件布局初步

控件布局的基本概念

什么是控件布局
所谓的控件布局方法,就是指控制控件在Activity当中的位置、大小、颜色以及其他控件样式属性的方法。
1、 使用布局文件完成控件布局(静态)
2、 在Java代码当中完成控件布局(动态)

控件布局的种类

布局方法分类一
a) Linear Layout:要么是全部横着放,要么竖着放
b) Relative Layout:通过控件的相对位置控制布局方式

布局方法分类二
a) ListView
b) GridView

布局的距离单位

1.距离单位px


2.距离单位dp


3.距离单位sp

什么是sp
a、Sp:scaled pixels
b、Sp单位通常是用于指定字体的大小
c、当用户修改手机显示字体时,sp会随之改变
在设置字体的大小size的时候用sp,可以跟随系统;而在设置字体的布局layout时用dp。
在默认系统字体大小的情况下,sp和dp一样大

控件的外边距和内边距

多选按钮checkbox

多选按钮(Checkbox)的基本概念

标签与CheckBox类

CheckBox是View的子类

OnClickListener与OnCheckChangeListener监听器

OnClickListener:监测控件是否被点击了
OnCheckChangeListener:监控控件选中状态

对于OnClickListener
实现功能:选中或取消按钮,则打印出对应的文字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class MainActivity extends AppCompatActivity
{

private CheckBox checkBox_lol;
private CheckBox checkBox_dota;
private CheckBox checkBox_cs;

@Override
protected void onCreate(Bundle savedInstanceState)
{

super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);

checkBox_lol = (CheckBox)findViewById(R.id.lol);
checkBox_dota = (CheckBox)findViewById(R.id.dota);
checkBox_cs = (CheckBox)findViewById(R.id.cs);

CheckBoxListener checkBoxListener = new CheckBoxListener();
checkBox_lol.setOnClickListener(checkBoxListener);
checkBox_dota.setOnClickListener(checkBoxListener);
checkBox_cs.setOnClickListener(checkBoxListener);

}
class CheckBoxListener implements OnClickListener
{

@Override
public void onClick(View v)//View是Checkbox的父类
{

CheckBox box = (CheckBox)v;
if (box.isChecked())//isChecked()是否被选中,是返回true
{
System.out.println("我喜欢玩" + box.getText());
}
else
{
System.out.println("我不喜欢玩" + box.getText());
}
}
}
}

对于OnCheckChangeListener
实现相同功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class MainActivity extends AppCompatActivity
{

private CheckBox checkBox_lol;
private CheckBox checkBox_dota;
private CheckBox checkBox_cs;

@Override
protected void onCreate(Bundle savedInstanceState)
{

super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);

checkBox_lol = (CheckBox)findViewById(R.id.lol);
checkBox_dota = (CheckBox)findViewById(R.id.dota);
checkBox_cs = (CheckBox)findViewById(R.id.cs);

CheckBoxListener checkBoxListener = new CheckBoxListener();
checkBox_lol.setOnCheckedChangeListener(checkBoxListener);
checkBox_dota.setOnCheckedChangeListener(checkBoxListener);
checkBox_cs.setOnCheckedChangeListener(checkBoxListener);
}
class CheckBoxListener implements OnCheckedChangeListener
{

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{

if (isChecked)
{
System.out.println("我喜欢玩" + buttonView.getText());
}
else
{
System.out.println("我不喜欢玩" + buttonView.getText());
}
}
}
}

这一节需要掌握的几个内容有:
1、标签的使用
2、View是CheckBox、TextVIew等视图控件的父类;CompoundButton是复合控件(像CheckBox这样的有开关的控件)父类
3、OnClickListener和OnCheckedChangeListener的区别和用法
4、判断控件是否被选中的函数是isChecked()方法
5、获取一个控件的属性的一般方法是:获取到这个控件,然后getXXX()方法,具体参考关于该控件的文档

CheckBox练习

1、实现全选和全不选
2、强化全选功能,即在取消某个CheckBox时,全选的选项自动取消;勾选全部CheckBox时,全选的选项自动勾选。
3、强化后的全选和反选功能

暂时只实现了第一个功能,尝试了第二个功能,没成功。第三个功能应该需要遍历所有控件。有时间再想想吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//1、实现全选和全不选
public class MainActivity extends AppCompatActivity
{

private CheckBox checkBox_lol;
private CheckBox checkBox_dota;
private CheckBox checkBox_cs;
private CheckBox checkBox_all;

@Override
protected void onCreate(Bundle savedInstanceState)
{

super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);

checkBox_lol = (CheckBox)findViewById(R.id.lol);
checkBox_dota = (CheckBox)findViewById(R.id.dota);
checkBox_cs = (CheckBox)findViewById(R.id.cs);
checkBox_all = (CheckBox)findViewById(R.id.all);

CheckBoxListener checkBoxListener = new CheckBoxListener();
CheckAllBoxListener checkAllBoxListener = new CheckAllBoxListener();
checkBox_lol.setOnCheckedChangeListener(checkBoxListener);
checkBox_dota.setOnCheckedChangeListener(checkBoxListener);
checkBox_cs.setOnCheckedChangeListener(checkBoxListener);
checkBox_all.setOnCheckedChangeListener(checkAllBoxListener);
}
public boolean IsCheckAll ()
{

if (checkBox_lol.isChecked() && checkBox_dota.isChecked() && checkBox_cs.isChecked())
{
return true;
}
else
{
return false;
}
}
class CheckBoxListener implements OnCheckedChangeListener
{

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{

if (isChecked)
{
System.out.println("我喜欢玩" + buttonView.getText());
}
else
{
System.out.println("我不喜欢玩" + buttonView.getText());
}
// if (checkBox_lol.isChecked() && checkBox_dota.isChecked() && checkBox_cs.isChecked())
// {
// checkBox_all.setChecked(true);
// System.out.println("true");
// }
// else if (checkBox_lol.isChecked() || checkBox_dota.isChecked() || checkBox_cs.isChecked())
// {
// checkBox_all.setChecked(false);
// }
// else
// {
// checkBox_all.setChecked(false);
// System.out.println("false");
// }

}
}
class CheckAllBoxListener implements OnCheckedChangeListener
{

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{

if (isChecked)
{
CheckAll(true);
System.out.println("我都喜欢");
}
else
{
CheckAll(false);
System.out.println("我都不喜欢");
}

}

public void CheckAll(boolean bool)
{

checkBox_lol.setChecked(bool);
checkBox_dota.setChecked(bool);
checkBox_cs.setChecked(bool);
}
}
}

这一节额外知道的函数:setChecked(bool)

单选按钮

单选按钮(Radio Button)的基本概念


一组单选按钮只能被选中一个

RadioGroup与RadioButton

的子标签

OnClickListener与OnCheckedChangedListener监听器

注意
RadioGroup的OnCheckedChangedListener导入包是Radio的包,不是上节CheckedBox的包;
RadioButton的OnCheckedChangedListener是compound的包;

CompoundButton是有两种状态的按钮,RadioButton和CheckBox都是其子类。

这一节需要知道:
1、单选按钮的概念
2、如何设置一组单选按钮
3、Radio和Compound包的区别
4、getId()获取控件的ID(该ID在R.Java文件中可以查看)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//设置一个单选按钮
public class MainActivity extends AppCompatActivity
{


private RadioGroup radioGroup;
private RadioButton radioButton1;
private RadioButton radioButton2;
private RadioButton radioButton3;

@Override
protected void onCreate(Bundle savedInstanceState)
{

super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);

radioGroup = (RadioGroup)findViewById(R.id.firstGroup);
radioButton1 = (RadioButton)findViewById(R.id.button1);
radioButton2 = (RadioButton)findViewById(R.id.button2);
radioButton3 = (RadioButton)findViewById(R.id.button3);

RadioGroupListener radioGroupListener = new RadioGroupListener();
radioGroup.setOnCheckedChangeListener(radioGroupListener);

}
class RadioGroupListener implements RadioGroup.OnCheckedChangeListener
{

@Override
public void onCheckedChanged(RadioGroup group, int checkedId)
{

if (checkedId == radioButton1.getId())
{
System.out.println("第一个按钮");
}
else if (checkedId == radioButton2.getId())
{
System.out.println("第二个按钮");
}
else
{
System.out.println("第三个按钮");
}
}
}
}

布局文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<RadioGroup
android:id="@+id/firstGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">

<RadioButton
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮1"/>

<RadioButton
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮2"/>

<RadioButton
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮3"/>


</RadioGroup>

单选按钮练习

实现:两组按钮,第二组按钮跟随第一组按钮动作。比如:第一组按钮A、B;第二组按钮C、D;当点击A时,第二组的C按钮也被选中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<RadioGroup
android:id="@+id/firstGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">

<RadioButton
android:id="@+id/A_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A"/>

<RadioButton
android:id="@+id/B_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"/>

</RadioGroup>

<RadioGroup
android:id="@+id/secondGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">

<RadioButton
android:id="@+id/C_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="C"/>

<RadioButton
android:id="@+id/D_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="D"/>

</RadioGroup>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class MainActivity extends AppCompatActivity
{


private RadioGroup radioGroup1;
private RadioGroup radioGroup2;
private RadioButton radioButton_A;
private RadioButton radioButton_B;
private RadioButton radioButton_C;
private RadioButton radioButton_D;

@Override
protected void onCreate(Bundle savedInstanceState)
{

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

radioGroup1 = (RadioGroup)findViewById(R.id.firstGroup);
radioGroup2 = (RadioGroup)findViewById(R.id.secondGroup);
radioButton_A = (RadioButton)findViewById(R.id.A_button);
radioButton_B = (RadioButton)findViewById(R.id.B_button);
radioButton_C = (RadioButton)findViewById(R.id.C_button);
radioButton_D = (RadioButton)findViewById(R.id.D_button);

RadioGroupListener radioGroupListener = new RadioGroupListener();
radioGroup1.setOnCheckedChangeListener(radioGroupListener);
radioGroup2.setOnCheckedChangeListener(radioGroupListener);
}

class RadioGroupListener implements RadioGroup.OnCheckedChangeListener
{

@Override
public void onCheckedChanged(RadioGroup group, int checkedId)
{

if (checkedId == radioButton_A.getId())
{
radioButton_C.setChecked(true);
}
else if (checkedId == radioButton_B.getId())
{
radioButton_D.setChecked(true);
}
}
}
}

ImageView的使用方法

图片视图(ImageView)的基本概念

ImageView可以显示图片,它是图片的容器
1、在xml文件中使用标签
2、在代码中使用ImageView的对象表示
3、这个图片可以来自res文件夹中,网络上,SD卡上等等。

<ImageView/><ImageView>

标签的方式:

1
2
3
4
5
6
7
<ImageView
android:id="@+id/img_coser"
android:layout_width="100dp"
android:layout_height="160dp"
android:src="@drawable/coser"
android:background="#23ef34"
android:scaleType="centerCrop"/>

ImageView在Java中的方式:

1
2
imageView = (ImageView)findViewById(R.id.img_coser);
imageView.setScaleType(ImageView.ScaleType.FIT_END);

神奇的ScaleType属性

ScaleType属性可以拉伸缩放图片大小,这类似于设置电脑壁纸

ImageView.ScaleType.CENTER|android:scaleType="center"以原图的几何中心点和ImagView的几何中心点为基准,按图片的原来size居中显示,不缩放。
当图片长/宽超过View的长/宽,则截取图片的居中部分显示ImageView的size.当图片小于View 的长宽时,只显示图片的size,不放大。
原则是:用View的大小截取原图。

ImageView.ScaleType.CENTER_CROP|android:scaleType="centerCrop"以原图的几何中心点和ImagView的几何中心点为基准,按比例缩放图片。
它的原则是:
1、以图片的最短边匹配View(老师是这么说的,但我实验的时候是最长边没变,最短边变小了);
2、确保整个图片显示在View里(小了就放大,大了就缩小);
3、它能很好的将图片和View匹配,即使图片恰好能放入View中

ImageView.ScaleType.CENTER_INSIDE|android:scaleType="centerInside"
以原图的几何中心点和ImagView的几何中心点为基准,将图片的内容完整居中显示。
当原图 > imageView时,按比例缩小原图,使其小于等于ImageView,显示全图;
当原图 < imageView时,不放大,居中显示原图。

ImageView.ScaleType.FIT_CENTER|android:scaleType="fitCenter" 把图片按比例扩大(缩小)到View的宽度(短的边),居中显示。显示全部图片,通过按比例缩小(扩大)原来的size使得图片长(宽)等于或小于ImageView的长(宽)。这和centerInside效果差不多啊。
原则:按比例缩放,居中显示全图

ImageView.ScaleType.FIT_START|android:scaleType="fitStart"
把图片按比例扩大(缩小)到View的宽度,显示在View的上部分位置。
原则:按比例缩放,靠上显示全图

ImageView.ScaleType.FIT_END|android:scaleType="fitEnd"
把图片按比例扩大(缩小)到View的宽度,显示在View的下部分位置。关键字:按比例缩放,靠右显示全图
原则:按比例缩放,靠下显示全图

ImageView.ScaleType.FIT_XY|android:scaleType="fitXY"
把图片按照指定的大小在View中显示,拉伸显示图片,不保持原比例,全部显示图片填满View.
原则:不保持比例,拉伸显示全图,填满ImageView

ImageView.ScaleType.MATRIX|android:scaleType="matrix"用matrix来绘制

这一节主要是自己试试各个ScaleType的样式,代码都差不多,在xml文件中改属性,直接预览就可以了。所以代码就不粘出来了。

深入LinearLayout

LinearLayout布局的嵌套

LinearLayout嵌套LinearLayout,通过LinearLayout的orientation属性可以设置不同容器里的控件垂直或水平分布,从而有更加复杂的布局,这当然也就达到了更好的布局效果。比如,他可以实现下面的图:

奇葩的layout_weight属性

layout_weight属性的值用于指定空闲的分配比例
如果layout_weight的值设置如下:

则有:

注意:
1、上面并不是将屏幕平分了,而是将剩余的部分平均分给了两个控件。于是,不难推出1:1是剩余部分分配比例。类似的1:2就是将剩余部分分为3份,第一个控件占1份,第二个控件占2份。
2、如果我就想把屏幕按比例平分,并不是按剩余部分平分怎么办呢?
其实,只需要将该控件的layout_width设置为0dp即可。原理是本身为0,此时剩余部分就是整个屏幕的宽度。

结合本节所学实现下面布局效果:

xml文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">


<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
android:text="猜拳游戏"
android:textSize="30sp"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:gravity="center_horizontal"/>

</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
tools:ignore="DisableBaselineAlignment">

<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1">

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/left"
tools:ignore="ContentDescription"/>

<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">

<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="石头"/>

<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="剪刀"/>

<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="布"/>

</RadioGroup>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1">

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/right"
tools:ignore="ContentDescription"/>

<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">

<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="石头"/>

<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="剪刀"/>

<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="布"/>

</RadioGroup>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>

<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="确定"/>

</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="结果:"
android:textSize="30sp"
tools:ignore="SpUsage"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/result"
android:textSize="30sp"/>

</LinearLayout>


</LinearLayout>

相对布局(上)

什么是相对布局(Relative Layout)

1、与Linear Layout相对的另外一种控件摆放的方式
2、相对布局是通过指定当前控件与兄弟控件或者是父控件之间的相对位置,从而达到控制控件位置的目的

为什么要使用相对布局

1、如果布局相对复杂,那么使用多层嵌套的线性布局将会越来越复杂,嵌套越来越多难免会出错。
2、使用多层嵌套布局较降低性能

相对布局基本思路

1、没有指定的控件将放在屏幕左上角。
2、基本思路:先确定某个控件的位置,然后,其他控件的位置是相对先前确定好位置的控件的位置。

相对布局的两组常用属性

第一组相对布局属性

在使用这组属性时,要先给指定控件+id,这些布局属性后面的值就是该id

1、android:layout_below
将当前控件的上边缘放在指定控件的下边缘,即把当前控件放在指定控件的下边

2、android:layout_above
将当前控件的下边缘放在指定控件的上边缘,即把当前控件放在指定控件的上边

3、android:layout_toLeftOf
将当前控件的右边缘放在指定控件的左边缘,即把当前控件放在指定控件的左边

4、android:layout_toRightOf
将当前控件的左边缘放在指定控件的右边缘,即把当前控件放在指定控件的右边

第二组相对布局属性

1、android:layout_alignLeft
当前控件的左边缘对齐到指定控件的左边缘

2、android:layout_alignRight
当前控件的右边缘对齐到指定控件的右边缘

3、android:layout_alignTop
当前控件的上边缘对齐到指定控件的上边缘

4、android:layout_alignBottom
当前控件的下边缘对齐到指定控件的下边缘

相对布局(中)

对齐至控件的基准线

基准线:为了保证印刷字母的整齐而划定的线。比如音乐乐谱中的五线谱。

android:layout_alignBaseline
当前控件的基准线对齐到指定控件的基准线。它的作用就是使两个控件水平对齐。

与父控件的四个边缘对齐

其属性的值为true/false;
父控件就是包含它的控件;
有多个父控件则遵守就近原则;
可以组合两个属性实现右下角等效果。
1、android:layout_alignParentLeft

2、android:layout_alignParentRight

3、android:layout_alignParentTop

4、android:layout_alignParentBottom

对齐至父控件的中央

1、android:layout_centerInParent
2、android:layout_centerHorizontal
3、android:layout_centerVertical

相对布局(下)

RelativeLayout布局的属性(android4.2)

1、android:layout_alignStart
当前控件的头部和指定id控件的头部对齐

2、android:layout_alignEnd
当前控件的尾部和指定id控件的尾部对齐

3、android:layout_alignParentStart
当前控件的头部和父控件的头部对齐

4、android:layout_alignParentEnd
当前控件的尾部和父控件的尾部对齐

相对布局练习

一、简单的登陆界面

提示:
1、编辑文本标签:<EditText/>
2、编辑文本的提示属性:android:hint;不可见密码属性:android:inputType="textPassword"
3、让控件的长度和父控件的长度一致,既可以使用match_parent也可以使用layout_alignParentLeft与layout_alignParentRight或者layout_alignLeft与layout_alignRight组合的方式达到相同(拉伸)效果。而这样的好处在于降低了耦合性,使对齐方式更加灵活。
4、使用padding设置内边距

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="50dp"
tools:context=".MainActivity">


<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/signTitle"
android:text="登陆界面"
android:gravity="center"
android:textSize="30sp"/>

<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/username"
android:layout_below="@+id/signTitle"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:hint="username"
android:textSize="25sp"/>

<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/password"
android:layout_below="@+id/username"
android:layout_alignLeft="@+id/username"
android:layout_alignParentRight="true"
android:hint="password"
android:textSize="25sp"/>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/cancelButton"
android:layout_alignRight="@+id/password"
android:layout_below="@+id/password"
android:textSize="25sp"
android:text="取消"/>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/okButton"
android:layout_alignBaseline="@+id/cancelButton"
android:layout_toLeftOf="@+id/cancelButton"
android:textSize="25sp"
android:text="确定"/>


</RelativeLayout>

二、用相对布局实现上次线性布局的综合练习

1
2


总结:
1、在用xml布局时,应该想象自己是控件,“我”应该和谁对齐,才不会在移动时“走散”
2、统一一下格式,控件的属性从长到下应为:
—>id
—>必须的宽高
—>相对布局属性
—>图片、文本内容
—>图片、文本样式

时间与日期

TimePicker的使用方法

在xml中设置一个<TimePicker/>标签,效果如下:

TimePicker的常用属性和函数:
属性:
函数:setContentView();

选择时间TimePicker类,和OnTimeChangedListener监听器组合使用

OnTimeChangedListener的使用方法

1
2
3
4
5
6
7
8
9
10
11
12
class TimeListener implements OnTimeChangedListener
{

@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute)
{

/*
view:该对象代表的TimePicker
hourOfDay:用户所选择的小时
minute:用户所选择的分钟
*/

}
}

DatePicker的使用方法

选择日期,与TimePicker类似。

AnalogClock的使用方法

显示时钟的类/标签

ProgressBar

Android当中的进度条

加载数据时的界面。
不同种类的进度条:

各种进度条之间的关系

ProgressBar进度条的风格

通过修改<ProgressBar>控件的属性达到现实不同风格的进度条
比如设置水平风格属性:style="@android:style/Widget.ProgressBar.Horizontal"
默认是垂直风格。
ProgressBar的Style有:
1、水平风格:Horizontal(更适合深色背景)
2、小风格:Small
3、大风格:Large
4、反向风格:Inverse(更适合浅色背景)
5、小反向风格:Small.Inverse
6、大反向风格:Large.Inverse

progressBar的使用方法

进度条的主要属性

1、进度条最大值:max
2、当前进度:progress
3、次要进度的值:SecondaryProgress

进度条常用函数

1、progressBar类有个判断当前进度条是否是不确定的函数:
isIndeterminate():是不确定的返回true;
不确定的进度条是指转圈的不知道什么时候结束的进度条。

2、incrementProgressBy(int)表示主进度条在原来的基础上增加多少

3、incrementSecondaryProgressBy(int)表示次进度条在原来基础上增加多少

小练习

两个按钮,实现点击第一个按钮主进条增加10,点击第二个按钮次进度条增加10.

xml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity"
style="@style/AlertDialog.AppCompat.Light">


<ProgressBar
android:id="@+id/progressBar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:max="100"
android:progress="10"
android:secondaryProgress="20"
style="@android:style/Widget.ProgressBar.Horizontal"/>

<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/progressBar"
android:layout_centerHorizontal="true"
android:text="增加主进度条"/>

<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/button1"
android:layout_centerHorizontal="true"
android:text="增加次进度条"/>


</RelativeLayout>

Java文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class MainActivity extends AppCompatActivity
{

private ProgressBar progressBar;
private Button button1;
private Button button2;

@Override
protected void onCreate(Bundle savedInstanceState)
{

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = (ProgressBar)findViewById(R.id.progressBar);
button1 = (Button)findViewById(R.id.button1);
button2 = (Button)findViewById(R.id.button2);

ButtonListener buttonListener = new ButtonListener();
button1.setOnClickListener(buttonListener);
button2.setOnClickListener(buttonListener);

}

class ButtonListener implements OnClickListener
{


@Override
public void onClick(View v)
{

if (v.getId() == R.id.button1)
{
progressBar.incrementProgressBy(10);
}
else if (v.getId() == R.id.button2)
{
progressBar.incrementSecondaryProgressBy(10);
}

}
}
}

SeekBar和RatingBar

SeekBar和RatingBar是可以拖动的,而上节的ProgressBar是不可以拖动的。

SeekBar的主要属性

1、进度条最大值:max
2、当前进度:progress
3、次要进度的值:SecondaryProgress
比如音乐播放器的下载进度条:当前进度是当前音乐播放的进度;次要进度是下载的进度。

OnSeekBarChangeListener监听器

1、nProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
只要SeekBar进度出现变化就会调用
seekBar:触发了监听器的SeekBar对象
progress:当前SeekBar的进度
fromUser:这次的进度变化是不是用户引起的,如果是用户引起的则为true

2、onStartTrackingTouch(SeekBar seekBar)
当用户开始拖拽时,调用这个方法

3、onStopTrackingTouch(SeekBar seekBar)
当用户停止拖拽时,调用这个方法

RatingBar的主要属性

它的效果如下:

属性:
1、星星的个数:numStars
2、当前等级:progress
3、stepSize:星星前进的步伐;当stepSize的值为0.5时,半颗星半颗星的增长

OnRatingBarChangeListener监听器

onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser)
ratingBar:RatingBar对象
rating:当前得分
fromUser:该次改变是否来自用户

后记