替换交易后如何保持片段状态?

时间:2019-01-08 08:20:03

标签: java android android-fragments android-mapview

我在一个Android应用中有两个片段(假设 FragmentA FragmentB ),我可以使用 BottomBar 进行切换。

我有一个正在使用 Retrofit 获取的数据列表,该列表是使用 FragmentA 中的 RecyclerView 显示的,并且我有一个< FragmentB 中的strong> MapView 。

我的问题是,每当我从 FragmentB 切换回 FragmentA 时, API调用都会再次获取数据列表。然后,当我从 FragmentA 切换到 FragmentB 时,MapView从头开始再次呈现。

有没有一种方法可以保持FragmentA的状态,即数据列表的状态,直到销毁Activity?并将MapView保留在FragmentB中?

我用以下替换片段。

public void replaceFragment(Fragment fragment // This can be FragmentA or FragmentB) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.framelayout, fragment);
        transaction.commit();
    }
  

我只想片段化以保持其状态,而不是重新初始化   一切,直到活动被破坏。我想人生   碎片的循环方法在这里起着重要的作用。

感谢您的帮助。谢谢!

3 个答案:

答案 0 :(得分:1)

在MyActivity中, 在onCreate上方声明两个片段对象:

private Fragment1 fragment1 = new Fragment1();
private Fragment2 fragment1 = new Fragment2();

点击BottomBar,您可以将两个片段都设置为单击以显示和隐藏。

设置片段1为选中状态

private void fragment1Selected() {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        if (fragment1 == null || !fragment1.isAdded()) {
            fragment1 = new Fragment1();
            transaction.add(R.id.framelayout, fragment1);
        } else {
            transaction.show(fragment1);
        }

        if (fragment2 != null)
            transaction.hide(fragment2);

        transaction.commit();
    }

设置片段2为选中状态

private void fragment2Selected() {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        if (fragment2 == null || !fragment2.isAdded()) {
            fragment2 = new Fragment2();
            transaction.add(R.id.framelayout, fragment2);
        } else {
            transaction.show(fragment2);
        }

        if (fragment1 != null)
            transaction.hide(fragment1);

        transaction.commit();
    }

答案 1 :(得分:1)

Architecture components更适合您的情况。使用LiveDataViewModel

  1. 在“活动”中,创建一个视图模型,并使用服务器响应更新实时数据。

  2. 在片段中,使用实时数据更新视图。

在这种情况下,ViewModel生命周期将附加到该活动,并且片段事务不会影响所存储的数据。由于您是从LiveData更新数据,因此在创建活动时只会进行一次api调用。除此之外,ViewModel还可以保留方向更改,这意味着LiveData仍然保留API响应。

答案 2 :(得分:0)

以鲁米特·帕特尔(Rumit Patel)的答案为基础

我创建了一个显示第一个片段的函数

private fun initialFragment(fragment: Fragment) {
    val fragmentTransaction = supportFragmentManager.beginTransaction()
    fragmentTransaction.replace(R.id.frameLayoutMA,fragment)
    fragmentTransaction.commit()
}

然后对于每个后续片段,我将前一个片段(我要隐藏的片段)与新片段(我要显示的片段)一起传递给该函数

private fun fragmentSelected(oldFragment: Fragment, newFragment: Fragment) {
    val fragmentTransaction = supportFragmentManager.beginTransaction()

    fragmentTransaction.hide(oldFragment)

    if (!newFragment.isAdded) {
        fragmentTransaction.add(R.id.frameLayoutMA, newFragment)
    }

    else {
        fragmentTransaction.show(newFragment)
    }

    fragmentTransaction.commit()
}

如果要隐藏多个片段,则可以创建一个arrayList并添加除要显示的片段之外的所有片段

fun fragmentArrayList(exception: Int): ArrayList<Fragment> {

    val fragmentList: ArrayList<Fragment> = ArrayList()

    if (exception != fragment1) {
        fragmentList.add(fragment1)
    }

    if (exception != fragment2 {
        fragmentList.add(fragment2)
    }

    if (exception != fragment3 {
        fragmentList.add(fragment3)
    }

    if (exception != fragment4 {
        fragmentList.add(fragment4)
    }

    return fragmentList
}

并使用第二种功能的这种变体隐藏除新片段以外的所有片段

    private fun fragmentSelected(oldFragments: ArrayList<Fragment>, newFragment: Fragment) {
    val fragmentTransaction = supportFragmentManager.beginTransaction()

    for (oldFragment in oldFragments) {
        fragmentTransaction.hide(oldFragment)
    }

    if (!newFragment.isAdded) {
        fragmentTransaction.add(R.id.frameLayoutMA, newFragment)
    }

    else {
        fragmentTransaction.show(newFragment)
    }

    fragmentTransaction.commit()
}