记一次Toolbar和Menu配合使用的坑

记一次Toolbar和Menu配合使用的坑

在重构app页面中一些布局的时候,想着统一使用AppbarLayout和Toolbar作为标题栏来控制Activity的返回,但是其中有些Activity中是有使用Menu的,所以我试着在Toolbar中添加Menu,还真有一个属性可以设置Menu,想着这么方便就直接加上了

xml 复制代码
<com.google.android.material.appbar.AppBarLayout
        android:layout_height="60dp"
        android:layout_width="match_parent"
        android:theme="@style/Theme.Talk.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/moment_list_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            android:background="@color/teal_700"
            app:title="@string/moment"                             
            app:menu="@menu/moment"
            app:navigationIcon="@drawable/back"
            android:textAlignment="center"
            app:popupTheme="@style/Theme.Talk.PopupOverlay" />

    </com.google.android.material.appbar.AppBarLayout>

上述代码中,我直接在Toolbar中添加了menu

如上图所示,是起了作用的

java 复制代码
//点击返回按钮
        activityMomentListBinding.momentListToolbar.setNavigationOnClickListener(v -> finish());

左侧返回Icon也是生效的,点击事件也是无问题,但是一点击Menu,问题就来了

java 复制代码
//选择图片新增朋友圈
        activityMomentListBinding.momentListToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @SuppressLint("NonConstantResourceId")
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                if (item.getItemId() == R.id.moment_menu_item){
                    imageChooseLauncher.launch(new PickVisualMediaRequest.Builder()
                            .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE)
                            .build());
                }
                return true;
            }
        });
问题:

使用Toolbar自带的menu点击监听设置方法设置了监听,但是死活没去选择图片(代码中的逻辑),debug方法也是执行了,但是item.getItemId()与menu文件中的itemId不对。

What??? 怎么会呢?找资料找到怀疑人生,看到大家基本都是使用

java 复制代码
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    //在这里处理点击事件
    return super.onOptionsItemSelected(item);
}

这两个方法去处理menu的点击,我想着Toolbar不是都自带嘛,又可以设置menu,还可以设置监听,如果用回这个,我感觉用toolbar设置menu就有点多余了,所以我慢慢尝试,最后发现,我想达到的效果应该这样使用

解决方法:

在layout中设置toolbar,并设置menu

xml 复制代码
<com.google.android.material.appbar.AppBarLayout
        android:layout_height="60dp"
        android:layout_width="match_parent"
        android:theme="@style/Theme.Talk.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/moment_list_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            android:background="@color/teal_700"
            app:title="@string/moment"                             
            app:menu="@menu/moment"
            app:navigationIcon="@drawable/back"
            android:textAlignment="center"
            app:popupTheme="@style/Theme.Talk.PopupOverlay" />

</com.google.android.material.appbar.AppBarLayout>

在onCreate中添加

java 复制代码
setSupportActionBar(activityMomentListBinding.momentListToolbar);

然后重写onCreateOptionsMenu(Menu menu)方法

java 复制代码
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.moment_menu,menu);
    return super.onCreateOptionsMenu(menu);
}

再设置Toolbar的menu点击监听就可以了

java 复制代码
activityMomentListBinding.momentListToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @SuppressLint("NonConstantResourceId")
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                if (item.getItemId() == R.id.moment_menu_item){
                    imageChooseLauncher.launch(new PickVisualMediaRequest.Builder()
                            .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE)
                            .build());
                }
                return true;
            }
        });
原因:

我暂时没去深究,按照逻辑个人猜测应该是需要使用setSupportActionBar()设置Toolbar为ActionBar,然后再加载menu文件到上下文中,这样子Activity和Toolbar所使用的menu是同一个,点击事件下发处理时才会是相同的,如果就单纯在xml中设置menu,可能是加载menu文件然后新new了一个menu文件,所以menuItem的id才会对不上,也不知道这么理解对不对。

相关推荐
古法安卓29 分钟前
Android-SELinux 策略调试实战:从 AVC 日志到策略修复
android·java·android studio
Dovis(誓平步青云)1 小时前
DevEco Studio 6.1.1 Windows 安装实录:从下载校验到首次启动
android·开发语言·数据库·人工智能·windows·harmonyos
Zender Han1 小时前
Flutter 自适应(Adaptive)与响应式(Responsive)设计实践:官方推荐方案详解
android·flutter·ios
我命由我123452 小时前
Android 开发问题:TopAppBar 和 topAppBarColors API is experimental...
android·java·java-ee·kotlin·android studio·android jetpack·android-studio
造火箭2 小时前
Android UI自动化测试可行性评估SKILL
android·功能测试·ui
hunterandroid4 小时前
[Android 从零到一] ViewPager2 与 Fragment 生命周期协同:从预加载到状态一致性
android·前端
mmsx4 小时前
一个黑边 Bug 修了两版:自己算矩阵直接黑屏,借库重建只用了一行 setZoom
android·前端
枢影Kernel5 小时前
Android CLI 与 Android Skills 最佳实践:把 AI Agent 接入可验证的 Android 开发流程
android
Kapaseker5 小时前
没想到吧!Skill 也可以测试 — 小白都看得懂的 Skill 教程
android·人工智能·kotlin
我命由我123455 小时前
Android 开发问题:使用 AndroidTreeView 时,自定义视图无法撑满父容器
android·java·java-ee·kotlin·android studio·android-studio·android runtime