一,在活动中使用 Toast
Toast 是 Android 系统提供的一种非常好的提醒方式,在程序中可以使用它将一些短小的信息通知给用户,这些信息会在一段时间后自动消失,并且不会占用任何屏幕空间。
使用Toast首先需要定义一个弹出 Toast 的触发点,先在活动对应的Layout的文件中设置一个按钮:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="?attr/actionBarSize"
android:text="Button_1"
/>
<!-- ?attr/actionBarSize 是系统定义的标准 ActionBar/Toolbar 高度。-->
<!-- 这样按钮就会从 Toolbar 之下开始显示,不会被遮挡。-->
<!--<Button
android:id="@+id/button_1" 为按钮定义一个唯一的ID,用于在代码中引用该按钮
android:layout_width="match_parent" 设置按钮的宽度以匹配父容器的宽度
android:layout_height="wrap_content" 设置按钮的高度以包裹其内容
android:text="Button_1" 设置按钮上显示的文本
/>-->
</LinearLayout>
然后在对应的Activity代码文件中 onCreate() 方法中添加如下代码:
package com.example.activitytest;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);//setContentView()方法给当前的活动加载一个布局; 设置当前页面的布局文件
Button button1 = findViewById(R.id.button_1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(FirstActivity.this, "You clicked Button 1", Toast.LENGTH_SHORT).show();
// Toast.makeText() 创建一个 Toast 提示;
//FirstActivity.this 指定上下文;
//"You clicked Button 1" 是提示内容;
//Toast.LENGTH_SHORT 表示提示持续时间较短;
//.show() 显示该提示。
}
//通过 findViewById() 获取布局中 id 为 button_1 的按钮组件;
//调用 setOnClickListener() 为该按钮设置点击监听器;
//在点击监听器中,通过 startActivity() 方法启动 SecondActivity;
});
}
}
在活动中,可以通过 findViewById() 方法获取到在布局文件中定义的元素,这里我们传入 R.id.button_1,来得到按钮的实例,这个值是刚才在 first_layout.xml 中通过 android:id 属性指定的。findViewById() 方法返回的是一个 View 对象,我们需要向下转型将它转换成 Button 对象。得到按钮的实例之后,我们通过调用 setOnClickListener() 方法为按钮注册一个监听器,点击按钮时就会执行监听器中的 onClick() 方法。因此,弹出 Toast 的功能当然是要在 onClick() 方法中编写了。
Toast 的用法非常简单,通过静态方法 makeText() 创建出一个 Toast 对象,然后调用 show() 将 Toast 显示出来就可以了。这里需要注意的是,makeText() 方法需要传入 3 个参数:
-
第一个参数是 Context,也就是 Toast 要求的上下文,由于活动本身就是一个 Context 对象,因此这里直接传入 FirstActivity.this 即可
-
第二个参数是 Toast 显示的文本内容
-
第三个参数是 Toast 显示的时长,有两个内置常量可以选择 Toast.LENGTH_SHORT 和 Toast.LENGTH_LONG
运行程序并点击按钮,在底部会出现短暂的弹窗提醒如图:
二,在活动中使用Menu
首先在 res 目录下新建一个 menu 文件夹,右击 res 目录-New一Directory,输入文件夹名 menu,点击 OK。接着在这个文件夹下再新建一个名叫 main 的菜单文件,右击 menu 文件夹一New一Menu resource file。
在main.xml中添加如下代码:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/add_item"
android:title="Add"
/>
<item
android:id="@+id/remove_item"
android:title="Remove"/>
</menu>
以上代码创建了菜单栏中的两个菜单选项,其中<item>标签是用来创建具体的菜单项,然后通过android:id为菜单项指定唯一标识符,通过android:title为菜单项指定一个名称。接着返回FirstActivity重写onCreateOptionsMenu方法(注重写的方法要和onCreate方法并齐,包含在FirstActivity类的大括号中):
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main,menu);
return true;
}
这里通过 getMenuInflater() 方法能够得到 MenuInflater 对象,再调用它的 inflate() 方法就可以给当前活动的建菜单了。inflate() 方法接收两个参数,第一个参数用于指定我们通过哪一个资源文件来创建菜单,这里当然传入 R.menu.main。第二个参数用于指定我们的菜单项将添加到哪一个 Menu 对象当中,这里直接使用 onCreateOptionsMenu() 方法中传入的 menu 参数。然后给这个方法返回 true,表示允许创建的菜单显示出来,如果返回了 false,创建的菜单将无法显示。
之后为显示出来的菜单定义菜单响应事件。在FirstActivity重写onOptionsItemSelected方法:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.add_item) {
Toast.makeText(this, "You clicked Add", Toast.LENGTH_SHORT).show();
// 处理 button_1 的点击事件
} else if (id == R.id.remove_item) {
Toast.makeText(this, "You clicked Remove", Toast.LENGTH_SHORT).show();
// 处理 button_2 的点击事件
}
return true;
}
注:此处不建议使用switch代码结构
在 onOptionsItemSelected()方法中,通过调用 item.getItemId()来判断我们点击的是哪一个菜单项,然后给每个菜单项加入自己的逻辑处理,这里是弹出一个Toast。
重新运行程序,你会发现在标题栏的右侧多了一个三点的符号,这个就是菜单按钮了。
可以看到,菜单里的菜单项默认是不会显示出来的,只有点击一下菜单按钮才会弹出里面具体的内容,因此它不会占用任何活动的空间。
如果你点击了 Add 菜单项底部就会弹出 You clicked Add 提示如果点击了 Remove 菜单项底部就会弹出 You clicked Remove 提示。
三,使用Intent在活动中进行跳转
Intent 是 Android 程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent 一般可被用于启动活动、启动服务以及发送广播等场景。Intent 大致可以分为两种:显式 Intent 和隐式 Intent。
显式 Intent 和隐式 Intent区别
在 Android 开发中,显式 Intent(Explicit Intent) 和 隐式 Intent(Implicit Intent) 是两种不同的组件启动方式,核心区别如下:
显式 Intent(Explicit Intent)
定义:直接指定目标组件的类名(如 Activity、Service),明确告诉系统要启动哪个组件。
使用场景:用于启动同一应用内的组件(已知具体目标)。
特点:
精确指定目标,安全性高。
不依赖系统匹配,直接执行。
隐式 Intent(Implicit Intent)
定义:通过声明 Action、Category、Data 等条件,由系统匹配符合条件的组件(可能来自其他应用)。
使用场景:跨应用交互(如打开网页、分享、调用相机等)。
特点:
灵活性高,允许多个应用响应同一 Intent。
需在 AndroidManifest.xml 中为目标组件配置 <intent-filter>。
总结:
使用显示Intent
在已有FirstActivity前提下新建一个SecondActivity,并勾选Generate Layout File,并给布局文件命名为second_layout,但不要勾选Launcher Activity选项。点击 Finish 完成创建,Android Studio 会为我们自动生成 SecondActivity.java 和 second_layout.xml 这两个文件。将自动生成的布局代码 替换为LinearLayout,编辑 second_layout.xml,将里面的代码替换成如下内容:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="?attr/actionBarSize"
android:text="Button2"
/>
<!-- ?attr/actionBarSize 是系统定义的标准 ActionBar/Toolbar 高度。-->
<!-- 这样按钮就会从 Toolbar 之下开始显示,不会被遮挡。-->
</LinearLayout>
将SecondActivity中OnCreate中代码替换为:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.secons_layout);
}
在FirstActivity对应的layout中的xml文件中添加一个按钮:
<Button
android:id="@+id/newActivity_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="NewActivityButton"
/>
在FirstActivity中设置一个按钮的点击事件:
Button button2 = findViewById(R.id.newActivity_button);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//显示Intent(意图)通常用于在应用程序内部调用已知的组件,隐示Intent通常用于在不同应用程序之间进行交互
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
}
});
这里构建出了一个 Intent,传入 FirstActivity.this 作为上下文,传入 SecondActivity.class 作为目标活动,这样我们的"意图"就非常明显了,即在 FirstActivity 这个活动的基础上打开 SecondActivity 这个活动。然后通过 startActivity()方法来执行这个 Intent。
运行程序:
点击NewActivityButton按钮会跳转:
点击
中的会返回上一活动。
使用隐式Intent
相比于显式 Intent,隐式 Intent 则含蓄了许多,它并不明确指出我们想要启动哪一个活动,而是指定了一系列更为抽象的 action 和 category 等信息,然后交由系统去分析这个 Intent,并帮我们找出合适的活动去启动。
什么叫作合适的活动呢?简单来说就是可以响应我们这个隐式 Intent 的活动,通过在<activity>标签下配置<intent-filter>的内容,可以指定当前活动能够响应的 action 和 category,打开 AndroidManifest.xml,在android:name=".SecondActivity"下添加如下代码:
<activity
android:name=".SecondActivity"
android:exported="true" >
<!-- android:exported="true" 表示该组件(如 Activity、Service 等)可以被其他应用访问。 若此标签用于 <activity> 或 <service>,则说明该组件对外暴露,可被外部应用启动或绑定。 -->
<intent-filter>
<action android:name="com.example.activity.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
在<action>标签中我们指明了当前活动可以响应 com.example.activitytest.ACTION_START 这个 action,而<category>标签则包含了一些附加信息,更精确地指明了当前的活动能够响应的 Intent 中还可能带有的 category。只有 <action> 和 <category> 中的内容同时能够匹配上 Intent 中指定的 action 和 category 时,这个活动才能响应该 Intent。
修改 FirstActivity 中按钮的点击事件,代码如下所示:
Button button2 = findViewById(R.id.newActivity_button);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//显示Intent(意图)通常用于在应用程序内部调用已知的组件,隐示Intent通常用于在不同应用程序之间进行交互
// Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
//startActivity(intent);
//当按钮被点击时,创建一个隐式意图(Intent)用于启动名为 SecondActivity 的新活动,并调用 startActivity(intent) 来实际启动该活动。
Intent intent = new Intent("com.example.activity.ACTION_START");
// intent.addCategory("com.example.activity.MY_CATEGORY");
startActivity(intent);
}
});
可以看到,我们使用了 Intent 的另一个构造函数,直接将 action 的字符串传了进去,表明我们想要启动能够响应 com.example.activitytest.ACTION_START 这个 action 的活动。 <action> 和 <category> 同时匹配上才能响应的,这里没有有指定 category 。这是因为 android.intent.category.DEFAULT 是一种默认的 category,在调用 startActivity() 方法的时候会自动将这个 category 添加到 Intent 中。
重新运行程序,在 FirstActivity 的界面点击一下按钮,你同样成功启动 SecondActivity 了。不同的是,这次你是使用了隐式 Intent 的方式来启动的,说明我们在 <activity> 标签下配置的 action 和 category 的内容已经生效了。
每个 Intent 中只能指定一个 action,但却能指定多个 category。目前我们的 Intent 中只有一个默认的 category,那么现在再来增加一个。
修改 FirstActivity 中按钮的点击事件,代码如下所示:
Button button2 = findViewById(R.id.newActivity_button);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//显示Intent(意图)通常用于在应用程序内部调用已知的组件,隐示Intent通常用于在不同应用程序之间进行交互
// Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
//startActivity(intent);
//当按钮被点击时,创建一个意图(Intent)用于启动名为 SecondActivity 的新活动,并调用 startActivity(intent) 来实际启动该活动。
Intent intent = new Intent("com.example.activity.ACTION_START");
intent.addCategory("com.example.activity.MY_CATEGORY");
startActivity(intent);
}
});
并在 AndroidManifest.xml,在android:name=".SecondActivity"下添加如下代码:
<activity
android:name=".SecondActivity"
android:exported="true" >
<!-- android:exported="true" 表示该组件(如 Activity、Service 等)可以被其他应用访问。 若此标签用于 <activity> 或 <service>,则说明该组件对外暴露,可被外部应用启动或绑定。 -->
<intent-filter>
<action android:name="com.example.activity.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.example.activity.MY_CATEGORY" />
</intent-filter>
</activity>
再次运行,发现可以正常运行,但是如果没有在 AndroidManifest.xml添加对应的
<category android:name="com.example.activity.MY_CATEGORY" />
的话,运行时会提示