I am using a collapsingToolbarLayout in my application and as long as the menu is not collapsed there is no problem when rotating the phone. But when the menu is collapsed and only the original toolbar is showing the app crashes. The thing is, when only the original toolbar is showing a clickable item appears and disappears when the collapsing toolbar is shown. When rotating the phone, the application does not find this item. How can I solve this?
The activity where the menu is.
private Menu menu;
protected void onCreate(Bundle savedInstanceState) {
...
AppBarLayout mAppBarLayout = findViewById(R.id.appBarLayout2);
mAppBarLayout.addOnOffsetChangedListener(new
AppBarLayout.OnOffsetChangedListener() {
int scrollRange = -1;
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int
verticalOffset) {
if (scrollRange == -1) {
scrollRange = appBarLayout.getTotalScrollRange();
}
if (scrollRange + verticalOffset == 0) {
isShow = true;
showOption();
} else if (isShow) {
isShow = false;
hideOption();
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
this.menu = menu;
getMenuInflater().inflate(R.menu.menu_scrolling, menu);
hideOption();
return true;
}
private void hideOption() {
MenuItem item = menu.findItem(R.id.action_info);
item.setVisible(false);
}
private void showOption() {
MenuItem item = menu.findItem(R.id.action_info);
item.setVisible(true);
}
The relevant code in xml-file:
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout2"
android:layout_width="match_parent"
android:layout_height="128dp"
android:theme="@style/AppTheme.Base"
app:layout_constraintTop_toTopOf="@+id/nestedScrollView">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsTool"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorSecondary"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="bottom|center"
app:expandedTitleMargin="16dp"
app:expandedTitleTextAppearance="@style/TextAppearance.AppCompat.Display2"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:title="@string/title_expenses">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:navigationIcon="@drawable/ic_action_exit"
app:title="@string/title_expenses"
app:titleTextColor="@android:color/background_light" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
The menu_Scrolling.xml
<menu 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"
tools:context="com.journaldev.collapsingtoolbarlayout.ScrollingActivity">
<item
android:id="@+id/action_info"
android:icon="@drawable/ic_action_add"
android:orderInCategory="200"
android:title="Add"
app:showAsAction="ifRoom" />
</menu>
This is the error message:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.korneliapalm.android.samboappen/com.korneliapalm.android.samboappen.MoneyListActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'android.view.MenuItem android.view.Menu.findItem(int)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3114)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257)
at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5039)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4948)
at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'android.view.MenuItem android.view.Menu.findItem(int)' on a null object reference
at com.korneliapalm.android.samboappen.MoneyListActivity.showOption(MoneyListActivity.java:163)
at com.korneliapalm.android.samboappen.MoneyListActivity.onCreate(MoneyListActivity.java:51)
at android.app.Activity.performCreate(Activity.java:7327)
at android.app.Activity.performCreate(Activity.java:7318)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3094)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257)
at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5039)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4948)
at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
The problem is that in onCreate
you are calling the methods hideOption()
and showOption()
.
However, oncreate is called before onCreateOptionsMenu
which is where you are inflating the menu view. So calling menu.findItem(R.id.action_info);
triggers a null pointer.
getMenuInflater().inflate(R.menu.menu_scrolling, menu);
You need to ensure that the menu view is inflated before you call these two methods in onCreate.
private void hideOption() {
if (menu == null) return;
MenuItem item = menu.findItem(R.id.action_info);
item.setVisible(false);
}
private void showOption() {
if (menu == null) return;
MenuItem item = menu.findItem(R.id.action_info);
item.setVisible(true);
}