You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 使用androidx.widget.Toolbar实现选项菜单首次打开延迟如何解决

问题原因
  • 懒加载机制:Toolbar的弹出菜单默认采用懒加载逻辑,只有首次点击溢出按钮时,系统才会执行菜单布局解析、主题资源加载、动画配置初始化等操作,这些IO和渲染操作会造成数十到数百毫秒的延迟,低配置设备上延迟会更高。
  • 主题不匹配:你当前Toolbar使用的是ThemeOverlay.MaterialComponents.Dark.ActionBar主题,但弹出菜单的popupTheme指定的是 AppCompat 系列的ThemeOverlay.AppCompat.Light,两个主题体系不兼容,系统首次渲染菜单时需要做额外的适配转换,额外增加耗时。
  • 多余资源加载:你三个菜单项都配置了icon属性,首次加载时需要额外解析drawable资源,也会增加少量耗时,如果不需要显示菜单项图标可以去掉该属性。
  • 代码笔误:你onCreateOptionsMenu中加载的菜单是R.menu.menu,但你提供的菜单文件名为appbar_menu.xml,资源ID不匹配也可能导致首次加载时的资源查找耗时。
优化方案

1. 修正基础配置问题

首先把onCreateOptionsMenu中的菜单加载代码改为对应你的菜单文件名,同时补充Toolbar绑定逻辑:

package com.test.test_option_menu;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.Menu;
import android.view.MenuInflater;
import android.widget.PopupMenu;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

public class MainActivity extends AppCompatActivity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 绑定Toolbar到Activity
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        
        // 预加载菜单资源,主线程空闲时执行
        new Handler(Looper.getMainLooper()).post(() -> {
            PopupMenu dummyPopup = new PopupMenu(this, toolbar);
            dummyPopup.getMenuInflater().inflate(R.menu.appbar_menu, dummyPopup.getMenu());
        });
    }

    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        // 修正菜单资源ID
        inflater.inflate(R.menu.appbar_menu, menu);
        return true;
    }
}

上面的代码已经加入了预加载逻辑,会在主线程空闲时提前初始化PopupMenu实例,完成布局和资源的加载,首次点击时直接复用已经加载好的资源,延迟会大幅降低。

2. 统一主题配置

把Toolbar的popupTheme替换为和MaterialComponents配套的主题,避免主题适配耗时,修改activity_main.xml中的Toolbar配置:

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar"
    app:layout_constraintTop_toTopOf="parent"
    <!-- 修改为配套的MaterialComponents主题 -->
    app:popupTheme="@style/ThemeOverlay.MaterialComponents.Light"
    app:title="Quran"
    app:titleTextAppearance="@style/Toolbar.TitleText"
    app:titleTextColor="?attr/colorOnPrimary">
</androidx.appcompat.widget.Toolbar>

3. 自定义弹出动画时长(可选)

如果需要进一步加快弹出速度,可以自定义动画缩短时长:
首先在res/values/styles.xml中添加自定义弹出主题:

<style name="FastPopupOverlay" parent="ThemeOverlay.MaterialComponents.Light">
    <item name="android:popupAnimationStyle">@style/FastPopupAnim</item>
    <!-- 不需要动画的话可以直接设为@null,菜单会直接弹出 -->
    <!-- <item name="android:popupAnimationStyle">@null</item> -->
</style>

<style name="FastPopupAnim">
    <item name="android:windowEnterAnimation">@anim/fast_fade_in</item>
    <item name="android:windowExitAnimation">@anim/fast_fade_out</item>
</style>

新建res/anim/fast_fade_in.xml:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="60"
    android:fromAlpha="0"
    android:toAlpha="1" />

新建res/anim/fast_fade_out.xml:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="50"
    android:fromAlpha="1"
    android:toAlpha="0" />

最后把Toolbar的popupTheme修改为自定义主题即可:

app:popupTheme="@style/FastPopupOverlay"

内容的提问来源于stack exchange,提问作者Umar Alfaruq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 00:24:01