封面画师:画师JW 封面ID:77038942
Android 简介
安卓是一种基于 Linux 内核(不包含 GNU 组件)的自由及开放源代码的操作系统。主要使用于移动设备,如智能手机和平板电脑,由 Google 公司和开放手机联盟领导及开发。Android 操作系统最初由 Andy Rubin 开发,主要支持手机。2005 年 8 月由 Google 收购注资。2007 年 11 月,Google 与 84 家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良 Android 系统。随后 Google 以 Apache 开源许可证的授权方式,发布了 Android 的源代码。
Android 一词的本义指「机器人」,同时也是 Google 于 2007 年 11 月 5 日宣布的基于 Linux 平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成。
Android 一词最早出现于法国作家利尔亚当(Auguste Villiers de l’Isle-Adam)在 1886 年发表的科幻小说《未来夏娃》(L’ève future)中。他将外表像人的机器起名为 Android。
Android 的 Logo 是由 Ascender 公司设计的,诞生于 2010 年,其设计灵感源于男女厕所门上的图形符号,于是布洛克绘制了一个简单的机器人,它的躯干就像锡罐的形状,头上还有两根天线,Android 小机器人便诞生了。其中的文字使用了 Ascender 公司专门制作的称之为「Droid 」 的字体。Android 是一个全身绿色的机器人,绿色也是 Android 的标志。颜色采用了 PMS 376C 和 RGB 中十六进制的#A4C639 来绘制,这是 Android 操作系统的品牌象徵。有时候,它们还会使用纯文字的 Logo。
内容摘录于百度百科——Android。
Android Studio
Android Studio 是开发 Android 应用程序的官方 IDE,基于 Intellij IDEA。
删除一个 Module 的方法:选中要删除的 Module > Open Module Settings > 选中要删除的 Module,然后点击"-" > 坚持磁盘目录下文件是否被删除,如果没有,删除即可。
java 节点
解决:Build —> Clean Project
- Android Studio 卡在「Waiting for target device to come online」:
后续补充:
这些方法没啥卵用,不用看了,可以试试选用 Target 不带有 Google 字样的 x64 模拟器。
解决:每种解决都可以试一下!参考链接
- 将镜像改成 x86_64 然后新建一个模拟器。
- 打开 AVD manager 找到自己的模拟器,然后右击模拟器,选择 Cold Boot Now,模拟器打开并提示一行信息,直接 dismiss。
- 重启 AS,重启系统。(注意:如果你是 Win10 系统,重启的时候记得按住 shift 来禁用系统的强制签名)
- paltform-tools 目录下 adb kill-server,然后 adb start-server。
- SDK tool 或 paltform tool 有更新,下载更新。
- 删除<Your_AVD_Directory>.android\avd\Pixel_XL_API_28.avd 目录下.lock 文件,然后重新载入。
- 打开 AVD manager,选中模拟器,右击,wipe data,然后启动模拟器。
res 节点
drawable 目录
主要用于放置位图文件(PNG,JEPG 或者 GIF)、9-Patch 图片文件、Shape Drawable、Drawable 对象等 XML 资源文件。图片命名不能大写!!
layout 目录
用于存储安卓的布局文件。
布局文件就是用于控制窗口中显示哪些内容。
mipmap 目录
创建项目后会创建多个子目录(mipmap-mdpi、mipmap-hdpi、mipmap-xhdpi、mipmap-xxhdpi、mipmap-xxxhdpi)。用于储存不同分辨率的启动图标文件。
drawable和mipmap的区别:
- 9-Patch 图片和 Shape 资源文件只能放在 drawable 目录中;
- 需要适应屏幕分辨率的图片推荐放在 mipmap 目录中,可以提高显示性能、占用内存更少;
values 目录
主要用于保存字符串资源、样式资源、尺寸资源、颜色资源。
UI 布局
View
我们一般不直接使用 View 类,而是使用 View 类的子类(比如 TextView)。
View类位于android.view包中;View类的子类一般都用于android.widget包中。
常用属性:
1
| android:id = "@+id/user"
|
android:background 为组件设置背景(可以是图片资源也可以是颜色)
1
| android:background = "@mipmap/bg" //bg为图片资源名称,需要将资源放置于mipmap目录下
|
android:padding 为组件四周设置 一样的内边距
衍生属性:
android:paddingLeft、android:paddingTop、android:paddingRight、android:paddingBottom
API 17 以后:
android:paddingStart = android:paddingLeft
android:paddingEnd = android:paddingRight
ViewGroup
理解:若将 View 比作成整个窗户,那么 ViewGroup 就是窗户框。用于控制 View 如何摆放。
实际使用中经常使用 ViewGroup 的子类,如 RelativeLayout、LinearLayout 等。
ViewGroup 控制其子组件分布时依赖的内部类:
ViewGroup.LayoutParams 类和 ViewGroup.MarginLayoutParams 类。
ViewGroup.LayoutParams常用于设置布局高度和宽度。
ViewGroup.MarginLayoutParams用于控制子组件的外边距。
-
属性:android:layout_marginTop、android:layout_marginBottom、android:layout_marginLeft、android:layout_marginRight
API 17 以后:
android:layout_marginStart = android:layout_marginLeft
android:layout_marginEnd = android:layout_marginRight
-
属性值:通过尺寸变量或具体的值进行设置
Android UI 组件的层次结构
所有的 UI 界面都是由 View 类、ViewGroup 类或其子类组合而成的。
ViewGroup 中可以包含多个 View 和 ViewGroup,其中的 ViewGroup 又可以包含多个 View 和 ViewGroup…
禁止套娃!!
控制 UI 界面
方法:使用XML布局文件控制UI界面(推荐)、在 Java 代码中控制 UI 界面、使用 XML 和 Java 代码混合控制 UI 界面、开发自定义的 View。
使用 XML 布局文件控制 UI 界面
- 在 Android 应用的 res/layout 目录下编写 XML 布局文件(如 activity_main.xml)
- 在 Activity 中使用以下 Java 代码显示 XML 文件中布局的内容
1
| setContentView(R.layout.activity_main);
|
android:layout_gravity 用来设置该 view 相对与父 view 的位置,比如值为 center 将该 view 置于父 view 中间。
RelativeLayout
RelativeLayout:相对布局管理器
1
| <RelativeLayout></RelativeLayout>
|
使用相对布局需要一个参考点,所有的组件以参考点的位置为基准。
如果有 根据组件间的相对位置来控制组件的摆放 的设计需求,那么此时就可以使用相对布局。
部分属性 参考ViewGroup ,其他属性:
android:gravity 用于设置布局管理器中各个子组件的摆放方式
android:ignoreGravity 指定哪个子组件不受android:gravity的影响
RelativeLayout.LayoutParams
属性:相对布局管理器组件上设置的属性,而不是布局管理器上设置的属性。
| 属性名 |
作用 |
android:layout_above |
上方 |
android:layout_below |
下方 |
android:layout_toLeftOf |
左方 |
android:layout_toRightOf |
右方 |
| 属性名 |
作用 |
android:layout_alignParentBottom |
底部对齐 |
android:layout_alignParentLeft |
左对齐 |
android:layout_alignParentRight |
右对齐 |
android:layout_alignParentTop |
顶部对齐 |
| 属性名 |
作用 |
android:layout_alignBottom |
底部对齐 |
android:layout_alignLeft |
左对齐 |
android:layout_alignRight |
右对齐 |
android:layout_alignTop |
顶部对齐 |
| 属性名 |
作用 |
android:layout_centerHorizontal |
位于水平居中 |
android:layout_centerInparent |
位于中间位置 |
android:layout_centerVertical |
位于垂直居中 |
LinearLayout
LinearLayout:线性布局管理器
1
| <LinearLayout></LinearLayout>
|
将放入其中的组件按照水平或垂直的方向进行排列。
若其内部组件一个挨着一个(按行或列)排列到屏幕的边缘以后,剩下的组件将不会显示出来。
本身属性
android:orientation 设置线性布局内组件的排列方式
1 2 3
| //属性值:仅有两个
horizontal: 水平方向
vertical: 垂直方向
|
android:gravity 设置线性布局内组件的显示位置
属性值之间可以使用|分割,达到组合的效果,如
1
| android:gravity = "right|bottom" //使布局管理器位于右下角
|
子组件属性
android:layout_weight 设置子组件所占的权重,即:组件占父容器 剩余空间 的比例 默认值为 0

