更改片段而无需重新创建

时间:2018-04-19 14:26:01

标签: java android android-fragments

我正在学习MVP。

我有导航菜单和活动,我从菜单中更改片段:

switch (id) {
    case R.id.nav_status:
        fragmentManager.beginTransaction().replace(R.id.fr_main, mAppProductFragment).commit();
        Log.d(TAG, "Выбрано меню статус");
        break;           
    case R.id.nav_schemas:
        AppRedirectFragment schemasFragment = new AppRedirectFragment();
        fragmentManager.beginTransaction().replace(R.id.fr_main, schemasFragment).commit();
        Log.d(TAG, "Выбрано меню переадресация");
        break;
}

问题在于,当我更改片段时,我之前的片段被破坏了。 它调用以下回调:

D/AppProductPresenter: onStopDetouchView()
D/AppProductFragment:  onDestroyView
D/AppProductFragment: onDestroy()

它丢失了对演示者的引用,并且还提供了所有改装请求。  mPresenter.onDestroyView();,所以我的所有网络操作都是destroyd。但我喜欢在背景中运行它们。但它处置了。

public void onDestroy() {
        super.onDestroy();
        mPresenter.onDestroyView();
    }

那么如何在不调用onDestroy的情况下更改片段呢?我读到我必须使用add代替fragmentManager.beginTransaction().replace 那怎么做呢?

3 个答案:

答案 0 :(得分:1)

使用时

fragmentManager
.beginTransaction()
.replace(R.id.fr_main, schemasFragment)
//addToBackstack(String name) //if you want to keep transaction to backstack
.commit();

replace()将删除以前的片段并添加新片段,因此您无法避免使用onDestroy()。 但是当你打电话时

fragmentManager
.beginTransaction()
.add(R.id.fr_main, schemasFragment)
//addToBackstack(String name) //if you want to keep transaction to backstack
.commit();

你只是add上一个片段的新片段和之前的片段仍然存在。但是,如果您在不删除之前添加大量片段 - 您的应用程序可能会变得迟缓。 如果您的改造请求很复杂 - 在服务中做出好的决定。

答案 1 :(得分:0)

我遇到了类似的问题。我正在使用ViewPager来管理片段视图,使用ArrayList来存储它们的实例。我也是使用片段的bottomNavigationView,你可以改为你的导航方法。我知道我创建片段并放入列表的ordem,我知道要在我的BottomNavigationView的ClickListener上设置的索引。

MainActivity.java

public class MainActivity extends AppCompatActivity  {

List<Fragment> fragmentList;
MyAdapter myAdapter;
ViewPager viewPager;

BottomNavigationView bottomNavigationView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.i(TAG,"onCreate()");

    fragmentList = new ArrayList<>();
    fragmentList.add(new Fragment1());
    fragmentList.add(new Fragment2());

    bottomNavigationView = findViewById(R.id.bottomNavigationView);
    viewPager = findViewById(R.id.viewPagerAppActivity);

    myAdapter = new MyAdapter(getSupportFragmentManager());
    viewPager.setAdapter(myAdapter);
    viewPager.setCurrentItem(0);

    bottomNavigationView.setOnNavigationItemSelectedListener(botNavViewItemSelectedListener());

}

public BottomNavigationView.OnNavigationItemSelectedListener botNavViewItemSelectedListener() {
    return new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {

            switch (item.getItemId()) {
                case R.id.itemFragment1:

                    viewPager.setCurrentItem(0);
                    break;

                case R.id.itemFragment2:

                    viewPager.setCurrentItem(1);
                    break;
            }

            return true;
        }
    };
}

public class MyAdapter extends FragmentStatePagerAdapter {

    public MyAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return fragmentList.get(position);
    }

    @Override
    public int getCount() {
        return fragmentList.size();
    }
}

}

activity_main.xml中

<android.support.constraint.ConstraintLayout android:layout_width="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPagerAppActivity"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@id/bottomNavigationView"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginBottom="0dp"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="0dp"
        app:layout_constraintVertical_bias="1.0" />

    <android.support.design.widget.BottomNavigationView
        app:menu="@menu/menu_bottom"
        android:id="@+id/bottomNavigationView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:itemBackground="@color/colorPrimary"
        app:itemIconTint="@drawable/bottom_bar_item_selector"
        app:itemTextColor="@drawable/bottom_bar_item_selector"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />

</android.support.constraint.ConstraintLayout>
用于填充导航菜单的

menu_bottom.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item android:id="@+id/itemFragment1" android:title="Frag1" android:enabled="true" app:showAsAction="always|withText" android:icon="@mipmap/ic_launcher"/>
    <item android:id="@+id/itemFragment2" android:title="Frag2" android:enabled="true" app:showAsAction="always|withText" android:icon="@mipmap/ic_launcher"/>


</menu>

答案 2 :(得分:0)

我解决了一个问题。 答案是使用以下组合:.add .attach.detach方法。我创建了一个替换像这样的碎片的函数:

 switch (id) {
            case R.id.nav_product:
                replaceFragment(PRODUCT_FRAGMENT);
                break;
            case R.id.nav_redirection:
                replaceFragment(REDIRECTION_FRAGMENT);
                break;
}

private void replaceFragment(String tag) {
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    Fragment currentFragment = fragmentManager.findFragmentById(R.id.fr_container);
    Fragment nextFragment = fragmentManager.findFragmentByTag(tag);

    Log.d(TAG, "f detached: " + currentFragment.toString());
    transaction.detach(currentFragment);

    if (nextFragment == null) {
        nextFragment = createFragment(tag);
        transaction.add(R.id.fr_container, nextFragment, tag);
    } else {
        Log.d(TAG, "f attach: " + nextFragment.toString());
        transaction.attach(nextFragment);
    }
    transaction.commit();
}

private Fragment createFragment(String tag) {
    Fragment result = null;
    switch (tag) {
        case CALLHISTORY_FRAGMENT:
            result = new AppCallHistoryFragment();
            break;
        case CALLTRACKING_FRAGMENT:
            result = new AppCallTrackingFragment();
            break;
        case REDIRECTION_FRAGMENT:
            result = new AppRedirectFragment();
            break;
    }
    Log.d(TAG, "create: " + result.toString());
    return result;
}

现在好了。仅当“活动”正在销毁时才会销毁碎片。

相关问题