java 替换片段不起作用/我是否以正确的方式执行此操作?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11620855/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 05:48:31  来源:igfitidea点击:

Replacing Fragments isn't working/Am I executing this the proper way?

javaandroidandroid-fragments

提问by EGHDK

It's taken me some time to wrap my head around fragments, but this should be my last question on fragments, since I think I just about have them down. I know this is a huge mess of code to go through. But I'd appreciate the help, to make sure I'm not breaking any fundamental rules with fragments.

我花了一些时间来思考 Fragment,但这应该是我关于 Fragment 的最后一个问题,因为我想我快要解决它们了。我知道这是一大堆代码。但我很感激你的帮助,以确保我没有用片段破坏任何基本规则。

I am going to post all of my code just to see if someone can "look over it" to see if I'm making any major mistakes or if I should go a simpler route. Lastly, as stated in the title, my fragment is NOT being replaced... it'd being added on top.

我将发布我所有的代码只是为了看看是否有人可以“查看它”以查看我是否犯了任何重大错误或者我是否应该走更简单的路线。最后,如标题所述,我的片段没有被替换......它会被添加到顶部。

File Tree:

文件树:

enter image description here

在此处输入图片说明

MainActivity.java:

主活动.java:

package com.example.learn.fragments;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;

public class MainActivity extends FragmentActivity{

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    /* Add a class to handle fragment */
    public static class SSFFragment extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            View v = inflater.inflate(R.layout.choose_pill_frag, container,
                    false);
            return v;
        }
    }

    public void red(View view) {


        // Create new fragment and transaction
        ExampleFragments newFragment = new ExampleFragments();
        android.support.v4.app.FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

        // Replace whatever is in the fragment_container view with this fragment,
        // and add the transaction to the back stack
        transaction.replace(R.id.frag, newFragment);
        transaction.addToBackStack(null);

        // Commit the transaction
        transaction.commit();
    }

    public void blue(View view) {
        //Figure out code for "red" first
    }

}

ExampleFragments.java:

示例Fragments.java:

package com.example.learn.fragments;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

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

ActivityMain.xml:

ActivityMain.xml:

<RelativeLayout 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" >

    <fragment
        android:id="@+id/frag"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.example.learn.fragments.MainActivity$SSFFragment" />

</RelativeLayout>

choose_pill_frag.xml

choose_pill_frag.xml

<RelativeLayout 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" >

    <ImageButton
        android:id="@+id/imageButton1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:onClick="blue"
        android:src="@drawable/blue" />

    <ImageButton
        android:id="@+id/imageButton2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:onClick="red"
        android:src="@drawable/red" />

</RelativeLayout>

red_pill_frag.xml

red_pill_frag.xml

<RelativeLayout 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" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="You stay in Wonderland and I show you how deep the rabbit-hole goes."
        android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

The application should show two buttons. The two buttons exist in a single fragment, and then if you hit a button, the fragment gets replaced with a new fragment that shows the proper text. As of right now, it should replace, but it only seems to add it on top.

应用程序应显示两个按钮。这两个按钮存在于一个片段中,然后如果你点击一个按钮,这个片段就会被一个显示正确文本的新片段替换。截至目前,它应该替换,但它似乎只是将它添加到顶部。

回答by pawelzieba

Instead of <fragment>use <FrameLayout>in layout xml for activity.

而不是<fragment><FrameLayout>在布局XML的活动。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container_id"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Then in FragmentActivityin onCreateadd initial fragment (in your case SSFFragment):

然后在FragmentActivityonCreate添加初始片段(你的情况SSFFragment):

    FragmentA fragmentA = new FragmentA();
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.add(R.id.container_id, fragmentA);
    transaction.commit();

From inside fragment you can replace fragment in container.

从片段内部,您可以替换容器中的片段。

class FragmentA extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        Button button = new Button(getActivity());
        button.setText("Replace");
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                FragmentB fragmentB = new FragmentB();
                transaction.replace(R.id.container_id, fragmentB);
                transaction.commit();
            }
        });
        return button;
    }
}

回答by whyoz

Here is the answer to your real question...since this was your second question resulting from your original post, I've modified the solution to get at that frag in another way:

这是您真正问题的答案……由于这是您的原始帖子产生的第二个问题,因此我修改了解决方案以通过另一种方式解决该问题:

Fragment details = (Fragment)getSupportFragmentManager().findFragmentById(R.id.details);
details = new ExamplesFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.details, details);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();