gravity 和 layout_gravity 的不同处
gravity 是设置控件自身内部元素的对齐方式。比如一个 TextView,则是设置内部文字的对齐方式。如果是 ViewGroup 组件如 LinearLayout 的话,则为设置它内部 view 组件的对齐方式。
layout_gravity 是设置控件自身相当于父容器的对齐方式。比如,一个 TextView 设置 layout_gravity 属性,则表示这 TextView 相对于父容器的对齐方式。
FrameLayout
FrameLayout:帧布局管理器
1
| <FrameLayout></FrameLayout>
|
帧布局容器为每个加入其中的组件创建一个 空白的区域 (称为一 帧 ),每个子组件占据一帧,默认是把他们放在这块 区域的左上角 ,但是我们也可以 通过layout_gravity属性 ,指定到其他的位置。
帧布局会把组件按先后顺序一个一个地叠加在一起,上层的组件会覆盖底层的组件 ,不能 将底层的帧移到上层。
帧布局的 大小由组件中最大的子组件决定 ,如果每个组件的大小一样大的话,那么同一时刻只能看到最上面的那个组件。
本身属性
前景图像:始终位于最上层的图像,其他组件无法将它盖住
android:foreground 为当前的帧布局管理器 设置一个前景图像
属性值常为图片资源。
android:foregroundGravity 设置 前景图像的位置
属性值之间可以使用|分割,达到组合的效果,如
1
| android:foregroundGravity = "right|bottom" //使前景图像位于右下角
|
TableLayout
TableLayout:表格布局管理器
1
| <TableLayout></TableLayout>
|
表格布局由 TableLayout 类代表,其会采用行、列的形式来管理 UI 组件。
TableLayout 通过添加 TableRow、其它组件来控制表格的行数和列数,而不需要明确地声明包含多少行、多少列。
每次向 TableLayout 中添加一个 TableRow,该 TableRow就是一个表格行,TableRow 也是容器,因此它也可以不断地添加其它组件,每 添加一个子组件该表格就增加一列。若直接向 TableLayout 中添加组件,那么这个 组件将直接占用一行。
在表格布局中,列的宽度由该列中 最宽的那个单元格决定,整个表格布局的宽度则取决于 父容器的宽度(默认总是占满父容器本身)。
列单元格常用的三种行为方式:
- Shrinkable。该列的所有单元格的宽度可以被 收缩,以保证该表格能 适应父容器的宽度
- Stretchable。该列的所有单元格的宽度可以被 拉伸,以保证组件能 完全填满表格空余空间
- Collapsed。该列的所有单元格会被 隐藏
1 2 3 4 5 6 7 8 9
| <!--定义一个表格布局,指定第2列允许收缩,第3列允许拉伸,第4列允许隐藏。-->
<!--列数是从0开始的-->
<TableLayout
android:id="@+id/tableLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:shrinkColumns="1"
android:stretchColumns="2"
android:collapseColumns="3">
|
GridLayout
GridLayout:网格布局管理器
1
| <GridLayout></GridLayout>
|
GridLayout 布局是 Android 4.0 以后引入的新布局,和 TableLayout(表格布局) 有点类似,不过它功能更多,也更加好用:
- 可以自己设置布局中组件的排列方式
- 可以自定义网格布局有多少行,多少列
- 可以直接设置组件位于某行某列
- 可以设置组件横跨几行或者几列
本身属性
android:columnCount 指定网格最大列数
android:orientation 与线性布局属性一样,默认采用水平排列
android:rowCount 指定网格的最大行数
GridLayout .LayoutParams
属性:网格布局管理器组件上设置的属性,而不是布局管理器上设置的属性。
这些属性可以控制网格布局管理器上各子组件的分布。
| 属性名 |
含义 |
android:layout_column |
指定子组件位于网格的第几列 |
android:layout_columnSpan |
指定子组件横向跨几列 |
android:layout_columnWeight |
指定子组件在水平方向上的权重 |
android:layout_gravity |
指定子组件以什么方式占据网格空间 |
android:layout_row |
指定子组件位于网格的第几行 |
android:layout_rowSpan |
指定子组件纵向跨几行 |
android:layout_rowWeight |
指定子组件在垂直方向上的权重 |
1 2 3 4 5
| <!--从0开始计算,与表格布局类似-->
<!--设置组件位于第二行-->
android:layout_row = "1"
<!--设置组件位于第三列-->
android:layout_column = "2"
|
布局管理器的嵌套
嵌套原则
- 根布局管理器必须包含 xmlns 属性;
- 在一个布局文件中,最多只能有一个根布局管理器,如果需要有多个还需要使用一个根布局管理器将它们括起来;
- 不能嵌套地太深,如果嵌套太深,会影响性能。
不能套娃太深!!
基本 UI 组件
使用 UI 组件时注意字母的大小写!
使用 UI 组件时注意字母的大小写!
使用 UI 组件时注意字母的大小写!
文本框组件
属性
android:text 设置文本框中要显示的内容。
属性值为字符串资源(res/values/string.xml 进行设置)名称。
1
| android:text = "@string/demo" //字符串资源名为demo
|
android:textSize 设置字体大小,单位为 sp
android:textColor 设置字体颜色
android:singleLine 设置文本框单行显示文字 属性值为 true 时,则单行显示
跑马灯——使用 TextView 内的属性实现
1 2 3 4 5 6 7 8 9 10 11 12
| <!--激活焦点,必须-->
android:focusable="true"
<!--单行显示,必须-->
android:singleLine="true"
<!--这里设置为超出文本后滚动显示,必须-->
android:ellipsize="marquee"
<!--TouchMode模式的焦点激活,必须-->
android:focusableInTouchMode="true"
<!--这个是设置滚动几次,这里是无限循环-->
android:marqueeRepeatLimit="marquee_forever"
<!--横向超出后是否有横向滚动条-->
android:scrollHorizontally="true"
|
除了添加这些属性外,还需要在对应的 Activity 中添加:
1 2 3 4 5 6
| protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.tv);
textView.setSelected(true); //必须
}
|
这只是简单实现页面中单个跑马灯,如果界面中有 EditText 等能获取焦点的组件时,这种方法会失效。具体操作可以参考:Android之跑马灯详解
编辑框
它是文本框组件的子类。
属性
android:hint 设置默认提示内容,属性值为字符串
android:inputType 设置输入内容类型,如:
1 2
| android:inputType = "textPassword" <!--设置输入类型为密码-->
android:inputType = "number" <!--设置输入类型为数字-->
|
android:drawableLeft 在编辑框左侧绘制一个图像,常用于图标的设置,属性值为图片资源,如:
1
| android:drawableLeft = "@mipmap/mr" <!--mr为图片资源名-->
|
android:drawableStart 在 API 17 后,android:drawableStart 等同于 android:drawableLeft 的使用。
android:drawableBottom 在文字底部绘制图像
android:drawableRight 在文字右侧绘制图像
android:drawableEnd 在 API 17 后,android:drawableEnd 等同于 android:drawableRight 的使用。
android:drawableTop 在文字顶部绘制图像
android:drawablePadding 设置文字与图像之间的距离,单位 dp
android:lines 设置编辑框的最大行数,当超过设置的数值时,自动向上滚动
获取编辑框组件内容
首先需要给编辑框组件设置一个 id,假设设置 id 为 et,则在 Activity 中有:
1 2 3 4 5
| protected void onCreate(Bundle saveInstanceState){
...
EditText et = findViewById(R.id.et);
et.getText(); //这样就可以获取到编辑框中的内容
}
|
普通按钮
它是文本框组件的子类。
为普通按钮添加点击事件监听器
首先需要给按钮设置一个 id,假设设置 id 为 btn,则在 Activity 中有:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| protected void onCreate(Bundle savedInstanceState) {
...
//根据Button ID绑定Button
Button mButton = findViewById(R.id.btn);
//按钮点击监听器
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//单击按钮后短时间内显示消息提示框
Toast.makeText(MainActivity.this, "单击了按钮", Toast.LENGTH_SHORT).show();
}
});
}
|
- 在 Activity 中编写一个包含 View 类型参数的方法。
1 2 3 4
| public void myClick(View view){
//编写要执行的动作代码
Toast.makeText(MainActivity.this, "单击了按钮", Toast.LENGTH_SHORT).show();
}
|
- 将
android:onClick 属性指定为步骤(1)中的方法名。
1
| android:onClick = "myClick"
|
图片按钮
ImageButton 和 Button 的异同:
相同点:
- 单击时都可以触发 onClick 事件。即:使用它们两个都可以生成一个可供点击的按钮,且点击时都会触发 onClick 事件
不同点:
- ImageButton 没有
android:text 属性,而 Button 有。Button 上的文字是在代码中指定的,而 ImageButton 上的文字是在制作图片时加上去的
基本使用(属性)
android:src 设置按钮要显示的图片,属性值为图片资源。假设图片名称为 img 且在 mipmap 目录下:
1
| android:src = "@mipmap/img"
|
android:background 为图片按钮设置一个背景。为图片按钮设置透明背景:
1
| android:background = "#0000"
|
全屏显示
设置界面全屏显示:
1 2 3 4 5 6
| protected void onCreate(Bundle savedInstanceState) {
...
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
...
}
|
单选按钮
基本使用(属性)
android:text 给单选按钮旁设置说明性文字
android:checked 设置单选按钮为默认选中状态 属性值为 true,则表示为默认选中。
设置单选按钮组,并获取单选按钮组中选中项的值
如果我们需要 设置单选按钮组,我们需要使用 <RadioGroup></RadioGroup> 将单选按钮们包裹起来:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <RadioGroup
android:id="@+id/radio_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<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>
|
前提是 需要给RadioGroup设置一个id,然后在对应的 Activity 中编写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| RadioGroup radioGroup;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
//根据radioGroup ID绑定radioGroup
radioGroup = findViewById(R.id.radio_1);
//获取单选按钮内容
radioGroup.setOnCheckedChangeListener(new RadioGroup
.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
RadioButton radioButton = findViewById(checkedId);
CharSequence text = radioButton.getText();
Toast.makeText(MainActivity.this,"性别:"+text,
Toast.LENGTH_LONG).show();
}
});
}
|
添加其他按钮,并设置属性:
1 2 3 4 5 6
| <Button
android:id="@+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="提交"
/>
|
在对应的 Activity 中进行编写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| RadioGroup radioGroup;
protected void onCreate(Bundle savedInstanceState) {
...
radioGroup = findViewById(R.id.radio_1);
Button btn_1 = findViewById(R.id.btn_1);
btn_1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for (int i = 0;i <radioGroup.getChildCount();i++){
RadioButton r = (RadioButton) radioGroup.getChildAt(i);
if (r.isChecked()){ Toast.makeText(MainActivity.this,r.getText(),Toast.LENGTH_LONG).show();
//当已经找到选中的单选按钮后就跳出循环,提高程序效率
break;
}
}
}
});
}
|
复选框
使用(本身属性)
设置多个复选框只需要使用多个 <CheckBox /> 即可
android:text 给复选框旁设置说明性文字
android:checked 设置复选框为默认选中状态 属性值为 true,则表示为默认选中。
获取选中的复选框的值
首先需要给要获取值的复选框设置 id:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <CheckBox
android:id="@+id/box_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="唱"
/>
<CheckBox
android:id="@+id/box_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳"
/>
<CheckBox
android:id="@+id/box_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="rap"
/>
|
在对应的 Activity 中绑定点击响应:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| CheckBox checkBox_1;
protected void onCreate(Bundle savedInstanceState) {
...
//根据id绑定一个复选框 box_1
checkBox_1 = findViewById(R.id.box_1);
checkBox_1.setOnCheckedChangeListener(new CompoundButton.
OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (checkBox_1.isChecked()){
//当box_1被选中后,短暂弹出带有复选框值的提示框
Toast.makeText(MainActivity.this,checkBox_1.getText(),
Toast.LENGTH_SHORT).show();
}
}
});
}
|
日期选择器
常将日期选择器的长宽设置成根据父容器变化。
如果添加日期选择器后发现日期没有显示完全,应该进入对应的 Activity 中 修改继承的类。
将其修改为:Activity 而不是默认的 AppCompatActivity。
选择日期后,相应的给出我们选择的日期
1 2 3 4
| <DatePicker
android:id="@+id/datePicker_1"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
|
这里的 Activity 继承的是 Activity,而不是 AppCompatActivity。
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
| public class DatepickerActivity extends Activity {
int year, month, day;
DatePicker datePicker;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_datepicker);
datePicker = findViewById(R.id.datePicker_1);
Calendar calendar = Calendar.getInstance();
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
day = calendar.get(Calendar.DAY_OF_MONTH);
datePicker.init(year, month, day, new DatePicker.OnDateChangedListener() {
@Override
public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
DatepickerActivity.this.year = year;
DatepickerActivity.this.month = month;
DatepickerActivity.this.day = day;
show(year,monthOfYear, dayOfMonth);
}
});
}
private void show(int year, int month, int day) {
String str = year + "年" + (month + 1) + "月" + day + "日";
//选择日期后弹出显示日期的提示框
Toast.makeText(DatepickerActivity.this, str, Toast.LENGTH_SHORT).show();
}
}
|
时间选择器
常将日期选择器的长宽设置成根据父容器变化。
选择时间后,相应的给出我们选择的时间
1 2 3 4
| <TimePicker
android:id="@+id/timePicker_1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class TimepickerActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timepicker);
TimePicker timePicker = findViewById(R.id.timePicker_1);
//设置时间为24小时制
timePicker.setIs24HourView(true);
timePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
String str = hourOfDay + "时" + minute + "分";
//选择时间后弹出显示时间的提示框
Toast.makeText(TimepickerActivity.this, str, Toast.LENGTH_SHORT).show();
}
});
}
}
|
计时器
它是文本框组件的子类。
计时器默认的样式是 时:分:秒
如果我们想自定义时间格式,我们可以通过 android:format 属性进行设置。
%s 表示时:分:秒的计时器格式
1
| android:format = "已用时间:%s"
|
计时器所需要的方法
| 方法名 |
含义 |
setBase() |
设置计时器的起始时间 |
setFormat() |
设置显示时间的格式 |
start() |
指定开始计时 |
stop() |
指定停止时间 |
setOnChronometerTickListener() |
为计时器绑定事件监听器,当计时器改变时触发该监听器 |
编写一个计数器
1 2 3 4
| <Chronometer
android:id="@+id/chronometer_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class ChronometerActivity extends AppCompatActivity {
Chronometer chronometer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chronometer);
chronometer = findViewById(R.id.chronometer_1);
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.setFormat("%s");
chronometer.start();
chronometer.setOnChronometerTickListener(new Chronometer.
OnChronometerTickListener() {
@Override
public void onChronometerTick(Chronometer chronometer) {
//设置1分钟计时器
if (SystemClock.elapsedRealtime() - chronometer.getBase() >= 60000){
chronometer.stop();
}
}
});
}
}
|
高级 UI 组件
使用 UI 组件时注意字母的大小写!
使用 UI 组件时注意字母的大小写!
使用 UI 组件时注意字母的大小写!
进度条
安卓提供了两种进度条模式:水平进度条和圆形进度条。默认是圆形进度条。
属性
style 设置进度条的样式。
通过主题属性进行设置,如:
| 属性值 |
含义 |
| ?android:attr/progressBarStyleHorizontal |
细水平长条进度条 |
| ?android:attr/progressBarStyleSmall |
小圆形进度条 |
| ?android:attr/progressBarStyleLarge |
大圆形进度条 |
通过安卓给我定义的样式资源进行设置,如:
| 属性值 |
含义 |
| @android:style/Widget.ProgressBar.Horizontal |
粗水平长条进度条 |
| @android:style/Widget.ProgressBar.Large |
旋转画面的大圆形进度条 |
| @android:style/Widget.ProgressBar.Small |
旋转画面的小圆形进度条 |
android:max 设置进度条的最大值,属性值为具体数值,如:100
android:progress 设置进度条当前进度,属性值为具体数值,如:50
进度条更新流程:

