我在ViewPager中有两个活动,第一个用几个ListView管理Fragments,第二个在里面有ListView和WebView。活动中的onCreate方法看起来都是一样的(唯一的区别是pager类):
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_subcat_list);
mPager = new SubcatListPager(this);
mPager.initialisePaging(false);
}
更改屏幕方向时出现问题。使用ListView片段的活动工作正常,但第二个活动在执行此行super.onCreate(savedInstanceState);
时使用WebView创建片段。然后在内部寻呼机代码中再创建一个片段。我在调试器中跟踪它,并在每个方向更改时创建两个带有webview的片段。我通过传递null而不是保存的实例来解决问题:super.onCreate(null);
,但我不认为这是正确的方法。
有没有更好的方法来解决这个问题,并恢复我在ViewPager中创建的片段的状态?我可以使用savedInstanceState并将其传递给我在寻呼机内创建的片段,但我不确定是否将null传递给活动的父节点是正确的。
UPD:ManosProm's solution解决了片段重放问题,但现在这些片段中的getActivity返回null。快速搜索告诉它可能是由于片段与活动分离造成的。这是我的代码:
public CommentsPager(SherlockFragmentActivity fa, Class<? extends SherlockFragment> fragment)
{
mFragmentActivity = fa;
try {
FragmentManager fm = mFragmentActivity.getSupportFragmentManager();
mContentFragment = (SherlockFragment) fm.findFragmentByTag(makeFragmentTag(0));
if (mContentFragment == null)
mContentFragment = fragment.newInstance();
mCommentsFragment = (CommentsListFragment) fm.findFragmentByTag(makeFragmentTag(1));
if (mCommentsFragment == null)
mCommentsFragment = CommentsListFragment.class.newInstance();
}
catch (Exception e) {
e.printStackTrace();
Toast.makeText(fa, "Pager creation failed: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
public void initialisePaging(boolean bInLayout) {
//mFragmentActivity.setTitle(mFragmentActivity.getResources().getString(SiteContent.curr_cat.nameID));
try {
List<Fragment> fragments = new Vector<Fragment>();
mSectionsPagerAdapter = new CommentsPagerAdapter(mFragmentActivity.getSupportFragmentManager(), fragments);
if (!(mContentFragment instanceof ContentDownloader)) {
throw new IllegalStateException(
"Fragment must implement content downloader interface.");
}
fragments.add(mContentFragment);
fragments.add(mCommentsFragment);
mViewPager = (ViewPager)mFragmentActivity.findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
final ActionBar actionBar = mFragmentActivity.getSupportActionBar();
actionBar.removeAllTabs();
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
Tab tab = actionBar.newTab();
tab.setText(mSectionsPagerAdapter.getPageTitle(i)).setTabListener(this);
actionBar.addTab(tab, i == 0);
}
//actionBar.setDisplayShowTitleEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayHomeAsUpEnabled(!bInLayout);
}
catch (Exception e)
{
e.printStackTrace();
}
}
如何将片段重新附加到活动中?或者代码很好,我应该在其他地方寻找问题?
答案 0 :(得分:2)
这是因为在方向更改时,您的viewpager中的片段将被重新创建,因此您可以创建相同类型的另一个片段。但是你的第一个片段没有被破坏,它只是保留在堆栈中。所以最后你有一个方向景观片段和一个肖像片段。
将null传递给onCreate可以解决您的问题,因为之前的片段没有重新创建,但它只是错误,因为如果您使用此方法,您可能会遇到其他问题;
解决问题的方法是检查片段管理器中是否已存在片段,然后是否存在该片段,或者是否创建新片段并提交事务!
下面是一个示例代码(取自我的一个测试文件)。
MFragment fragment1;
if (fragmentManager().findFragmentByTag("android:switcher:" + R.id.viewpager + ":" + 0) == null) {
M.LogLifecycle("Fragment1", "does not exists so instantiate");
fragment1 = MFragment.instance("Example");
}
else {
M.LogLifecycle("Fragment1", "exists so retrieve instance");
fragment1 = (MFragment) fragmentManager().findFragmentByTag("android:switcher:" + R.id.viewpager + ":" + 0);
}
检查"android:switcher:" + R.id.viewpager + ":" + position
默认情况下FragmentPagerAdapter在FragmentManager中存储片段的方式,其中R.id.viewpager是布局中viewpager的id,位置是你的片段在viewpager中的位置。 / p>
我只能举例说明如何在viewpager中实现它,因为你没有添加很多项目代码。
片段的一般想法是在提交事务之前检查片段管理器中是否存在它们,否则您可能会创建重复项。