问题描述
我有一个活动,它最初托管一个 ViewPager,连接到 FragmentPagerAdapter.
I've got an activity which initially hosts a ViewPager, hooked up to a FragmentPagerAdapter.
当用户单击 ViewPager 的子片段中的项目时,我正在使用 FragmentTransaction 将空容器视图替换为要导航到的新片段.
When the user clicks on an item inside the ViewPager's child fragment, I'm using a FragmentTransaction to replace an empty container view with a new Fragment which I want to navigate to.
如果我在事务上使用 addToBackStack(),提交事务然后返回,我不会返回到 ViewPager 的视图(初始布局).
If I use addToBackStack() on the transaction, commit the transaction and then navigate back, I am not returned to the ViewPager's views (the initial layout).
如果我不在事务上使用 addToBackStack(),提交事务然后返回,应用程序退出.
If I don't use addToBackStack() on the transaction, commit the transaction and then navigate back, the application exits.
ViewPager 似乎没有添加到后台堆栈中(这并不奇怪,因为它本身不是一个片段).但我希望默认行为是后台按下将我带回即活动初始视图(ViewPager).
It seems apparent that the ViewPager is not added to the backstack (which is not that surprising as it isn't a fragment in itself).. But I would expect the default behaviour would be that the back press takes me back to that activities initial View (the ViewPager).
根据我读到的内容,似乎可能是因为片段事务正在发生,ViewPager 或 PagerAdapter 失去了对应该显示哪个片段的跟踪.
Based on what I've read, it seems that perhaps because a fragment transaction is taking place, the ViewPager or PagerAdapter loses track of which fragment should be on display.
我真的对此感到困惑,但我最终创建了一大堆代码来覆盖 onBackPress 并显示和隐藏 viewpager 视图.我会认为有一种更简单的方法可以使用默认行为来执行适当的导航.
I'm really confused with this, but I ended up creating a huge mess of code overriding the onBackPress and showing and hiding the viewpager views. I would've thought there is a simpler way to use default behaviours to perform the appropriate navigation.
tl;博士
A 是一个 Viewpager 托管片段.B 是一个新的 Fragment.
A is a Viewpager hosting fragments. B is a new Fragment.
当我将 A 替换为 B,然后按返回时,我希望导航回 A,但这并没有发生.
When I replace A with B, and then press back, I expect to navigate back to A, but that is not happening.
任何建议将不胜感激.
代码:
主活动:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
headingLayout = (RelativeLayout) findViewById(R.id.headingLayout);
headingLayout.setVisibility(View.GONE);
// Set up the ViewPager, attaching the adapter and setting up a listener
// for when the
// user swipes between sections.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setPageMargin(8);
/** Getting fragment manager */
FragmentManager fm = getSupportFragmentManager();
/** Instantiating FragmentPagerAdapter */
MyFragmentPagerAdapter pagerAdapter = new MyFragmentPagerAdapter(fm);
/** Setting the pagerAdapter to the pager object */
mViewPager.setAdapter(pagerAdapter);
.
.
.
}
public void onListItemClicked(Fragment fragment) {
fromPlayer = false;
InitiateTransaction(fragment, true);
}
public void InitiateTransaction(Fragment fragment, boolean addToBackStack) {
invalidateOptionsMenu();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragmentContainer, fragment).addToBackStack(null)
.commit();
}
PagerAdapter:
PagerAdapter:
package another.music.player;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import another.music.player.fragments.AlbumListFragment;
import another.music.player.fragments.ArtistListFragment;
import another.music.player.fragments.SongListFragment;
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 3;
/** Constructor of the class */
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
/** This method will be invoked when a page is requested to create */
@Override
public Fragment getItem(int i) {
switch (i) {
case 0:
ArtistListFragment artistListFragment = new ArtistListFragment();
Bundle artistData = new Bundle();
artistData.putInt("current_page", i + 1);
artistListFragment.setArguments(artistData);
return artistListFragment;
case 1:
AlbumListFragment albumListFragment = new AlbumListFragment();
Bundle albumData = new Bundle();
albumData.putInt("current_page", i + 1);
albumData.putBoolean("showHeader", false);
albumListFragment.setArguments(albumData);
return albumListFragment;
default:
SongListFragment songListFragment = new SongListFragment();
Bundle songData = new Bundle();
songData.putInt("current_page", i + 1);
songListFragment.setArguments(songData);
return songListFragment;
}
}
/** Returns the number of pages */
@Override
public int getCount() {
return PAGE_COUNT;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Artists";
case 1:
return "Albums";
default:
return "Songs";
}
}
}
主xml(包含fragmentContainer & ViewPager):
main xml (containing fragmentContainer & ViewPager):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/app_background_ics" >
<RelativeLayout
android:id="@+id/headingLayout"
android:layout_width="match_parent"
android:layout_height="56dp" >
</RelativeLayout>
<FrameLayout
android:id="@+id/fragmentContainer"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@+id/headingLayout" />
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<android.support.v4.view.PagerTabStrip
android:id="@+id/pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#33b5e5"
android:paddingBottom="4dp"
android:paddingTop="4dp"
android:textColor="#fff" />
</android.support.v4.view.ViewPager>
</RelativeLayout>
推荐答案
我也遇到这个问题很久了.解决方案非常简单,您不需要任何对 ViewPager Visibility 的修改.我在其他与 SO 相关的问题中进行了描述:ViewPager 中的片段在 popBackStack 后未恢复
I also had this very same problem for a long time. The solution turns out to be very simple, and you don't need any hacks with the ViewPager Visibility. I is described in this other SO related question: Fragment in ViewPager not restored after popBackStack
但是,为了简单起见,您只需在 ViewPager 适配器中使用 getChildFragmentManager(),而不是 getSupportFragmentManager().所以,而不是这个:
However, to make it simple, all you need is to use getChildFragmentManager() in your ViewPager adapter, instead of getSupportFragmentManager(). So, instead of this:
/** Getting fragment manager */
FragmentManager fm = getSupportFragmentManager();
/** Instantiating FragmentPagerAdapter */
MyFragmentPagerAdapter pagerAdapter = new MyFragmentPagerAdapter(fm);
/** Setting the pagerAdapter to the pager object */
mViewPager.setAdapter(pagerAdapter);
你这样做:
/** Getting fragment manager */
FragmentManager fm = getChildFragmentManager();
/** Instantiating FragmentPagerAdapter */
MyFragmentPagerAdapter pagerAdapter = new MyFragmentPagerAdapter(fm);
/** Setting the pagerAdapter to the pager object */
mViewPager.setAdapter(pagerAdapter);
这篇关于用片段替换 ViewPager - 然后导航回来的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!