目录
前言
由于篇幅过长,本文将分为两部分,该篇介绍的是基础内容,非初学者可跳过。
其他内容将在下一篇,初探 Acitivity 中讨论
简介
Activity 是一个应用程序组件,用户可与其提供的屏幕进行交互,以执行拨打电话、拍摄照片、发送电子邮件或查看地图等操作。 每个 Activity 都会获得一个用于绘制其用户界面的窗口。窗口通常会充满屏幕,但也可小于屏幕并浮动在其他窗口之上。
一个应用通常由多个彼此松散联系的 Activity 组成。 一般会指定应用中的某个 Activity 为 “主” Activity,即首次启动应用时呈现给用户的那个 Activity。 而且每个 Activity 均可启动另一个 Activity,以便执行不同的操作。
每次新 Activity 启动时,前一 Activity 便会停止,但系统会在堆栈(“返回栈”)中保留该 Activity。 当新 Activity 启动时,系统会将其推送到返回栈上,并取得用户焦点。 返回栈遵循基本的 “后进先出” 堆栈机制,因此,当用户完成当前 Activity 并按 “返回” 按钮时,系统会从堆栈中将其弹出(并销毁),然后恢复前一 Activity。
Activity 有助于完成系统和应用程序之间的以下重要交互:
- 追踪用户当前关心的内容(屏幕上显示的内容),以确保系统继续运行托管 Activity 的进程。
- 了解先前使用的进程包含用户可能返回的内容(已停止的 Activity),从而更优先保留这些进程。
- 帮助应用处理终止其进程的情况,以便用户可以返回已恢复其先前状态的 Activity。
- 提供一种途径,让应用实现彼此之间的用户流,并让系统协调这些用户流。(此处最经典的示例是共享。)
ps:在 Android Studio 创建一个 Activity 默认继承的是:AppCompatActivity。它是 Activity 的子类,为我们提供了一些新东西。
Activity基本用法
创建Activity
- 勾选 Generate Layout File 表示自动为该活动生成一个对应得布局文件
- 勾选 LauncherActivity 表示将自动为该活动设置为当前项目得主活动
创建及加载布局
若我们在上一步未勾选 Generate Layout File,则需要我们手动完成。
接着我们就可以通过 Text界面 或 Design界面 实现布局。
加载布局的方法也很简单
setContentView(R.layout.test);
AndroidManifest.xml注册
注意所有的四大组件,均需在 AndroidManifest.xml 中注册。当然智能的 Android Studio 已经帮我们完成了
销毁Activity
- 按下 Back
- 调用 finish()
Menu
在 res 目录下,新建一文件夹,取名为 menu
接着添加 menu 文件
main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/item1"
android:title="Item1"/>
<item
android:id="@+id/item2"
android:title="Item2"/>
</menu>
回到MainActivity 中重写 onCreateOptionsMenu()
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main,menu);
return super.onCreateOptionsMenu(menu);
}
通过 getMenuInflater()方法取得 MenuInflater 对象,再调用 inflate()方法为当前活动创建菜单
效果
仅仅显示菜单当花瓶是不够的,我们还需要给它添加一些功能
这里添加的功能是:Toast提示
当然更常见的功能是 跳转至另一Activity
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch(item.getItemId()){
case R.id.item1:
Toast.makeText(MainActivity.this,"I'm a item1.",Toast.LENGTH_SHORT).show();
break;
case R.id.item2:
Toast.makeText(MainActivity.this,"I'm a item2.",Toast.LENGTH_SHORT).show();
break;
}
return super.onOptionsItemSelected(item);
}
效果
启动另一个 Activity
显式启动
在上文 Menu示例 的基础上,我们修改 onOptionsItemSelected(),让它跳转到对应的Activity
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch(item.getItemId()){
case R.id.item1:
//Toast.makeText(MainActivity.this,"I'm a item1.",Toast.LENGTH_SHORT).show();
Intent intent1 = new Intent(this,Item1.class);
startActivity(intent1);
break;
case R.id.item2:
// Toast.makeText(MainActivity.this,"I'm a item2.",Toast.LENGTH_SHORT).show();
Intent intent2 = new Intent(this,Item2.class);
startActivity(intent2);
break;
}
return super.onOptionsItemSelected(item);
}
这里使用的是显式Intent
首先构造出一个Intent,上下文为 MainActivity.this,Itemx.class作为目标活动,这样意图已经很明显了。
接着通过 startActivity()来执行这个 Intent
效果
隐式启动
当然并不是所有意图都是这么明显的,有些意图则隐晦得多,例如这里介绍的 隐式启动
它不明确指明需要启动得 Activity,而是通过 action 和 category 指定
<activity android:name=".Item2">
<intent-filter>
<action android:name="start_item2"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
启动时只需要
Intent intent2 = new Intent("start_item2");
startActivity(intent2);
更多用法
启动网页
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
跳转至系统拨号界面
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("tel: 12530"));
startActivity(intent);
...
消息传递
向下一个 Activity 传递数据
使用 Intent 自带的 bundle 对象
我们在 MainActivity 中跳转至 Item1
String data = "Hello Item1_Activity";
Intent intent = new Intent(MainActivity.this,Item1.class);
intent.putExtra("data",data);
startActivity(intent);
在 Item1 中使用 getIntent()取得 Intent
Intent intent = getIntent();
String data = intent.getStringExtra("data");
Toast.makeText(this,data,Toast.LENGTH_LONG).show();
效果
上文演示的是简便的方法,使用 Intent 内部为我们准备好了一个 bundle
下面我们试着通过 bundle 对象来传递信息,bundle 维护了一个 HashMap<String, Object> 对象,将我们的数据存贮在这个 HashMap 中来进行传递。
创建 Bundle 对象来传递
MainActivity
Intent intent = new Intent(MainActivity.this,Item1.class);
Bundle bundle = new Bundle();
bundle.putString("user_data","Hi,Item1_Activity!");
intent.putExtra("data",bundle);
startActivity(intent);
Item1
Intent intent = getIntent();
Bundle bundle = intent.getBundleExtra("data");
String data = bundle.getString("user_data");
Toast.makeText(this,data,Toast.LENGTH_LONG).show();
返回数据给上一个 Activity
这里采用的方法是:启动带返回结果的 MainActivity
startActivityForResult(Intent intent, int requestCode)
MainActivity
Intent intent = new Intent(MainActivity.this,Item1.class);
//在Item1销毁之前会回调onActivityResult()
startActivityForResult(intent,1);
//...
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 1:
if (resultCode == RESULT_OK) {
String return_data = data.getStringExtra("data_return");
Toast.makeText(this, return_data, Toast.LENGTH_SHORT).show();
}
}
}
Item1
Intent intent = new Intent();
intent.putExtra("data_return","Hello");
setResult(RESULT_OK,intent);
finish();
效果