Android NavigationView片段状态

时间:2015-06-12 23:00:18

标签: android android-fragments navigationview

我正在使用新的NavigationView以显示带有Android设计支持库的导航菜单。我还在DrawerLayout中使用FrameLayout将片段替换为它。

当我在片段之间切换时会出现问题。我的意思是,当我使用NavigationView单击另一个片段并再次返回到第一个片段时,视图已被“清理”(例如,来自ViewPagers选项卡的内容刚刚消失)。我不知道如何“刷新”FrameLayout,或者我是否必须重用Fragments而不是使用 transaction.replace()

<android.support.v4.widget.DrawerLayout 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/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <FrameLayout
            android:id="@+id/content_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="?attr/actionBarSize" />
        <include layout="@layout/toolbar" />
    </RelativeLayout>
    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/menu_drawer" />
</android.support.v4.widget.DrawerLayout>

我也使用这种方法将片段切换到FrameLayout。

private void displayFragment(int position) {
    Fragment fragment = null;
    String title = "";

    switch (position) {
        case 0:
            fragment = new FragmentA();
            title = getString(R.string.fragment_a);
            break;
        case 1:
            fragment = new FragmentB();
            title = getString(R.string.fragment_b);
            break;
        case 2:
            fragment = new FragmentC();
            title = getString(R.string.fragment_c);
            break;

        default:
            fragment = new HomeFragment();
            title = getString(R.string.app_name);
            break;
    }

    if (fragment != null) {
        fragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(R.id.content_frame, fragment);
        transaction.commit();

        drawerLayout.closeDrawers();
        setTitle(title);
    } else {
        Log.w(TAG, "Error creating fragment");
    }
}

谢谢!

5 个答案:

答案 0 :(得分:0)

更换片段时可能需要尝试这个..

transaction.replace(R.id.content_frame, fragment).addToBackStack("Any_String");

答案 1 :(得分:0)

试试这个

     NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
            if (navigationView != null) {
                setupDrawerContent(navigationView);
            }


     private void setupDrawerContent(NavigationView navigationView) {
            navigationView.setNavigationItemSelectedListener(
                    new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(MenuItem menuItem) {
                    Fragment fragment = null;
                    switch (menuItem.getItemId()) {
                        case R.id.nav_home:
                            Log.i("TAG","HOME");
                            fragment = new CheeseListFragment();
                            break;
                        case R.id.nav_messages:
                            fragment = new MessageFragment();
                            break;
                        case R.id.nav_friends:
                            fragment = new FriendsFragment();
                            break;
                        case R.id.nav_discussion:
                             fragment = new DiscussionFragment();
                            break;

                    }

                    if (fragment != null) {
                        FragmentManager fragmentManager = getSupportFragmentManager();
                        fragmentManager.beginTransaction()
                                .replace(R.id.container, fragment).commit();

                    }
                        menuItem.setChecked(true);
                        mDrawerLayout.closeDrawers();
                        return true;

                }
            });
}

您可以通过这种方式打开片段,检查在切换案例中选择了哪个菜单并相应地打开片段

答案 2 :(得分:0)

不确定是否存在同样的问题,这是我的观察和发现。溶液:

应用程序得到一个NavigationView,其中有5个项目可以切换5个不同的片段(A,B,C,D,E)。最初它正确地切换片段,但在切换大约5次之后,一个片段只是粘在持有者FrameLayout中。所有交易都由replace().commit()调用。

  • 选择A
  • 选择B.
    ...
    ...
  • 选择C
  • 选择A(C只留在支架下面有A)
  • 选择B(C只留在支架下面,B下面)

由于屏幕方向改变,我发现片段C实际上被片段C覆盖了。片段事务已经提交但不知何故片段C没有被替换。 我甚至尝试用getSupportFragmentManager().findFragmentByTag()找到前一个片段。没有任何效果。

因此,对于解决方案,我不确定它是否合法但是有效: ```

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/rootLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:theme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_collapseMode="pin"
            app:layout_scrollFlags="enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

        </android.support.v7.widget.Toolbar>

    </android.support.design.widget.AppBarLayout>


    <FrameLayout
        android:id="@+id/a_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <FrameLayout
        android:id="@+id/b_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <FrameLayout
        android:id="@+id/c_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <FrameLayout
        android:id="@+id/d_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <FrameLayout
        android:id="@+id/e_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>

<android.support.design.widget.NavigationView
    android:id="@+id/navigation"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:itemIconTint="#333"
    app:itemTextColor="#333"
    app:menu="@menu/navigation_drawer_items" />

```

正如您所看到的,每个片段都有5个FrameLayout个容器。当导航项选择其中一个容器设置为VISIBLE时,其他容器设置为GONE。并且工作更顺畅然后片段交易。希望能给你一些想法。

- 编辑 有人说使用附加/分离而不是替换。 https://stackoverflow.com/a/20959779/164005

我试一试。如果你找到了什么,请告诉我。

答案 3 :(得分:0)

我认为这个解决方案应该适用于我。 在您的活动中进行以下更改...并且忘记在您的活动中覆盖onbackpressed按钮.....它会在片段管理器中加载片段并在按下按钮时将其返回...如果有的话...否则发送用户到主屏幕(因为它可以由您自定义)

fragmentManager = getSupportFragmentManager();
    ChatWithUs myFragment0 = new ChatWithUs();
    FragmentTransaction ft = fragmentManager.beginTransaction();
    ft.replace(R.id.frameholder, myFragment0);
    ft.addToBackStack("chat_fragment");
    ft.commit();
    Log.i(MainActivity.TAG, "this is create method last line");

@Override
public void onBackPressed() {
    fragmentManager = getSupportFragmentManager();
    int backCount = fragmentManager.getBackStackEntryCount();
    //Log.i(MainActivity.TAG, String.valueOf(backCount));
    if((backCount > 1)){
        //Log.i(MainActivity.TAG, String.valueOf(backCount)) ;
        //Log.i(MainActivity.TAG, "im here") ;
        fragmentManager.popBackStack();
        Log.i(MainActivity.TAG, String.valueOf(fragmentManager.getBackStackEntryCount()));
    }
    else{
        //super.onBackPressed();
        //Log.i(MainActivity.TAG, String.valueOf(fragmentManager.getBackStackEntryCount())) ;
        Intent a = new Intent(Intent.ACTION_MAIN);
        a.addCategory(Intent.CATEGORY_HOME);
        a.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(a);
    }

}`

答案 4 :(得分:0)

根据此answer,解决方案是在包含其他片段的片段中使用getChildFragmentManager()而不是getSupportFragmentManager(),例如ViewPagers标签。