Android 工具栏会在应用程序关闭并重新打开时删除所有菜单项
Android Toolbar removes all menu items when app is closed and reopened
我的目标是当应用程序关闭并重新打开(Activity 销毁和创建)时,工具栏中的菜单项仍然存在于该工具栏中。当应用程序关闭并重新打开时,菜单项当前会被删除。有 0 个项目,我无法访问工具栏中的项目;如果我尝试我会收到以下错误:java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
问题似乎是当应用程序重新启动时没有调用 onCreateOptionsMenu()。
这是带有工具栏的 xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:id="@+id/coordinatorLayoutActivityMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ActivityMain">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
这是我在 onResume()
中设置工具栏的方法:
private void setUpActionBar() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitleTextColor(getResources().getColor(R.color.colorOnPrimary));
Drawable overflowIcon = toolbar.getOverflowIcon();
if (overflowIcon != null) {
overflowIcon.setColorFilter(getResources().getColor(R.color.colorOnPrimary), PorterDuff.Mode.SRC_ATOP);
}
setSupportActionBar(toolbar);
}
});
}
和onCreateOptionsMenu()
:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_toolbar, menu);
return true;
}
这会在应用程序首次打开时正确填充工具栏。
我的目标是在 content_main 中托管的片段创建视图时能够 运行 以下代码而无需 IndexOutOfBoundsException
:
Toolbar toolbar = ((ActivityMain) getActivity()).findViewById(R.id.toolbar);
Menu menu = toolbar.getMenu();
menu.getItem(ActivityMain.MENU_ACTION_ADD).setVisible(true);
如何做到这一点?
问题是 onCreateOptionsMenu()
在创建片段视图之前不会被调用。
这意味着您需要在创建视图时使用 Fragment 设置 BroadcastReceiver,并在 onCreateOptionsMenu()
结束时通过 Intent 发送匹配的广播。
这是一个例子。
首先在onViewCreated()
中设置BroadcastReceiver。感谢 CommonsWare 让我知道竞争条件。谢谢!
private void setUpBroadcastReceiverServiceOnOptionsMenuCreated() {
ActivityMain activityMain = ((ActivityMain) getActivity());
IntentFilter filterComplete = new IntentFilter();
filterComplete.addCategory(Intent.CATEGORY_DEFAULT);
filterComplete.addAction(activityMain.getResources().getString(
R.string.broadcast_receiver_on_create_options_menu));
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Toolbar toolbar = activityMain.findViewById(R.id.toolbar);
// Menu items have been added!!!
Menu menu = toolbar.getMenu();
menu.getItem(ActivityMain.MENU_ACTION_ADD).setVisible(true);
}
};
activityMain.registerReceiver(broadcastReceiver, filterComplete);
}
创建发送广播的方法:
private void sendBroadcastOnOptionsMenuCreated() {
Intent intent = new Intent();
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setAction(getResources().getString(
R.string.broadcast_receiver_on_create_options_menu));
sendBroadcast(intent);
}
最后,在创建菜单时发送广播。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_toolbar, menu);
sendBroadcastOnOptionsMenuCreated();
return true;
}
我的目标是当应用程序关闭并重新打开(Activity 销毁和创建)时,工具栏中的菜单项仍然存在于该工具栏中。当应用程序关闭并重新打开时,菜单项当前会被删除。有 0 个项目,我无法访问工具栏中的项目;如果我尝试我会收到以下错误:java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
问题似乎是当应用程序重新启动时没有调用 onCreateOptionsMenu()。
这是带有工具栏的 xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:id="@+id/coordinatorLayoutActivityMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ActivityMain">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
这是我在 onResume()
中设置工具栏的方法:
private void setUpActionBar() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitleTextColor(getResources().getColor(R.color.colorOnPrimary));
Drawable overflowIcon = toolbar.getOverflowIcon();
if (overflowIcon != null) {
overflowIcon.setColorFilter(getResources().getColor(R.color.colorOnPrimary), PorterDuff.Mode.SRC_ATOP);
}
setSupportActionBar(toolbar);
}
});
}
和onCreateOptionsMenu()
:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_toolbar, menu);
return true;
}
这会在应用程序首次打开时正确填充工具栏。
我的目标是在 content_main 中托管的片段创建视图时能够 运行 以下代码而无需 IndexOutOfBoundsException
:
Toolbar toolbar = ((ActivityMain) getActivity()).findViewById(R.id.toolbar);
Menu menu = toolbar.getMenu();
menu.getItem(ActivityMain.MENU_ACTION_ADD).setVisible(true);
如何做到这一点?
问题是 onCreateOptionsMenu()
在创建片段视图之前不会被调用。
这意味着您需要在创建视图时使用 Fragment 设置 BroadcastReceiver,并在 onCreateOptionsMenu()
结束时通过 Intent 发送匹配的广播。
这是一个例子。
首先在onViewCreated()
中设置BroadcastReceiver。感谢 CommonsWare 让我知道竞争条件。谢谢!
private void setUpBroadcastReceiverServiceOnOptionsMenuCreated() {
ActivityMain activityMain = ((ActivityMain) getActivity());
IntentFilter filterComplete = new IntentFilter();
filterComplete.addCategory(Intent.CATEGORY_DEFAULT);
filterComplete.addAction(activityMain.getResources().getString(
R.string.broadcast_receiver_on_create_options_menu));
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Toolbar toolbar = activityMain.findViewById(R.id.toolbar);
// Menu items have been added!!!
Menu menu = toolbar.getMenu();
menu.getItem(ActivityMain.MENU_ACTION_ADD).setVisible(true);
}
};
activityMain.registerReceiver(broadcastReceiver, filterComplete);
}
创建发送广播的方法:
private void sendBroadcastOnOptionsMenuCreated() {
Intent intent = new Intent();
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setAction(getResources().getString(
R.string.broadcast_receiver_on_create_options_menu));
sendBroadcast(intent);
}
最后,在创建菜单时发送广播。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_toolbar, menu);
sendBroadcastOnOptionsMenuCreated();
return true;
}