invalidateOptionsMenu() not working when “restarting” activity

Refresh

November 2018

Views

680 time

2

I have an activity, let's call it FirstActivity.java, which has an actionBar with a navigation drawer instantiated via fragment. In this fragment, NavigationDrawerFragment.java, I've put the methods onCreateOptionsMenu(Menu menu, MenuInflater inflater), onOptionsItemSelected(MenuItem item) and onPrepareOptionsMenu(Menu menu) as anyone normally would in order to instantiate the actionBar. On the right side of the actionBar, I have a button with a "messages" icon that leads to the user's inbox fragment. When a new message incomes, I call invalidateOptionsMenu() inside my FirstActivity and change the icon to a brighter one in onPrepareOptionsMenu(Menu menu). Everything works fine so far.

The problem is: I can leave the FirstAcitivty via one of the options in the navigation drawer. I do it via Intent. Let's call it SecondActivity.java.

Intent myIntent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(myIntent);
finish();

When I call the FirstAcitivity again, also via Intent, the invalidateOptionsMenu() method stops working. It does not trigger the methods onCreateOptionsMenu nor onPrepareOptionsMenu. I have also tried supportInvalidateOptionsMenu() with no luck.

Only when I hit the MENU BUTTON (on the left side of the actionBar) is that these methods are called and the messages icon is changed. Does anyone know the reason for this strange behavior?

Better yet, does anyone know a solution for my problem? : )

FirstActivity.java

public class FirstActivity extends ActionBarActivity impements NavigationDrawerFragment.NavigationDrawerCallbacks {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first_activity);

//        When a new message arrives
        if (thereIsAnIncomingMessage) {
            invalidateOptionsMenu();
        }
    }
}

first_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" android:id="@+id/first_activity_layout">

    <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".FirstActivity">

        <!-- As the main content view, the view below consumes the entire
             space available using match_parent in both dimensions. -->
        <FrameLayout android:id="@+id/container" android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <!-- android:layout_gravity="start" tells DrawerLayout to treat
             this as a sliding drawer on the left side for left-to-right
             languages and on the right side for right-to-left languages.
             If you're not building against API 17 or higher, use
             android:layout_gravity="left" instead. -->
        <!-- The drawer is given a fixed width in dp and extends the full height of
             the container. -->
        <fragment android:id="@+id/navigation_drawer"
            android:layout_width="@dimen/navigation_drawer_width" android:layout_height="match_parent"
            android:layout_gravity="start"
            android:name="com.example.Controller.Main.NavigationBar.NavigationDrawerFragment"
            tools:layout="@layout/fragment_navigation_drawer" />

    </android.support.v4.widget.DrawerLayout>

</LinearLayout>

NavigationDrawerFragment.java

public class NavigationDrawerFragment extends Fragment {

    private RelativeLayout relativeLayout;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        relativeLayout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
        return relativeLayout;
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);

        menu.clear();
        inflater.inflate(R.menu.menu_main, menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.action_menu) {
//            Open navigation drawer menu
            return mDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
        } else if (item.getItemId == R.id.action_chat) {
//            Open messages fragment
            MessagesFragment messagesFragment = new MessagesFragment();
            FragmentManager fragmentManager = getFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

            fragmentTransaction.replace(R.id.container, messagesFragment, "MESSAGES_FRAGMENT");
            fragmentTransaction.addToBackStack("chatFrag");
            fragmentTransaction.commit();
        }
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);

        if (FirstActivity.thereIsAnIncomingMessage) {
            menu.getItem(0).setIcon(R.drawable.new_message_icon);
        } else {
            menu.getItem(0).setIcon(R.drawable.message_icon);
        }
    }

    public interface NavigationDrawerCallbacks {
        void onNavigationDrawerItemSelected(int position);
    }
}

1 answers

0

Проблема заключается в том, что OnCreateметод FirstActivityне вызывается , когда вы нажмете кнопку назад. Вместо этого, вы можете поместить свой код OnResumeследующим образом :

    @Override
    public void onResume(){
        super.onResume();
        if(thereIsAnIncomingMessage)
            invalidateOptionsMenu();
    }

См официальной деятельности Lifecycle документации.