57

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

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

可能吗?如果是这样,该怎么做?

4

7 回答 7

57

来自官方文档:

// 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_containerID 标识的布局容器中当前存在的任何片段(如果有)。通过调用addToBackStack(),被替换的片段被保存到后退堆栈中,因此用户可以通过按“后退”按钮来反转事务并带回前一个片段。

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

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

于 2012-11-04T08:11:29.243 回答
56

调用activity来替换fragment其实很简单。

您需要转换 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();
}
于 2012-11-04T18:31:03.880 回答
30

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

而且,正如其他人已经提到的,您的活动应该使用 FragmentManager (“本机”或来自兼容性库)来完成这项工作(如replace()oradd()remove()):

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

于 2012-11-04T18:48:14.783 回答
4

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

于 2013-08-27T23:32:03.920 回答
0

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

getFragmentManager().beginTransaction()
.add(R.id. container_of_this_frag, new MyNewFragment())
.remove(this)
.commit();
于 2019-03-02T15:04:50.523 回答
0

这对我有用:

getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                    new MenuFragment()).commit();
于 2020-11-24T20:13:40.473 回答
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
    }
}
于 2019-05-06T19:26:29.587 回答