模拟进度,实现进度条更新
1 2 3 4 5 6 7 8
| <ProgressBar
android:id="@+id/progressBar_1"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:layout_alignParentBottom="true"
android:layout_marginBottom="50dp"/>
|
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
| public class MainActivity extends AppCompatActivity {
private ProgressBar progressBar;
private int mProgress;
private Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = findViewById(R.id.progressBar_1);
mHandler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
if (msg.what == 0x111){ //耗时操作未完成
progressBar.setProgress(mProgress);
}else {
Toast.makeText(MainActivity.this, "耗时操作已完成!", Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE); //设置进度条消失
}
}
};
//模拟耗时操作
new Thread(new Runnable() {
@Override
public void run() {
while (true){
mProgress = doWork();
Message message = new Message();
if (mProgress < 100){
message.what = 0x111; //耗时操作未完成
mHandler.sendMessage(message);
}else {
message.what = 0x110; //耗时操作已完成
mHandler.sendMessage(message);
break;
}
}
}
//模拟进度条更新
private int doWork(){
mProgress += Math.random()*10;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
return mProgress;
}
}).start();
}
}
|
拖动条
它是进度条的子类。
属性
由于它是进度条的子类,因此它可以使用进度条 <ProgressBar /> 的属性,除此之外:
android:thumb 设置拖动条的拖动按钮的样式,属性值可以是我们自定义的图片资源,也可以是安卓给我们提供的值。
拖动拖动条按钮,界面内容实时改变
1 2 3 4 5 6
| <SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="10"
android:progress="5" />
|
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
| public class MainActivity extends AppCompatActivity {
SeekBar seekBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seekBar = findViewById(R.id.seekbar);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
//进度条改变时执行 progress:当前进度
@Override
public void onProgressChanged(SeekBar seekBar,
int progress, boolean fromUser) {
Toast.makeText(MainActivity.this, "进度改变:"+progress, Toast.LENGTH_SHORT).show();
}
//当我们触摸拖动条按钮时执行
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
Toast.makeText(MainActivity.this, "开始触摸", Toast.LENGTH_SHORT).show();
}
//当我们停止触摸拖动条按钮时执行
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
Toast.makeText(MainActivity.this, "停止触摸", Toast.LENGTH_SHORT).show();
}
});
}
}
|
拓展:设置图片透明度可用 setAlpha() 方法进行设置,参数为透明度。安卓中透明度最高为 255。
图像视图 参考下文。
星级评分条
属性
android:numStars 设置星级评分条中星级的个数。默认星级是 5。属性值为整型,如:8。
android:rating 设置点亮星级的个数。属性值为浮点型。
android:stepSize 设置每次评分的步长。属性值为浮点型。默认为 0.5。
android:isIndicator 设置 RatingBar 是否是一个指示器,即用户能否更改星级。默认为 false,表示用户可以更改。
获取用户的选中结果
1 2 3 4 5 6 7
| <RatingBar
android:id="@+id/ratingbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="7"
android:rating="2"
android:stepSize="1"/>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class MainActivity extends AppCompatActivity {
RatingBar ratingBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ratingBar = findViewById(R.id.ratingbar);
//获取星级评分(选中了几颗星)
String rating = String.valueOf(ratingBar.getRating());
Toast.makeText(MainActivity.this, "Rating:"+rating, Toast.LENGTH_SHORT).show();
//获取每次至少改变的星级
String stepSize = String.valueOf(ratingBar.getStepSize());
Toast.makeText(MainActivity.this, "stepSize:"+stepSize, Toast.LENGTH_SHORT).show();
//获取进度
String progress = String.valueOf(ratingBar.getProgress());
Toast.makeText(MainActivity.this, "progress:"+progress, Toast.LENGTH_SHORT).show();
}
}
|
图像视图
属性
android:src 设置 ImageView 的内容,属性值是图片的地址。如:其中 image1 是图片名称
1
| android:src="@drawable/image1
|
android:src和android:background的区别:
- background通常指的都是 背景,而src指的是 内容。
- 当使用 src 填入图片时,是按照图片大小 直接填充,并 不会进行拉伸;而使用background填入图片,则是会根据ImageView给定的宽度来进行 拉伸。
<ImageView />是正方形的。
android:layout_width和android:layout_height设置布局宽度和高度。同时可以改变内部图片的大小,而且是等比例缩放,图片不会存在拉伸的情况。
android:scaleType 控制图片如何resized/moved来匹对ImageView的size。属性值:
ImageView.ScaleType / android:scaleType值的意义区别,将属性值转换成下划线分割的大写单词即可。
参考链接:点击查看
| 属性值 |
含义 |
center |
按图片的原来size居中显示,当图片长/宽超过View的长/宽,则截取图片的居中部分显示 |
centerCrop |
按比例扩大图片的size居中显示,使得图片长(宽)等于或大于View的长(宽) |
centerInside |
将图片的内容完整居中显示,通过按比例缩小或原来的size使得图片长/宽等于或小于View的长/宽 |
fitCenter |
把图片按比例扩大/缩小到View的宽度,居中显示 |
fitEnd |
把图片按比例扩大/缩小到View的宽度,显示在View的下部分位置 |
fitStart |
把图片按比例扩大/缩小到View的宽度,显示在View的上部分位置 |
fitXY |
把图片不按比例扩大/缩小到View的大小显示 |
matrix |
用矩阵来绘制,动态缩小放大图片来显示。 |
android:adjustViewBounds 参考链接:参考链接1 参考链接2
官方表述:Adjust the ImageView’s bounds to preserve the aspect ration of its drawable. 解释:调整ImageView的界限来保持图片纵横比不变。
adjustViewBounds不管是设置成true还是false,都是不会影响图片本身的比例的(长/宽)!
实际上,adjustViewBounds影响的是ImageView的比例(不是图片的比例),所以,对于adjustViewBounds的定义应该是这样:
调整ImageView的边界,使得ImageView和图片有一样的长宽比例。
android:maxWidth/android:maxHeight 设置ImageView可以显示的最大宽/高,但是在Android中,只用当设置android:adjustViewBounds="ture"的时候,maxWidth/maxHeight 设置效果才能有效。
adjustViewBounds="ture"的时候,会将这个ImageView的android:scaleType属性设置为fitCenter,但是如果同时在 XML 文件中设置 android:scaleType,则 android:scaleType 的优先级会更高,adjustViewBounds="ture"中对 android:scaleType 属性设置将会失效。这种情况,只有在 Java 代码中设置 setAdjustViewBounds(true)的时候,才会生效。
android:tint 安卓着色器。将图片渲染成指定的颜色。
图像切换器
单击图片切换图片
1 2 3 4 5
| <ImageSwitcher
android:id="@+id/imageswitcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ImageSwitcher>
|
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
| public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageSwitcher imageSwitcher = findViewById(R.id.imageswitcher);
//设置图片切换淡出
imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(MainActivity.this,android.R.anim.fade_out));
//设置图片进入
imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(MainActivity.this,android.R.anim.fade_in));
//指定视图工厂
imageSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
@Override
public View makeView() {
ImageView imageView = new ImageView(MainActivity.this);
imageView.setImageResource(R.drawable.image1);
return imageView;
}
});
//指定新的图片显示资源(单击图片切换图片)
imageSwitcher.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((ImageSwitcher)v).setImageResource(R.drawable.image2);
}
});
}
}
|
实现左右滑动切换图片
1 2 3 4 5 6
| <ImageSwitcher
android:id="@+id/imageswitcher"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ImageSwitcher>
|
滑动动画文件,放置于 res/anim 目录下(anim 需要自己新建):
向左推进:push_left_in.xml
1 2 3 4 5 6 7
| <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%p" android:toXDelta="0"
android:duration="500" />
<alpha android:fromAlpha="0.1" android:toAlpha="1.0"
android:duration="500" />
</set>
|
向左推出:push_left_out.xml
1 2 3 4 5 6 7
| <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="-100%p"
android:duration="500" />
<alpha android:fromAlpha="1.0" android:toAlpha="0.1"
android:duration="500" />
</set>
|
向右推进:push_right_in.xml
1 2 3 4 5 6 7
| <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-100%p" android:toXDelta="0"
android:duration="500" />
<alpha android:fromAlpha="0.1" android:toAlpha="1.0"
android:duration="500" />
</set>
|
向右推出:push_right_out.xml
1 2 3 4 5 6 7
| <?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="100%p"
android:duration="500" />
<alpha android:fromAlpha="1.0" android:toAlpha="0.1"
android:duration="500" />
</set>
|
MainActivity.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 45 46 47 48 49
| public class MainActivity extends AppCompatActivity {
private int[] arrayPic = new int[]{R.drawable.image1,R.drawable.image2,
R.drawable.image3,R.drawable.image4};
private ImageSwitcher imageSwitcher;
private int index;
private float touchDownX;
private float touchUpX;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//设置全屏显示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
imageSwitcher = findViewById(R.id.imageswitcher);
imageSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
@Override
public View makeView() {
ImageView imageView = new ImageView(MainActivity.this);
imageView.setImageResource(arrayPic[index]);
return imageView;
}
});
//触摸图像切换器,实现图像的切换
imageSwitcher.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//判断是否为按下
if(event.getAction() == MotionEvent.ACTION_DOWN){
touchDownX = event.getX();
return true;
}else if (event.getAction() == MotionEvent.ACTION_UP){ //判断是否为抬起
touchUpX = event.getX();
if (touchUpX - touchDownX > 100){ //从左往右(向右推)
index = index == 0?arrayPic.length - 1 : index - 1;
imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.push_right_in)); imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.push_right_out));
imageSwitcher.setImageResource(arrayPic[index]);
}else if (touchDownX - touchUpX > 100){ //从右往左(向左推)
index = index == arrayPic.length - 1?0 : index + 1;
imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.push_left_in)); imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.push_left_out));
imageSwitcher.setImageResource(arrayPic[index]);
}
return true;
}
return false;
}
});
}
}
|
网格视图
可应用于相册。
属性
android:numColumns 设置网格布局的列数。属性值可以为整形,也可以是自动排列:auto_fit
android:verticalSpacing 设置垂直间距,单位 dp。
android:horizontalSpacing 设置水平间距,单位 dp。
android:stretchMode="columnWidth" 缩放与列宽大小同步
android:columnWidth 设置列宽度,单位 dp。
适配器
连接后端数据和前端显示的接口,是数据和 UI 组件的一个重要纽带。主要在 View 上显示(一般是 ListView)。可以看作是界面数据绑定的一种理解。它所操纵的数据一般都是一些比较复杂的数据,如数组,链表,数据库,集合等。适配器就像显示器,把复杂的东西按人可以接受的方式来展现。
使用者:ListView、GridView、Spinner、Gallery、ViewPage 等都需要使用适配器来为其设置数据源。
常用的适配器
建议花费一定量的时间学习适配器
ArrayAdapter,SimpleAdapter,SimpleCursorAdapter 这三个都是继承 BaseAdapter,BaseAdapter 是一个抽象类,需要子类继承并实现其中的方法才能使用,常用于用户自定义适配器时,显示比较复杂的数据。
ArrayAdapter 数组适配器是 Android 中最简单的适配器,专门用于显示列表控件,只能展示一行字。
SimpleAdapter 的扩展性最好,可以定义各种各样的布局,添加 ImageView、Button、CheckBox 等,可以自定义出各种效果。使用 SimpleAdapter 的数据用一般都是 HashMap 构成的 List,list 的每一节对应 ListView 的每一行。HashMap 的每个键值数据映射到布局文件中对应 id 的组件上。
SimpleCursorAdapter 可以认为是 SimpleAdapter 对数据库的简单结合,主要用来操作数据库。
BaseAdapter 一般用于显示复杂的列表布局,由于 BaseAdapter 是一个抽象类,使用该类需要自己写一个适配器继承于该类,并重新一些方法。
适配器继承图:

