如何从片段本身替换活动的片段?

时间:2012-11-04 07:34:45

标签: android android-fragments

我的应用程序在其Activity中有一个Fragment。我想以编程方式从当前片段本身替换另一个片段。

例如,如果我点击片段内的一个按钮,片段应该被另一个片段替换,但活动应该保持不变。

有可能吗?如果是的话,该怎么做?

7 个答案:

答案 0 :(得分:53)

来自官方文档:

// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();

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

// Commit the transaction
transaction.commit();

在此示例中,newFragment替换当前在R.id.fragment_container ID标识的布局容器中的任何片段(如果有)。通过调用addToBackStack(),替换的片段将保存到后台,因此用户可以通过按“返回”按钮来反转事务并恢复前一个片段。

您描述的行为正是片段的设计目标。请仔细阅读官方指南,以便彻底了解碎片,这将清除您的所有问题。

http://developer.android.com/guide/components/fragments.html

答案 1 :(得分:42)

实际上很容易调用活动来替换片段。

你需要强制转换getActivity():

((MyActivity) getActivity())

然后您可以从MyActivity调用方法,例如:

((MyActivity) getActivity()).replaceFragments(Object... params);

当然,这假设您的活动中有一个replaceFragments()方法来处理片段替换过程。

编辑: @ismailarilik在此代码中添加了可能的replaceFragments代码,下面的第一条评论由@ silva96撰写:

replaceFragments的代码可以是:

public void replaceFragments(Class fragmentClass) {
    Fragment fragment = null;
    try {
        fragment = (Fragment) fragmentClass.newInstance();
    } catch (Exception e) {
        e.printStackTrace();
    }
    // Insert the fragment by replacing any existing fragment
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.flContent, fragment)
            .commit();
}

答案 2 :(得分:26)

请注意,片段应 NOT 直接替换自身或任何其他片段。片段应该是单独的实体。应该做什么片段来通知其父活动已发生某些事件。但是,再次一个片段工作来决定如何处理它!应该是决定在电话上替换片段的活动,而是在平板电脑上添加另一个片段。所以你基本上是在设计上做错了。

而且,正如其他人已经提到的,您的活动应该使用FragmentManager(“本机”或兼容库)来完成工作(如replace()add()remove()):< / p>

http://developer.android.com/guide/components/fragments.html

答案 3 :(得分:3)

正如Marcin所说,你不应该有一个片段开始另一个片段或活动。处理这种情况的更好方法是为主活动创建一个回调实现来处理诸如启动新片段之类的请求。 Here是android开发者指南中的一个很好的例子。

答案 4 :(得分:0)

有一种方法可以起作用;只需(在片段中)执行以下操作:

getFragmentManager().beginTransaction()
.add(R.id. container_of_this_frag, new MyNewFragment())
.remove(this)
.commit();

答案 5 :(得分:0)

使用嵌套片段时,我们不希望每个内部片段替换都用于最外部的活动。一种允许片段通知其父节点要更改为另一个片段的机制可能会很有用。

这是我在Kotlin中的代码,我认为将其转换为Java很容易。

interface FragmentNavigator {
    fun navigateTo(fragment: Fragment)
}

class NavigableFragment: Fragment() {
    var navigator: FragmentNavigator? = null
    override fun onDetach() {
        super.onDetach()
        navigator = null
    }
}

内部片段需要扩展NavigableFragment,并使用以下代码将自身更改为另一个片段。

navigator?.navigateTo(anotherFragment)

外部活动或片段需要实现FragmentNavigator,并覆盖navigateTo

override fun navigateTo(fragment: Fragment) {
    supportFragmentManager.beginTransaction().replace(view_id, fragment).commit()
}

//Use childFragmentManager instead of supportFragmentManager a fragment

最后在外部活动或片段中,覆盖onAttachFragment

override fun onAttachFragment(fragment: Fragment?) {
    super.onAttachFragment(fragment)
    if(fragment is NavigableFragment) {
        fragment.navigator = this
    }
}

答案 6 :(得分:0)

这对我有用:

getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                    new MenuFragment()).commit();