【问题标题】:invalidateOptionsMenu() not working when "restarting" activity“重新启动”活动时 invalidateOptionsMenu() 不起作用
【发布时间】:2015-12-04 13:39:01
【问题描述】:

我有一个活动,我们称之为FirstActivity.java,它有一个带有通过片段实例化的导航抽屉的actionBar。在这个片段 NavigationDrawerFragment.java 中,我放置了方法 onCreateOptionsMenu(Menu menu, MenuInflater inflater)onOptionsItemSelected(MenuItem item)onPrepareOptionsMenu(Menu menu) 就像任何人通常会为了实例化 actionBar 一样。在 actionBar 的右侧,我有一个带有“消息”图标的按钮,该按钮指向用户的收件箱片段。当收到一条新消息时,我在 FirstActivity 中调用 invalidateOptionsMenu() 并在 onPrepareOptionsMenu(Menu menu) 中将图标更改为更亮的图标。到目前为止一切正常。

问题是:我可以通过导航抽屉中的一个选项离开 FirstAcitivty。我通过 Intent 来实现。我们称之为 SecondActivity.java

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

当我再次通过 Intent 调用 FirstAcitivity 时,invalidateOptionsMenu() 方法停止工作。它不会触发 onCreateOptionsMenuonPrepareOptionsMenu 方法。我也试过 supportInvalidateOptionsMenu() 没有运气。

只有当我点击菜单按钮(在操作栏的左侧)时,才会调用这些方法并更改消息图标。有谁知道这种奇怪行为的原因?

更好的是,有人知道我的问题的解决方案吗? :)

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);
    }
}

【问题讨论】:

  • 我认为也许 invalidateOptionsMenu() 触发了“旧”onPrepareOptionsMenu,但片段返回堆栈条目计数始终为 0(零)。还在调查中……

标签: java android android-fragments android-activity android-actionbar


【解决方案1】:

问题是当你点击返回按钮时,FirstActivityOnCreate 方法没有被调用。相反,你可以把你的代码放在OnResume,如下:

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

查看官方Activity Lifecycle 文档。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2022-08-04
    • 2020-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多