从另一个片段调用一个片段,然后替换其布局

Invoking a fragment from another fragment and then replacing its layout

我是 android 开发的新手,对 invocation/replacement 片段有疑问。我的问题与这个非常相似:Android - fragment .replace() doesn't replace content - puts it on top。 "solution" 然而,片段必须在代码中而不是在 xml 文件中创建。

我现在遇到了同样的问题,但我的片段是在代码中动态创建的 (MainActivity.java):

public void selectDrawerItem(MenuItem menuItem) {

    Fragment fragment = null;
    Class fragmentClass;
    switch(menuItem.getItemId()) {
        case R.id.nav_first_fragment:
            fragmentClass = FirstFragment.class;
            break;
        case R.id.nav_second_fragment:
            fragmentClass = SecondFragment.class;
            break;
        case R.id.nav_third_fragment:
            fragmentClass = ThirdFragment.class;
            break;
        default:
            fragmentClass = FirstFragment.class;
    }

    try {
        fragment = (Fragment) fragmentClass.newInstance();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e){
        e.printStackTrace();
    }

    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.flContent, fragment).addToBackStack(null).commit();

    menuItem.setChecked(true);
    setTitle(menuItem.getTitle());

    mDrawer.closeDrawers();
}

现在,当我尝试让那个 Fragment 调用另一个 Fragment 并用新的 Fragment 替换它自己的内容时,它只是将其内容添加到现有的内容下方,而不是替换它。

我的FirstFragment.java:

public class FirstFragment extends Fragment {

private View v;

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

private void configureImageButton() {
    // TODO Auto-generated method stub
    ImageButton btn = (ImageButton) v.findViewById(R.id.imageButton1);

    btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Toast.makeText(getActivity(), "You Clicked the button!", Toast.LENGTH_LONG).show();

            Fragment f1 = null;
            Class c;
            c = FirstFirstFragment.class;

            try {
                f1 = (Fragment) c.newInstance();
            } catch (IllegalAccessException e){
                e.printStackTrace();
            } catch (java.lang.InstantiationException e){
                e.printStackTrace();            }


            FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.tableLayout1, f1);
            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.commit();

        }
    });

}

我的第一个FirstFragment.java:

public class FirstFirstFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.content_first_first, container, false);
    return view;
}

我的activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<!-- This DrawerLayout has two children at the root  -->
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- This LinearLayout represents the contents of the screen  -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- The ActionBar displayed at the top -->
        <include
            layout="@layout/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <!-- The main content view where fragments are loaded -->
        <FrameLayout
            android:id="@+id/flContent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <Switch
                android:id="@+id/switch1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
        </FrameLayout>
    </LinearLayout>

    <!-- The navigation drawer that comes from the left -->
    <!-- Note that `android:layout_gravity` needs to be set to 'start' -->
    <android.support.design.widget.NavigationView
        android:id="@+id/nvView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="@android:color/white"
        app:menu="@menu/drawer_view"
        app:headerLayout="@layout/nav_header"/>
</android.support.v4.widget.DrawerLayout>

我在开头链接的文章的答案中读到有人遇到了这个确切的问题并使用相同的 FragmentManager 解决了它。就像我一样,他之前在他的 Activity 中使用过 getSupportFragmentManager() 并在他的 Fragment 中使用过 getFragmentManager()。

但是 Fragment 不知道 getSupportFragmentManager(),那么它应该如何工作?

我尝试了我所知道的一切来解决这个问题,但没有任何效果。然后我读了这个

As far as i know you cannot add fragments into fragments.In design document it's written that "A fragment must always be embedded in an activity and the fragment's lifecycle is directly affected by the host activity's lifecycle." So your design seems like impossible to develop for now.

关于 Whosebug 上的一个类似问题,我现在想知道:是否有可能让一个片段调用另一个片段然后替换第一个片段?(而不只是添加它下)

我真的希望这个问题是合理的,而不是一些愚蠢的初学者错误,因为我搜索了整个互联网并没有找到合适的答案。

提前感谢您的热心回答:)。

在fragment中使用fragmentManger

getActivity().getSupportFragmentManager()

您应该使用 R.id.flContent 作为您的框架布局主机,因此请使用

fragmentTransaction.replace(R.id.flContent, f1);

而不是

fragmentTransaction.replace(R.id.tableLayout1, f1);