Android笔记3
条评论图像
图像视图ImageView
图像视图的图片通常位于res/drawable目录
- 在Layout文件中通过属性
android:src来指定图片资源,如android:src="@drawable/splash" - 在Activity文件中通过调用
setImageResource()方法指定图片资源,如setImageResource(R.drawable.splash)
ImageView本身默认图片居中显示,如果要改变图片显示方式,可以通过scaleType属性设置
- fitXY:拉伸填充满视图
- fitStart:保持比例,拉伸使其位于视图上方或左侧
- fitCenter:保持比例,拉伸居中
- fitEnd:保持比例,拉伸使其位于视图下方或右侧
- center:尺寸不变,居中
- centerCrop:拉伸充满视图,居中
- centerInside:保持比例,缩小图片位于视图中间
1 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
1 | public class ImageScaleActivity extends AppCompatActivity { |
图像按钮ImageButton
ImageButton是可以显示图片的按钮,它继承自ImageView,而非继承Button
ImageButton和Button之间的区别如下:
- Button既可以显示文本也可以显示图片,ImageButton只能显示图片不能显示文本;
- ImageButton上的图像可以按比例缩放,Button通过背景设置图像会拉伸变形;
- Button只能显示一张背景图,而ImageButton可以分别设置前景图和背景图,从而实现叠加效果。
在某些场景下,特殊字符或字体无法通过输入法输入,就需要先切图再放到ImageButton中
ImageButton和ImageView的区别如下:
- ImageButton有默认的按钮背景,ImageView默认无背景
- ImageButton默认的缩放类型是center,ImageView默认的缩放类型是fitCenter
文本与图像同时显示
同时展示文本与图像的方法有:
- 利用LinearLayout对ImageView和TextView组合布局
- 通过按钮控件Button的drawable**属性设置文本周围的图标
- drawableTop:指定文字上边的图片
- drawableBottom:指定文字下边的图片
- drawableLeft:指定文字左边的图片
- drawableRight:指定文字右边的图片
- drawablePadding:设置图片和文字的间距
简单计算器开发
布局
计算器界面分为两大部分:表达式显示部分、按键部分
控件
- LinearLayout:整体布局从上到下线性排列
- GridLayout:按键部分网格排列
- ScrollView:表达式区域如果超出屏幕就需要滚动
- TextView:计算结果用文本视图显示
- Button:数字和运算符按键
- ImageButton:开根运算符
Activity
启停活动页面
Activity的启动和结束
从当前页面调转到新的页面:
startActivity(new Intent(源页面.this, 目标页面.class));
从当前页面返回到上一个页面,相当于关闭当前页面:
finish()
\src\main\java\com\example\chapter04\ActStartActivity.java
1 | public class ActStartActivity extends AppCompatActivity { |
\src\main\java\com\example\chapter04\ActFinishActivity.java
1 | public class ActFinishActivity extends AppCompatActivity implements View.OnClickListener { |
Activity的生命周期
Activity的生命周期指的是Activity从被创建到被销毁之间的一系列状态、阶段。在不同的状态、阶段下适用于处理不同的事物。

| Activity生命周期 | 说明 |
|---|---|
| onCreate | 创建活动。页面被加载进内存,进入初始状态。 |
| onStart | 开始活动。页面展示在屏幕上,进入就绪状态。 |
| onResume | 恢复活动。页面进入活跃状态,可以触发各种交互事件,如允许点击、输入。 |
| onPause | 暂停活动。页面进入暂停状态,无法触发交互事件。 |
| onStop | 停止活动。页面进入停止状态,不在屏幕上显示。 |
| onDestroy | 销毁活动。回收活动占用的所有系统资源,页面从内存中销毁。 |
| onRestart | 重启活动。重新加载内存中的页面数据。 |
| onNewIntent | 重用已有的活动实例。 |
如果一个Activity已经启动过,并且存在于当前应用的Activity任务栈中,启动模式为
singleTask,singleInstance或singleTop(任务栈顶),那么在此启动回到这个Activity的时候,不会创建新的实例,也就是不执行onCreate()方法,而是执行onNewIntent()方法。
各状态之间的切换过程:
- 打开新页面的调用顺序为:
- onCreate:arrow_right:onStart:arrow_right:onResume
- 关闭页面的调用顺序为:
- onPause:arrow_right:onStop:arrow_right:onDestroy
Activity的启动模式
Activity活动存储在任务栈(TaskStack)中,打开一个页面时就意味着一个活动入栈了,关闭一个页面就意味着一个活动出栈了。
在配置文件中指定启动模式
1 | <activity |
默认启动模式standard
该模式下,启动的Activity会依照启动顺序一次压入Task栈中

栈顶复用模式singleTop
在该模式下,如果栈顶Activity为目标Activity,那么就不会重复创建新的Activity。

适合开启渠道多、多应用开启调用的Activity,通过这种设置可以避免已经创建过的Activity被重复创建,多数情况通过动态设置使用。
栈内复用模式singleTask
与singleTop模式相似,只不过singleTop模式是针对栈顶的活动,而singleTask模式下,如果task栈内存在目标Activity实例,则将task内的对应Activity实例之上的所有Activity弹出栈,并将对应Activity置于栈顶获得焦点。

全局唯一模式singleInstance
该模式下会为目标Activity创建一个新的Task栈,将目标Activity放入新的Task,并让目标Activity获得焦点。新的Task有且只有一个Activity实例。如果已经创建过目标Activity实例,则不会创建新的Task,而是将已创建的Activity唤醒。

动态设置启动模式
在两个活动之间频繁交替跳转
假设活动A与活动B之间页面切换非常频繁,那么在切换数次后,在Task栈中就会创建数个A和B,当需要退回到首页时,则需要将这数个A和B按顺序退出后才能到达首页。但实际需求是:A和B只应该各退出一次然后就回到首页,而不需要退出数次。
对于不允许重复返回的情况,可以设置启动标志
FLAG_ACTIVITY_CLEAR_TOP1
2
3
4
5//创建一个意图对象,准备跳转到指定活动页面
Intent intent = new Intent(this, JumpSecondActivity.class);
//栈中存在待跳转的活动实例时,则重新创建该活动实例,并清除原实例上方的所有实例
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);登录成功后不再返回登录页面
登录页面在用户成功登录后就会消失,然后进入首页,当点击返回按钮时并不会返回到登录页面而是直接退出APP。
对于只打开一次不再需要退回去的页面,可以设置启动标志
FLAG_ACTIVITY_CLEAR_TASK,该标志会清空当前活动栈内的所有实例。清空之后就意味着当前栈无法继续使用,必须重新创建活动栈,也就是同时设置启动标志FLAG_ACTIVITY_NEW_TASK,该标志用于开辟新任务的活动栈。1
2
3
4
5//创建一个意图对象,准备跳转到指定的活动页面
Intent intent = new Intent(this, LoginSuccessActivity.class);
//跳转到新页面时,清空栈中原有的所有实例,同时开辟新任务的活动栈
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
| 动态设置启动模式中的启动标志 | 说明 |
|---|---|
| Intent.FLAG_ACTIVITY_NEW_TASK | 开辟一个新的任务栈 |
| Intent.FLAG_ACTIVITY_SINGLE_TOP | 当栈顶为待跳转的活动实例时,则重用栈顶的实例 |
| Intent.FLAG_ACTIVITY_CLEAR_TOP | 当栈中存在待跳转的活动实例时,则重新创建一个实例,并清除原实例上方所有实例 |
| Intent.FLAG_ACTIVITY_NO_HISTORY | 栈中不保存新启动的活动实例 |
| Intent.FLAG_ACTIVITY_CLEAR_TASK | 跳转到新页面时,栈中原有的实例都将清空 |
在活动之间传递消息
显式Intent和隐式Intent
Intent是各个组件之间信息沟通的桥梁,它用于Android各组件之间的通信,主要完成下列工作:
- 标明本次通信请求来源、目标、属性。
- 发起方携带本次通信需要的数据内容,接收方从收到的意图中解析数据。
- 发起方若想判断接收方的处理结果,意图就要负责让接收方传回应答的数据内容。
Intent的组成部分:
| 名称 | 设置方法 | 说明与用途 |
|---|---|---|
| Component | setComponent | 组件,指定意图的来源与目标 |
| Action | setAction | 动作,指定意图的动作行为 |
| Data | setData | 即Uri,指定动作要操作的数据路径 |
| Category | addCategory | 类别,指定意图的操作类别 |
| Type | setType | 数据类型,指定消息的数据类型 |
| Extras | putExtras | 扩展信息,指定装载的包裹信息 |
| Flags | setFlags | 标志位,指定活动的启动标志 |
显式Intent
显式Intent直接指定来源活动与目标活动,属于精确匹配。有三种构建方式:
在Intent的构造函数中指定
1
Intent intent = new Intent(this, ActNextActivity.class)//创建一个目标确定的意图对象
调用意图对象的setClass方法指定
1
2Intent intent = new Intent();//创建一个意图对象
intent.setClass(this, ActNextActivity.class);//设置意图对象的源和目标调用意图对象的setComponent方法指定
1
2
3Intent intent = new Intent();//创建一个新的意图对象
ComponentName component = new ComponentName(this, ActNextActivity.class);//创建包含目标活动在内的组件名称对象
intent.setComponent(component);//设置意图对象携带的组件信息
隐式Intent
没有明确指定要跳转的目标活动,只给出一个动作字符串让系统自动匹配,属于模糊匹配。
通常App不希望向外部暴露活动名称,只给出一个事先定义好的标记串,通过标记串找到指定的活动,隐式Intent起到了标记过滤的作用。这个标记串可以是自定义的动作,也可以是系统动作。
| Intent类的系统动作常量名 | 系统动作的常量值 | 说明 |
|---|---|---|
| ACTION_MAIN | android.intent.action.MAIN | App启动时的入口 |
| ACTION_VIEW | android.intent.action.VIEW | 向用户显示数据 |
| ACTION_SEND | android.intent.action.SEND | 分享内容 |
| ACTION_CALL | android.intent.action.CALL | 直接拨号 |
| ACTION_DIAL | android.intent.action.DIAL | 准备拨号 |
| ACTION_SENDTO | android.intent.action.SENDTO | 发送短信 |
| ACTION_ANSWER | android.intent.action.ANSWER | 接听电话 |
动作名称既可以通过setAction方法指定,也可以通过构造函数Intent(String action)直接生成意图对象。由于动作是模糊匹配,因此有时需要更详细的路径。Uri和Category便是这样的路径与门类信息,Uri数据可通过构造函数Intent(String action, Uri uri)在生成对象时一起指定,也可以通过setData方法指定;Category可通过addCategory方法指定,之所以用add而不用set方法,是因为一个意图允许设置多个Category,方便一起过滤。
1 | public class ActionUriActivity extends AppCompatActivity implements View.OnClickListener { |
向下一个Activity发送数据
Intent使用Bundle对象存放待传递的数据信息。
Bundle对象操作各类型数据的读写方法如下表:
| 数据类型 | 读方法 | 写方法 |
|---|---|---|
| 整型 | getInt | putInt |
| 单精度浮点型 | getFloat | putFloat |
| 双精度浮点型 | getDouble | putDouble |
| 布尔型 | getBoolean | putBoolean |
| 字符串 | getString | putString |
| 字符串数组 | getStringArray | putStringArray |
| 字符串列表 | getStringArrayList | putStringArrayList |
| 可序列化结构 | getSerializable | putSerializable |
ActSendActivity.java
1 | public class ActSendActivity extends AppCompatActivity { |
ActReceiveActivity.java
1 | public class ActReceiveActivity extends AppCompatActivity { |
- 在代码中发送消息包裹,调用意图对象的putExtras方法,即可存入消息包裹。
- 在代码中接收消息包裹,调用意图对象的getExtras方法,即可取出消息包裹。
向上一个Activity发送数据
处理下一个页面的应答数据,详细步骤说明如下:
- 上一个页面打包好请求数据,调用startActvityForResult方法执行跳转动作
- 下一个页面接收并解析请求数据,进行相应处理
- 下一个页面在放回上一个页面时,打包应答数据并调用setResult方法返回数据包裹
- 上一个页面重写方法onActivityResult,解析获得下一个页面的返回数据
