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

发布于 2024-11-27 15:09:21 字数 2966 浏览 0 评论 0 原文

我正在创建三个选项卡,每个选项卡包含一个片段,现在我想用同一选项卡中的新片段替换第一个选项卡的片段。如何在选项卡保持不变的情况下做到这一点?

我的代码 -

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

ma​​in_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);
    }
}

ma​​in_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

< strong>ma​​infragment.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>

毫无疑问,这个 Fragment 会被调用,但它与前一个 Fragment 重叠。

I am creating a three tabs that contains one fragment each now I want to replace the first Tab's Fragment with a new Fragment within the same Tab. How can I do that with the tab remaining the same?

My Code -

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

My 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>

By, this the Fragment is getting called no doubt, but its overlapping the previous Fragment.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

独自唱情﹋歌 2024-12-04 15:09:21

您的结构如下:

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

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

最好是 MainFragment 调用一个自定义的 TabActivity,而该 TabActivity 又调用其容器上的替换,或者像这样(这可能会遇到同样的问题,因为它基本上从相同的地方,但它应该让您对我的建议有一个基本的了解):

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

如果这不起作用,请尝试做类似的事情,但不要直接调用活动,而是通过 Intents & 向其传递命令。包含有关将哪个容器更改为什么内容的信息的操作(或捆绑包)。

我更愿意说/为什么/ Fragments 不能很好地与 Fragment-in-fragment 和相关的复杂性配合使用:检查 这里看看为什么我建议将片段切割出片段的控制。

You have a structure like so:

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

From inside of MainFragment you are trying to replace the contents of its container (itself).

It would be best if the MainFragment called a customised TabActivity which in turn called a replace on it's container, either like so (Which may likely fall foul of the same problem as it's basically running the same code from the same place, but it should give you a basic idea of what I'm suggesting):

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

If this doesn't work try doing a similar thing but instead of calling the activity directly pass commands to it through Intents & Actions (or Bundles) containing information on what to change which container to.

I would have preferred to say /why/ Fragments don't work well with Fragment-in-fragment and related intricacies: check here to see why I suggest cutting fragments out of the control of fragments.

黎歌 2024-12-04 15:09:21

好的,有几件事:

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

  2. 我怀疑您的替换命令参数不正确。这是正确的形式:

    replace(int containerViewId, Fragment片段)
    

    您似乎传递的是片段本身的 id,而不是容器的 id。替换命令获取容器视图的 ID,并在添加新片段之前删除该容器中的所有片段。因此,如果这是您的布局:

    
    
        
    
    
    

    你会使用:

    replace(R.id.container, mFragment);
    

    而不是

    replace(R.id.main_fragment, mFragment);
    
  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>

为您的 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();
            }
        });
    }
}

OK, several things:

  1. You don't need both replace and remove. Replace effectively just removes the first fragment and adds the second in its place.

  2. I suspect that your arguments are incorrect for the replace command. This is the proper form:

    replace (int containerViewId, Fragment fragment)
    

    You seem to be passing the id of the fragment itself, rather than the id of the container. The replace command takes the id of the container view and removes all fragments in that container before adding a new one. So if this was your layout:

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

    You would use:

    replace(R.id.container, mFragment);
    

    and not

    replace(R.id.main_fragment, mFragment);
    
  3. Since you are trying to findFragmentById(R.id.main_fragment), I suspect that you have added this fragment to your XML layout file. If you have a fragment added directly in the XML, you cannot remove it programmatically at run time. In order to remove or replace fragments, you must have added them with a FragmentTransaction at run time.

EDIT:

Numbers 2 and 3 from my original answer still apply. You need to use the id of the containing ViewGroup for adding and replacing. In this case, that's your LinearLayout, R.id.Maincontainer, not R.id.main_fragment.

Also, as I said before, you cannot remove fragments that you have added directly in the XML. Your main_fragment is added in the XML and therefore cannot be removed at run time.

Try this for your 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>

And this for your main_fragment class:

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();
            }
        });
    }
}
冷默言语 2024-12-04 15:09:21

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

}
}

@theisenp i am creating a tab view in that when a button is clicked it must move to another screen when i try to implement it using the above code it is changing to another screen but the button is still visible with next screen and i want next screen should cover entire screen

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文