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

时间:2011-08-01 06:22:08

标签: android android-fragments

我正在创建一个包含一个片段的三个选项卡,现在我想用同一个Tab中的新片段替换第一个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);
        }
     }

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);
    }
}

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;
    }
}

我的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>

通过,这个片段无疑会被调用,但它与之前的片段重叠。

3 个答案:

答案 0 :(得分:7)

你有这样的结构:

TabActivity
 -> Tab1 = FragmentActivity = MainFragment
 -> Tab2          
 -> Tab3          

MainFragment内部,您正在尝试替换其容器(本身)的内容。

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

    Fragment newFragment = new FragmentToChangeTo();
    CustomTabActivity tabActivity = (CustomTabActivity) getActivity();
    tabActivity.changeFragment(newFragment);

如果这不起作用,尝试做类似的事情,而不是直接调用活动通过Intents&amp;动作(或捆绑包),包含有关更改哪个容器的信息。

我更愿意说/为什么/碎片不能很好地处理片段碎片​​和相关的复杂性:检查here以查看为什么我建议切割碎片不受碎片控制。

答案 1 :(得分:5)

好的,好几件事:

  1. 您不需要替换和删除。有效替换只删除第一个片段并添加第二个片段。

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

    replace (int containerViewId, Fragment fragment)
    

    你似乎传递了片段本身的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>
    

    你会使用:

    replace(R.id.container, mFragment);
    

    而不是

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

  4. 修改

    我原来的答案中的数字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>
    

    这是你的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();
                }
            });
        }
    }
    

答案 2 :(得分:0)

@theisenp我正在创建一个标签视图,当单击一个按钮时,它必须移动到另一个屏幕,当我尝试使用上面的代码实现它时,它正在切换到另一个屏幕但是按钮仍然可以通过下一个屏幕看到我希望下一个屏幕应该覆盖整个屏幕

public class Tab1Fragment extends Fragment  {
LinearLayout mLayout;
/** (non-Javadoc)
 * @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
 */
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    if (container == null) {


        return null;
    }

    LinearLayout theLayout = (LinearLayout)inflater.inflate(R.layout.tab_frag1_layout, container, false);

            // Register for the Button.OnClick event

            Button b = (Button)theLayout.findViewById(R.id.button1);

            b.setOnClickListener(new View.OnClickListener() {



                @Override

                public void onClick(View v) {

                     Fragment mFragment = new third_fragment_view();
                     android.support.v4.app.FragmentTransaction ft = getFragmentManager().beginTransaction();

                     ft.replace(R.id.container, mFragment);
                     ft.addToBackStack(null);
                     ft.commit();   


                }

            });

    return theLayout;

}
}

activity is displaying partially