【问题标题】:orientation change with webview in view pager在视图寻呼机中使用 webview 更改方向
【发布时间】:2013-07-28 02:54:03
【问题描述】:

我有两个使用 ViewPager 的活动,第一个使用几个 ListView 管理 Fragments,第二个里面有 ListView 和 WebView。 Activity 中的两个 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 片段的 Activity 工作正常,但是当执行此行 super.onCreate(savedInstanceState); 时,第二个 Activity 会创建带有 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();
        }
    }

如何将片段重新附加到活动?还是代码没问题,我应该在别处寻找问题?

【问题讨论】:

    标签: android android-fragments android-webview android-viewpager


    【解决方案1】:

    发生这种情况是因为在方向更改时,您的 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 是您的视图页面在布局中的 id,位置是您的片段在视图页面中的位置。

    我只能给你一个如何在 viewpager 中实现它的例子,因为你没有添加太多的项目代码。

    片段的一般想法是在提交事务之前检查它们是否存在于片段管理器中,否则您可能会创建重复。

    【讨论】:

    • 我已经更新了我的问题并发布了更多代码,请看一下
    • 您在片段中使用 getActivity() 或 getSherlockActivity() 吗? (只是为了确保这不是一件简单的事情)。
    • 再想一想,我认为您的代码存在问题,您应该再次查看有关如何使用 FragmentPagerAdapter 实现 Fragment ViewPager 的示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    相关资源
    最近更新 更多