无法从导航抽屉项目加载片段

Cannot load Fragments from Navigation Drawer items

这方面我找了很多,但我真的无法解决我的问题。我花了几个小时在这上面,但一无所获。

我有一个导航抽屉 Activity,使用 Android Studio 2.1.1 模板制作。当然我想改变我的应用程序的视图,当我点击菜单中的一个项目时,显示不同的片段。这是我在 MainActivity:

中的代码
        public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_camera) {

            Context context = getApplicationContext();
            CharSequence text = "Hello toast!";
            int duration = Toast.LENGTH_SHORT;

            Toast toast = Toast.makeText(context, text, duration);
            toast.show();

            new gaussFragment();

        } else if (id == R.id.nav_gallery) {

        } else if (id == R.id.nav_slideshow) {

        } else if (id == R.id.nav_manage) {

        } else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

当我点击导航抽屉的第一项(id 为 R.id.nav_camera 的那个)时,我可以看到 toast,但新的 Fragment 没有出现。我在 gaussFragment():

中使用此代码
public class gaussFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_gauss, container, false);
    }

}

当然如您所见here fragment_gauss.xml 是其相对布局,代码如下:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="info.androidhive.tabsswipexx.gaussFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>

我该如何解决这个问题?


content_main 是应用程序启动时我首先看到的内容。我应该尝试添加类似

的内容吗?
<FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

并以某种方式加载我的片段?

如果您使用的是 Android Studio 提供的导航抽屉模板,那么在导航抽屉主 activity xml 中,您会发现类似于:

<?xml version="1.0" encoding="utf-8"?>
<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:openDrawer="start">

    <!-- The main content view -->
    <include layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <!-- the navigation drawer the comes from the left-->
    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"

        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

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

如果你仔细看一下,你会发现它由我为你评论的两个主要部分组成。一个用于导航抽屉,另一个用于主要内容。如果您按住 ctrl 并单击 layout="@layout/app_bar_main",您会看到另一个 xml 打开,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="copsonic.com.SoundExchange.demoApp.MainActivity">

    <!--Main View tool bar-->
    <android.support.design.widget.AppBarLayout
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.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" />

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

    <!--The content that will be displayed in the main view when the navigation drawer is not opened-->
    <include layout="@layout/content_main" />

    <!--Floating Action Button Stuff-->
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:scaleType="center"
        android:src="@mipmap/ic_rx_tx"
        android:saveEnabled="false"
        app:backgroundTint="#000000"
        android:adjustViewBounds="false" />



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

你会看到3个主要部分,一个是工具栏,一个是Floating Action Button控件,最后一个是导航抽屉未打开时在主视图中显示的内容,这个是你关心的人。如果你 ctrl+click <include layout="@layout/content_main" /> 你会看到第三个 xml 你必须添加一个 Fragmet 容器。最后是这样的:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/app_bar_main"
    tools:context="copsonic.com.SoundExchange.demoApp.MainActivity">

    <!-- A fragmet container to dynamically swap between fragmets-->
    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

所以在你的主要 activity 代码完成所有这些之后你只需要做两件事,首先管理哪个片段将首先被看到,你在 OnCreate 方法中通过添加来做到这一点:

FragmentTransmitter initialFragment = new FragmentTransmitter();


// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.fragment_container) != null) {

        // this check allows you not to load the default fragment unless 
        //it's the first time you launch the activity after having destroyed it
        if (savedInstanceState != null) {
            return;
        }

    // Create the fragment that is seen the first time your app opens

    //pass useful info to the fragment from main activity if needed 
    //(it is recommended not to do this in the constructor, so you have to do it through a Bundle)
    Bundle args = new Bundle();
    args.putSerializable("ModulationType",aModulation);
    initialFragment.setArguments(args);


    // In case this activity was started with special instructions from an
    // Intent, pass the Intent's extras to the fragment as arguments
    //initialFragment.setArguments(getIntent().getExtras());

    // Add the fragment to the 'fragment_container' FrameLayout
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, initialFragment).commit();

}

然后第二件事是正确处理每次在导航抽屉中选择一个选项时将显示哪个片段

public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_camera) {

            Context context = getApplicationContext();
            CharSequence text = "Hello toast!";
            int duration = Toast.LENGTH_SHORT;

            Toast toast = Toast.makeText(context, text, duration);
            toast.show();

            FragmentTransmitter Gauss= new new gaussFragment();

            //pass useful info to fragment if needed
            Bundle args = new Bundle();
            args.putSerializable(getString(R.string.ModulationType),aModulation);
            Gauss.setArguments(args);

            FragmentTransaction transaction =   getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.fragment_container, Gauss,"TAG_GaussFragment"); //pacing a tag is not mandatory but it is pretty useful if you want to know later which fragment is being displayed in the fragment container
            //transaction.addToBackStack(null);
            transaction.commit();



        } else if (id == R.id.nav_gallery) {

        } else if (id == R.id.nav_slideshow) {

        } else if (id == R.id.nav_manage) {

        } else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }