我正在学习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
那怎么做呢?
答案 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;
}
现在好了。仅当“活动”正在销毁时才会销毁碎片。