具体使用和参数意义参考下列链接。
参考链接: 参考链接1 参考链接2 参考链接3
实现网格视图
实现网格视图,使用 SimpleAdapter
准备工作:在 drawable 目录中放入 9 张图片,并命名为 image1 ~image9。
1 2 3 4 5
| <GridView
android:id="@+id/gridview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numColumns="3"/>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class MainActivity extends AppCompatActivity {
private int[] pic = new int[]{R.drawable.image1, R.drawable.image2,
R.drawable.image3, R.drawable.image4, R.drawable.image5,
R.drawable.image6, R.drawable.image7, R.drawable.image8,
R.drawable.image9};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView gridView = findViewById(R.id.gridview);
List<Map<String, Object>> listitem = new ArrayList<Map<String, Object>>();
for (int i = 0; i < pic.length; i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("image", pic[i]);
listitem.add(map);
}
SimpleAdapter simpleAdapter = new SimpleAdapter(this, listitem, R.layout.cell, new String[]{"image"}, new int[]{R.id.image});
gridView.setAdapter(simpleAdapter);
}
}
|
利用网格视图,实现相册界面,使用 BaseAdapter
准备工作:在 drawable 目录中放入 9 张图片,并命名为 image1 ~image9。
1 2 3 4 5 6 7 8
| <GridView
android:id="@+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="auto_fit"
android:verticalSpacing="5dp"
android:columnWidth="100dp"
android:gravity="center"/>
|
这里的 Activity 继承的是 Activity,而不是 AppCompatActivity。
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
| public class MainActivity extends Activity {
private int[] pic = new int[]{R.drawable.image1, R.drawable.image2,
R.drawable.image3, R.drawable.image4, R.drawable.image5,
R.drawable.image6, R.drawable.image7, R.drawable.image8,
R.drawable.image9};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView gridView = findViewById(R.id.gridview);
gridView.setAdapter(new ImageAdapter(this));
}
public class ImageAdapter extends BaseAdapter {
private Context context;
public ImageAdapter(Context context) {
this.context = context;
}
@Override
public int getCount() {return pic.length;}
@Override
public Object getItem(int position) {return null;}
@Override
public long getItemId(int position) {return 0;}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(context);
//设置图像宽高
imageView.setLayoutParams(new GridView.LayoutParams(100, 90));
//设置图片缩放方式(保持纵横比缩放)
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
} else {
imageView = (ImageView) convertView;
}
//将获取的图片放入imageView
imageView.setImageResource(pic[position]);
return imageView;
}
}
}
|
下拉列表框
属性
android:entries 为下拉列表框指定列表项,属性值为数组资源。
假设在 res/values 目录下创建了数组资源文件 arrays.xml:
1 2 3 4 5 6 7 8 9
| <?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="ctype">
<item>全部</item>
<item>电影</item>
<item>图书</item>
<item>游戏</item>
</string-array>
</resources>
|
则在布局文件中有:
1 2 3 4 5
| <Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:entries="@array/ctype">
</Spinner>
|
除了这种方式,我们还可以使用 适配器对下拉列表框的列表项进行设置。
使用适配器对下拉列表框的列表项进行设置,选择列表项后输出显示所选值
首先我们需要为 Spinner 设置一个 id,假设 id 设置为 spinner。
1 2 3 4 5
| <Spinner
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Spinner>
|
然后在 Activity 中进行编写:
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
| public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String []ctype = new String[]{"全部","音乐","游戏","编程"};
//创建数组适配器
ArrayAdapter<String > adapter = new ArrayAdapter<>(this,android.R.layout.simple_spinner_item,ctype);
//为列表框设置下拉样式
adapter.setDropDownViewResource(android.R.layout.
simple_spinner_dropdown_item);
//将适配器和下拉列表框关联起来
Spinner spinner = findViewById(R.id.spinner);
spinner.setAdapter(adapter);
//获取下拉列表框的选项值
/*String str = spinner.getSelectedItem().toString();
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();*/
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
//根据选中项获取其值
String result = parent.getItemAtPosition(position).toString();
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> parent) { }
});
}
}
|
列表视图
可应用于用户列表。
和下拉列表框一样,可以使用 android:entries 来给列表视图设置列表项。
具体步骤参考 下拉列表框 即可。
同样除了这种方式,我们还可以使用 适配器对列表视图的列表项进行设置。
使用适配器对列表视图的列表项进行设置,点击获得列表项的所选值
首先需要给 <ListView /> 设置一个 id。
1 2 3 4
| <ListView
android:id="@+id/listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] ctype = new String[]{"全部","音乐","游戏","编程"};
//设置适配器和viewlist的外观形式,可以有多种选择
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,ctype);
ListView listView = findViewById(R.id.listview);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String str = (String) parent.getItemAtPosition(position);
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
}
});
}
}
|
滚动视图
滚动视图可以在 xml 文件中添加,也可以在 java 文件中添加。
滚动视图默认是竖直的滚动,但我们也可以设置其他的滚动方式。
如果我们要设置水平方向的滚动,则需要使用 <HorizontalScrollView /> 标记。
在一个滚动视图中,只能放置一个组件,如果想要放置多个,我们需要使用布局管理器把这些组件括起来。
使用 xml 文件创建滚动视图
准备:创建一个字符串资源,在 res/values/strings.xml 中创建:
1 2 3 4 5
| <resources>
<string name="app_name">scrollview</string>
<string name="content"> 安卓是一种基于Linux内核(不包含GNU组件)的自由及开放源代码的操作系统。主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。Android操作系统最初由Andy Rubin开发,主要支持手机。2005年8月由Google收购注资。2007年11月,Google与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良Android系统。随后Google以Apache开源许可证的授权方式,发布了Android的源代码。
Android一词的本义指“机器人”,同时也是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成。</string>
</resources>
|
创建竖直的滚动视图:
1 2 3 4 5 6 7 8 9
| <ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/content"
android:textSize="30sp" />
</ScrollView>
|
创建水平的滚动视图:注意组件的长、宽设置
1 2 3 4 5 6 7 8 9
| <HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/content"
android:textSize="30sp" />
</HorizontalScrollView>
|
在滚动视图中创建多个组件:
1 2 3 4 5 6 7 8 9 10 11 12
| <ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--TextView中属性省略-->
<TextView />
<TextView />
</LinearLayout>
</ScrollView>
|
使用 java 文件创建滚动视图
步骤:
- 使用构造方法 ScrollView(Context c)创建一个滚动视图;
- 应用 addView()方法添加组件到滚动视图中;
- 将滚动视图添加到布局管理器中。
在这里我们回创建一个带有图片和文字的滚动视图,因此需要我们先准备好图片资源和字符串资源。
假设我们已准备好图片资源并命名为 image.jpg,同时我们需要把图片资源放置于 res/drawable 目录下。而我们使用的字符串资源就继续使用上文的 content 字符串资源。
根布局文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:paddingTop="16dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:orientation="vertical"
tools:context=".MainActivity">
</LinearLayout>
|
Activity 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取根布局管理器
LinearLayout ll = findViewById(R.id.ll);
//新建一个垂直的线性布局管理器
LinearLayout ll2 = new LinearLayout(MainActivity.this);
ll2.setOrientation(LinearLayout.VERTICAL);
//创建一个滚动视图对象
ScrollView scrollView = new ScrollView(MainActivity.this);
//将视图进行组合
ll.addView(scrollView);
scrollView.addView(ll2);
ImageView imageView = new ImageView(MainActivity.this);
imageView.setImageResource(R.drawable.image);
ll2.addView(imageView);
TextView textView = new TextView(MainActivity.this);
textView.setText(R.string.content);
ll2.addView(textView);
}
}
|
选项卡
我们不能使用某个具体的组件在 xml 文件添加选项卡。
使用步骤
- 在布局文件中添加
TabHost、TabWidget 和 TabContent 组件。TabHost 和 TabWidget 在布局文件中有具体的标记,而对于 TabContent 我们需要使用 FrameLayout 来实现。
- 编写各标签页的 XML 布局文件。(如果我们选项卡有几个标签页,就需要编写几个布局文件,布局文件的内容就是我们需要在选项卡中显示的内容)
- 获取并初始化
TabHost 组件。
- 为
TabHost 对象添加标签页。
具体实例
准备:我们在选项卡中实现两张图片的切换,因此我们需要两张图片。假设这两张图片命名为 image_left.jpg和image_right.jpg,并将它们放置在 res/drawable 目录下。
我们首先编写各标签页的XML布局文件: tab1.xml 和 tab2.xml
1 2 3 4 5 6 7 8 9 10 11
| <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/left"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/image_left"/>
</LinearLayout>
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/right"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/image_right"/>
</LinearLayout>
|
编写根布局文件:
注意:在根布局文件中,TabHost、TabWidget 和 FrameLayout 的 id 需要使用 Android 给我提供的,不能自己随意命名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TabWidget
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@android:id/tabs"></TabWidget>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
</TabHost>
|
在Activity文件中初始化TabHost组件,并为其添加标签页:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取TabHost对象
TabHost tabHost = findViewById(android.R.id.tabhost);
//对TabHost组件进行初始化
tabHost.setup();
//为TabHost添加标签页
//初始化LayoutInflater
LayoutInflater inflater = LayoutInflater.from(this);
inflater.inflate(R.layout.tab1,tabHost.getTabContentView());
inflater.inflate(R.layout.tab2,tabHost.getTabContentView());
//为TabHost设置标签页及文字内容
tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator("图片1").setContent(R.id.left));
tabHost.addTab(tabHost.newTabSpec("tab2").setIndicator("图片2").setContent(R.id.right));
}
}
|
Android 布局与组件完