Also, the android.support.v4.apppart is just not necessary, and frankly leads to possible hours of "going down the wrong road" type efforts by adding and removing it all over your code (as long as you're using:)

此外,android.support.v4.app部分并不是必需的,坦率地说,通过在您的代码中添加和删除它(只要您使用: )

import android.support.v4.app.FragmentTransaction;

In this my example, you don't need to import the support for FragmentManager. However, if you're getting errors, make sure you've imported the library itself into your "libs" folder.

在我的这个示例中,您不需要导入对 FragmentManager 的支持。但是,如果出现错误,请确保已将库本身导入到“libs”文件夹中。

This solution will fix the overlapping fragment problem, and hopefully save people hours of tinkering around with replacing frags.

该解决方案将解决重叠片段问题,并有望为人们节省数小时的时间来更换片段。

回答by grv_9098

well i was facing the same problem and i just replace the fragment from main layout with linear lay out and guess what its working.. its strange dont know how but its working. i am using actionbar to switch between fragments for replacing my code is :

好吧,我遇到了同样的问题,我只是用线性布局替换了主布局中的片段,然后猜测它的工作原理..奇怪的是不知道它是如何工作的。我正在使用操作栏在片段之间切换以替换我的代码是:

 protected class MyTabsListener1 implements ActionBar.TabListener{
        private Fragment frag ;
        public MyTabsListener1 ( Fragment frag){
            this.frag = frag;
        }

        @Override
        public void onTabReselected(Tab tab, FragmentTransaction ft) {
            //  TODO Auto-generated method stub

        }

        @Override
        public void onTabSelected(Tab tab, FragmentTransaction ft) {

                switch (tab.getPosition()){
                case 0:

                        ft.replace(R.id.replace, homeFrag);
                    break;

                case 1:
                    ft.replace(R.id.replace, createFrag);
                        break;

                case 2:
                    ft.replace(R.id.replace, ioListFrag);
                    break;
                case 3:

                    ft.replace(R.id.replace, settingFrag);

                    break;      


                default: 


                    break;

                }

            }

and my main layout is this :

我的主要布局是这样的:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <LinearLayout
        android:id="@+id/replace"
        android:layout_width="wrap_content"
        android:layout_height="match_parent" >
    </LinearLayout>

</LinearLayout>

回答by Ewoks

In short, you CAN NOT replace fragment if u defined it in XML with fragment tag. Instead, as @pawelzieba adviced add Frame tag in your layout, find it and add,remove, replace fragments there.. Hope it helped. Cheers

简而言之,如果您使用片段标记在 XML 中定义片段,则不能替换片段。相反,正如@pawelzieba 建议在您的布局中添加 Frame 标签,找到它并添加、删除、替换那里的片段..希望它有所帮助。干杯

回答by Steven Schoen

The main benefit of using fragments is to be able to make them take up portions of the screen rather than the whole screen, which is what Activities do.

使用片段的主要好处是能够让它们占据屏幕的一部分而不是整个屏幕,这就是活动所做的。

If you're just making an app for a small screen that will function like an Activity, but is coded in Fragments, just make a separate FragmentActivityfor each of your Fragments.

如果您只是为小屏幕制作一个应用程序,该应用程序的功能类似于 Activity,但在 Fragments 中编码,只需FragmentActivity为您的每个 Fragment创建一个单独的应用程序。

Make this the onCreate of your FragmentActivity:

使其成为您的 FragmentActivity 的 onCreate:

public void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.emptylayout);

    FragmentManager fragmentManager = getSupportFragmentManager(); //Or getFragmentManager() if you're not using the support library
    FragmentTransaction fragmentTransaction = fragmentManager
            .beginTransaction();
    YourFragment fragment = new YourFragment();
    fragmentTransaction.add(R.id.emptyview, fragment);
    fragmentTransaction.commit();
}

Where layout/emptylayout is an XML layout file with a FrameLayout. id/emptyview is that FrameLayout.

其中 layout/emptylayout 是一个带有 FrameLayout 的 XML 布局文件。id/emptyview 就是那个 FrameLayout。

If you want to use XML for your fragment's actual layout, make a separate XML layout for the actual fragment, and inflate it in the fragment's `onCreateView':

如果您想为片段的实际布局使用 XML,请为实际片段创建一个单独的 XML 布局,并在片段的“onCreateView”中对其进行扩充:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.files, container, false);
            // Do stuff here
    return view;
}

Then just use startActivity(new Intent(getActivity(), YourFragmentActivity.class))to launch a FragmentActivity from a Fragment.

然后只需使用startActivity(new Intent(getActivity(), YourFragmentActivity.class))从 Fragment 启动 FragmentActivity。

It seems redundant, yeah, but if you're going to be targeting larger screens later (if not, why are you bothering with fragments?), it'll make it easier in the long run.

这似乎是多余的,是的,但是如果您以后打算以更大的屏幕为目标(如果不是,您为什么要为碎片烦恼?),从长远来看,它会让事情变得更容易。