如何在单个选项卡中显示新的片段?

Lal*_*ani 8 android android-fragments

我正在创建一个包含一个片段的三个选项卡,现在我想用同一个选项卡中的新片段替换第一个Tab的片段.如何保持标签保持不变?

我的代码 -

Tab_Widget.java

    public class Tab_Widget extends TabActivity {

            TabHost tabHost; 

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

            tabHost = getTabHost();

            tabHost.addTab(tabHost.newTabSpec("Tab1")
                .setIndicator("Tab1")
                .setContent(new Intent().setClass(this, main_activity.class)));

            tabHost.addTab(tabHost.newTabSpec("Tab2")
                .setIndicator("Tab2")
                .setContent(new Intent().setClass(this, second_activity.class)));

            tabHost.addTab(tabHost.newTabSpec("Tab3")
                    .setIndicator("Tab3")
                    .setContent(new Intent().setClass(this, third_activity.class)));

            tabHost.setCurrentTab(0);
        }
     }
Run Code Online (Sandbox Code Playgroud)

main_activity.java

public class main_activity extends FragmentActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mainfragment);
    }
}
Run Code Online (Sandbox Code Playgroud)

main_fragment.java

public class main_fragment extends Fragment
{
    LinearLayout mLayout;
    Button mButton;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        mLayout = (LinearLayout) inflater.inflate(R.layout.main_view, null);
        mButton = (Button) mLayout.findViewById(R.id.btn);
        mButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                Fragment mFragment = new third_fragment_view();
                FragmentTransaction ft = getFragmentManager().beginTransaction();
//              ft.replace(R.id.Maincontainer, mFragment);
                ft.replace(R.id.main_fragment, mFragment);
                ft.addToBackStack(null);
                ft.commit();
            }
        });
        return mLayout;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的XML

mainfragment.xml

<?xml version="1.0" encoding="utf-8"?>

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

<fragment
  android:name="com.fragment.main_fragment"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:id="@+id/main_fragment">
</fragment>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

通过,这个片段无疑被称为,但它与之前的片段重叠.

Gra*_*eme 7

你有这样的结构:

TabActivity
 -> Tab1 = FragmentActivity = MainFragment
 -> Tab2          
 -> Tab3          
Run Code Online (Sandbox Code Playgroud)

MainFragment你内部试图替换其容器(本身)的内容.

最好是MainFragment调用一个自定义TabActivity,它反过来调用它的容器上的替换,或者像这样(这可能会犯同样的问题,因为它基本上从同一个地方运行相同的代码,但它应该给你我建议的一个基本概念):

    Fragment newFragment = new FragmentToChangeTo();
    CustomTabActivity tabActivity = (CustomTabActivity) getActivity();
    tabActivity.changeFragment(newFragment);
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,请尝试执行类似的操作,而不是直接通过Intents&Actions(或Bundles)调用活动直接将命令传递给它,其中包含有关更改哪个容器的信息.

我宁愿说/为什么/碎片不能很好地处理片段碎片​​和相关的复杂性:请在这里查看为什么我建议切割碎片不受碎片控制.


the*_*enp 5

好的,有几件事:

  1. 您不需要更换和删除.有效替换只删除第一个片段并在其位置添加第二个片段.

  2. 我怀疑你的参数对于replace命令是不正确的.这是正确的形式:

    replace (int containerViewId, Fragment fragment)
    
    Run Code Online (Sandbox Code Playgroud)

    你似乎传递了片段本身的id,而不是容器的id.replace命令获取容器视图的id,并在添加新容器之前删除该容器中的所有片段.所以如果这是你的布局:

    <LinearLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
        <fragment class="com.example.stackoverflow.YourFragmentName"
        android:id="@+id/main_fragment"
        android:layout_weight="1"
        android:layout_width="0px"
        android:layout_height="match_parent" />
    
    </LinearLayout>
    
    Run Code Online (Sandbox Code Playgroud)

    你会用:

    replace(R.id.container, mFragment);
    
    Run Code Online (Sandbox Code Playgroud)

    并不是

    replace(R.id.main_fragment, mFragment);
    
    Run Code Online (Sandbox Code Playgroud)
  3. 由于您正在尝试findFragmentById(R.id.main_fragment),我怀疑您已将此片段添加到XML布局文件中.如果直接在XML中添加了片段,则无法在运行时以编程方式删除它.要删除或替换片段,必须在运行时使用FragmentTransaction添加它们.

编辑:

我原来的答案中的数字2和3仍然适用.您需要使用包含ViewGroup的id进行添加和替换.在这种情况下,那是你的LinearLayout,R.id.Maincontainer,而不是R.id.main_fragment.

另外,正如我之前所说,您无法删除直接在XML中添加的片段.您main_fragment已添加到XML中,因此无法在运行时删除.

试试这个mainfragment.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/Maincontainer"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <Button
    android:id="@+id/btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Switch Fragments">

</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

这适用于你的main_fragment类:

public class main_activity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mainfragment);

        //Notice that I am adding this 1st fragment in the Activity and not the XML
        main_fragment mainFragment = new main_fragment();
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.add(R.id.Maincontainer, mainFragment);
        ft.commit();

        mButton = (Button) findViewById(R.id.btn);
        mButton.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View v)
            {

                Fragment mFragment = new third_fragment_view();
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                //Replacing using the id of the container and not the fragment itself
                ft.replace(R.id.Maincontainer, mFragment);
                ft.addToBackStack(null);
                ft.commit();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)