准备
IDE:
Android Studio 4.1.1
Build #AI-201.8743.12.41.6953283, built on November 5, 2020
Runtime version: 1.8.0_242-release-1644-b01 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0
Android Virtual Device:
Name: Pixel_2_API_28
CPU/ABI: Google Play Intel Atom (x86)
Path: C:\Users\86188\.android\avd\Pixel_2_API_28.avd
Target: google_apis_playstore [Google Play] (API level 28)
Skin: pixel_2
SD Card: 512M
fastboot.chosenSnapshotFile:
runtime.network.speed: full
hw.accelerometer: yes
hw.device.name: pixel_2
hw.lcd.width: 1080
hw.initialOrientation: Portrait
image.androidVersion.api: 28
tag.id: google_apis_playstore
hw.mainKeys: no
hw.camera.front: emulated
avd.ini.displayname: Pixel 2 API 28
hw.gpu.mode: auto
hw.ramSize: 1536
PlayStore.enabled: true
fastboot.forceColdBoot: no
hw.cpu.ncore: 4
hw.keyboard: yes
hw.sensors.proximity: yes
hw.dPad: no
hw.lcd.height: 1920
vm.heapSize: 256
skin.dynamic: yes
hw.device.manufacturer: Google
hw.gps: yes
hw.audioInput: yes
image.sysdir.1: system-images\android-28\google_apis_playstore\x86\
showDeviceFrame: yes
hw.camera.back: virtualscene
AvdId: Pixel_2_API_28
hw.lcd.density: 420
hw.arc: false
hw.device.hash2: MD5:55acbc835978f326788ed66a5cd4c9a7
fastboot.forceChosenSnapshotBoot: no
fastboot.forceFastBoot: yes
hw.trackBall: no
hw.battery: yes
hw.sdCard: yes
tag.display: Google Play
runtime.network.latency: none
disk.dataPartition.size: 6442450944
hw.sensors.orientation: yes
avd.ini.encoding: UTF-8
hw.gpu.enabled: yes
注意:以下示例仅在安卓虚拟设备上运行测试,并没有在真实的设备上运行测试。
项目
向 Activity 添加工具栏
-
新建项目,选择 Empty Activity,在配置项目时,我选择的
Minimum SDK
是API 16: Android 4.1 (Jelly Bean)
-
修改
src\main\AndroidManifest.xml
应用清单,使用NoActionBar
(第 11 行),既不使用原生的应用栏:<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mk"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.AppCompat.Light.NoActionBar"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
-
效果:
-
修改
src\main\res\layout\activity_main.xml
布局,删除原有TextView
元素,添加一个Toolbar
元素:<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:elevation="4dp" android:theme="@style/ThemeOverlay.AppCompat.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
-
在
MainActivity
的onCreate()
方法中,调用其setSupportActionBar()
方法,此方法会将工具栏设为 Activity 的应用栏(第 15 ~ 16 行):package com.mk; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); } }
-
您的应用现在有了一个基本操作栏:
添加和处理操作
应用栏中的空间有限。如果应用声明的操作数量过多,导致应用栏无法容纳,则应用栏会将无法容纳的操作发送到“溢出”菜单。应用还可以指定某项操作应始终显示在溢出菜单中,而不是显示在应用栏中。
添加操作按钮
操作溢出菜单中提供的所有操作按钮和其他项均在 XML 菜单资源中定义。若要向操作栏中添加操作,请在项目的 res/menu/
目录中创建新的 XML 文件。
-
新建
src\main\res\menu\items.xml
文件,为要添加到操作栏中的每项内容分别添加一个<item>
元素:<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_settings" android:title="设置" app:showAsAction="never"/> <item android:id="@+id/action_quit" android:title="退出" app:showAsAction="never"/> </menu>
app:showAsAction
属性用于指定操作是否应在应用栏中显示为按钮。如果您设置了app:showAsAction="ifRoom"
,那么只要应用栏中有足够的空间,此操作便会显示为按钮;如果空间不足,无法容纳的操作就会被发送到溢出菜单。如果您设置了 `app:showAsAction=“never”,此操作会始终列在溢出菜单中,而不会显示在应用栏中。 -
编辑
MainActivity
,重写onCreateOptionsMenu(Menu menu)
方法(第 14 ~ 19 行):package com.mk; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import android.os.Bundle; import android.view.Menu; import android.view.MenuInflater; public class MainActivity extends AppCompatActivity { // ... 其他,略 @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater menuInflater = getMenuInflater(); menuInflater.inflate(R.menu.items, menu); return true; } }
-
运行效果:
响应操作
当用户选择应用栏中的某个项时,系统会调用 Activity 的 onOptionsItemSelected()
回调方法,并传递 MenuItem
对象以指示用户点击的是哪个项。在您的 onOptionsItemSelected()
实现中,调用 MenuItem.getItemId()
方法可确定按下的是哪个项。返回的 ID 与您在相应 <item>
元素的 android:id
属性中声明的值相匹配。
-
编辑
MainActivity
,重写onOptionsItemSelected(@NonNull MenuItem item)
方法,当用户点击溢出菜单中的设置项之后,跳转到SettingsActivity
,如果无法识别用户的操作,则会调用父类方法:提示:此处
SettingsActivity
是一个EmptyActivity
。package com.mk; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import android.content.Intent; import android.os.Bundle; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.widget.Toast; public class MainActivity extends AppCompatActivity { // ... 其他,略 @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.action_settings: startActivity(new Intent(this, SettingsActivity.class)); return true; case R.id.action_quit: Toast.makeText(this, "Nothing happened.", Toast.LENGTH_SHORT).show(); return true; default: return super.onOptionsItemSelected(item); } } }
-
运行效果:
添加向上操作
应用应该让用户能够轻松地返回应用主屏幕。如需实现此目的,最简单的方法是针对除主 Activity 以外的所有 Activity 在应用栏中分别提供一个“向上”按钮。当用户选择“向上”按钮时,应用便会转到父 Activity。
声明父 Activity
如需在 Activity 中支持向上功能,您需要声明 Activity 的父级。为此,您可以在应用清单中设置 android:parentActivityName
属性。
android:parentActivityName
属性是在 Android 4.1(API 级别 16)中引入的。如需支持搭载旧版 Android 的设备,请定义一个 <meta-data>
名称值对,其中名称为 "android.support.PARENT_ACTIVITY"
,值为父 Activity 的名称。
例如,假设应用有一个名为 MainActivity
的主 Activity 和一个子 Activity。以下清单代码声明了这两个 Activity,并指定了父/子关系:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mk">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<activity android:name=".SettingsActivity" android:label="Settings" android:parentActivityName=".MainActivity">
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity" />
</activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
启用“向上”按钮
由于 SettingsActivity
并没有工具栏,所以在启用“向上”按钮之前,我们需要为其添加工具栏。
-
编辑
src\main\res\layout\activity_settings.xml
,添加一个Toolbar
元素:<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent" android:layout_height="match_parent" tools:context=".SettingsActivity"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorPrimary" android:minHeight="?attr/actionBarSize" android:theme="?attr/actionBarTheme" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
-
编辑
SettingsActivity
,为其添加工具栏(第 15 ~ 16 行),然后调用应用栏的setDisplayHomeAsUpEnabled()
方法(第 20 行):package com.mk; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import android.os.Bundle; public class SettingsActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_settings); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); // Get a support ActionBar corresponding to this toolbar, // and then enable the Up button getSupportActionBar().setDisplayHomeAsUpEnabled(true); } }
-
运行效果: