Android 使用viewPager在FragmentActivity内更改方向

Android 使用viewPager在FragmentActivity内更改方向,android,android-fragments,android-viewpager,fragment,screen-orientation,Android,Android Fragments,Android Viewpager,Fragment,Screen Orientation,我正在尝试构建一个应用程序,以纵向和横向模式显示一本书。所以很明显,有1页显示在肖像中,2页显示在风景中。每个模式都很好,但当我将方向从纵向更改为横向时,viewPager会尝试从纵向模式获取2页,而不是尝试从横向模式获取2页。。。 事实上,FragmentStatePagerAdapter保留了在纵向模式中创建的2个片段,并在为横向模式创建2个双页之前使用它们。如果我在纵向模式下再次切换,FragmentStatePagerAdapter将使用先前在横向模式下创建的2个片段,因此我再次看到1个

我正在尝试构建一个应用程序,以纵向和横向模式显示一本书。所以很明显,有1页显示在肖像中,2页显示在风景中。每个模式都很好,但当我将方向从纵向更改为横向时,viewPager会尝试从纵向模式获取2页,而不是尝试从横向模式获取2页。。。 事实上,FragmentStatePagerAdapter保留了在纵向模式中创建的2个片段,并在为横向模式创建2个双页之前使用它们。如果我在纵向模式下再次切换,FragmentStatePagerAdapter将使用先前在横向模式下创建的2个片段,因此我再次看到1个双页而不是1个单页等。。如果我继续切换方向,我会得到一个OutOfMemory错误,因为FragmentStatePagerAdapter从未在方向更改时刷新它的片段

以下是两个更容易理解的用例:

  • 我在纵向模式下启动viewPager
  • 我看到第一页了,好吗
  • 我向右滑动,看到第2页ok
  • 我向右滑动,看到第3页ok
  • 我将屏幕旋转到横向模式
  • 我看第三页错了
  • 我向右滑动,看到第4页错了
  • 我向右滑动,看到第5页和第6页,好吗

  • public class PlayerFragmentActivity extends FragmentActivity {
    private Intent mIntent;
    private ViewPager mPortraitPager;
    private ViewPager mLandscapePager;
    private Boolean mIsLandscape;
    private String mKey;
    private int mNbPages;
    private int mNbDoublePages;
    private PageFactory mPageFactory;
    private DoublePageFactory mDoublePageFactory;
    private PagerAdapter mPagerAdapter;
    
    @Override
    protected void onStop(){
        super.onStop();
        mPagerAdapter = null;
        mDoublePageFactory = null;
        mPageFactory = null; 
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_activity_player);
        mIntent = getIntent();
        mKey = mIntent.getStringExtra("key");
        mNbPages = mIntent.getIntExtra("nbPages", 0);
        mNbDoublePages = DoublePageFactory.getDoublePageNumFromPageNum(mNbPages);
    
        Resources res = getResources();
        mIsLandscape = (res.getConfiguration().orientation == 1) ? false : true;
        mPortraitPager = (ViewPager) findViewById(R.id.portraitPager);
        mLandscapePager = (ViewPager) findViewById(R.id.landscapePager);
    
        mPagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
    
        if (mIsLandscape) {
            mDoublePageFactory = new DoublePageFactory(this, mKey, mNbPages, res.getInteger(R.integer.nb_page_columns), res.getInteger(R.integer.nb_page_columns));
            mPortraitPager.setVisibility(View.GONE);
            mLandscapePager.setAdapter(mPagerAdapter);
            mPortraitPager.setAdapter(null);
        } else {
            mPageFactory = new PageFactory(this, mKey, this.mNbPages, res.getInteger(R.integer.nb_page_columns), res.getInteger(R.integer.nb_page_columns));
            mLandscapePager.setVisibility(View.GONE);
            mPortraitPager.setAdapter(mPagerAdapter);
            mLandscapePager.setAdapter(null);
        }
    }
    
    
    public class MyPagerAdapter extends FragmentStatePagerAdapter {
    
        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
        }
    
        @Override
        public Fragment getItem(int position) {
            Bundle args = new Bundle();
            if(mIsLandscape){
                Fragment doublePageFragment = new DoublePageFragment();
                args.putInt(DoublePageFragment.ARG_DOUBLEPAGE_NUM, position + 1);
                doublePageFragment.setArguments(args);
                return doublePageFragment;
            }else{
                Fragment pageFragment = new PageFragment();
                args.putInt(PageFragment.ARG_PAGE_NUM, position + 1);
                pageFragment.setArguments(args);
                return pageFragment;
            }
        }
    
        @Override
        public int getCount() {
            return (mIsLandscape) ? mNbDoublePages:mNbPages;
    
        }
    
                /* j'ai essayé cette méthode mais ça ne fonctionne pas :( */
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
                FragmentManager manager = ((Fragment) object).getFragmentManager();
                FragmentTransaction trans = manager.beginTransaction();
                trans.remove((Fragment) object);
                trans.commit();
    
            super.destroyItem(container, position, object);
        }
    
        @Override
        public int getItemPosition(Object object){
            return PagerAdapter.POSITION_NONE;
        }
    
        @Override
        public CharSequence getPageTitle(int position) {
            return "p." + position + 1;
        }
    }
    
    public boolean isLandscape() {
        return mIsLandscape;
    }
    
    public ImageView getSinglePage(int position) {
        return mPageFactory.getPage(position);
    }
    
    
    public LinearLayout getDoublePage(int position) {
        return mDoublePageFactory.getDoublePage(position);
    }
    }
    
    
    public class PageFragment extends Fragment {    
    private PlayerFragmentActivity mPlayerFragmentActivity;
    public static final String ARG_PAGE_NUM = "page_number";
    public static final String ARG_WOBOOK_DIRECTORY = "book_directory";
    public static final String ARG_NB_PAGE_COLUMNS = "nb_page_columns";
    public static final String ARG_NB_PAGE_ROWS = "nb_page_rows";
    
    @Override
    public ImageView onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        mPlayerFragmentActivity = ((PlayerFragmentActivity) getActivity());
        return mPlayerFragmentActivity.getSinglePage(getArguments().getInt(ARG_PAGE_NUM));
    }
    
    @Override
    public void onStop(){
        super.onStop();
        mPlayerFragmentActivity = null;
    }
    
  • 我在纵向模式下启动viewPager

  • 我看到第一页了,好吗
  • 我向右滑动,看到第2页ok
  • 我向右滑动,看到第3页ok
  • 我向右滑动,看到第4页ok
  • 我向右滑动,看到第5页ok
  • 我将屏幕旋转到横向模式
  • 我看第5页错了
  • 我向左滑动,看到第4页错了
  • 我向左滑动,看到第2页和第3页ok

    public class PlayerFragmentActivity extends FragmentActivity {
    private Intent mIntent;
    private ViewPager mPortraitPager;
    private ViewPager mLandscapePager;
    private Boolean mIsLandscape;
    private String mKey;
    private int mNbPages;
    private int mNbDoublePages;
    private PageFactory mPageFactory;
    private DoublePageFactory mDoublePageFactory;
    private PagerAdapter mPagerAdapter;
    
    @Override
    protected void onStop(){
        super.onStop();
        mPagerAdapter = null;
        mDoublePageFactory = null;
        mPageFactory = null; 
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_activity_player);
        mIntent = getIntent();
        mKey = mIntent.getStringExtra("key");
        mNbPages = mIntent.getIntExtra("nbPages", 0);
        mNbDoublePages = DoublePageFactory.getDoublePageNumFromPageNum(mNbPages);
    
        Resources res = getResources();
        mIsLandscape = (res.getConfiguration().orientation == 1) ? false : true;
        mPortraitPager = (ViewPager) findViewById(R.id.portraitPager);
        mLandscapePager = (ViewPager) findViewById(R.id.landscapePager);
    
        mPagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
    
        if (mIsLandscape) {
            mDoublePageFactory = new DoublePageFactory(this, mKey, mNbPages, res.getInteger(R.integer.nb_page_columns), res.getInteger(R.integer.nb_page_columns));
            mPortraitPager.setVisibility(View.GONE);
            mLandscapePager.setAdapter(mPagerAdapter);
            mPortraitPager.setAdapter(null);
        } else {
            mPageFactory = new PageFactory(this, mKey, this.mNbPages, res.getInteger(R.integer.nb_page_columns), res.getInteger(R.integer.nb_page_columns));
            mLandscapePager.setVisibility(View.GONE);
            mPortraitPager.setAdapter(mPagerAdapter);
            mLandscapePager.setAdapter(null);
        }
    }
    
    
    public class MyPagerAdapter extends FragmentStatePagerAdapter {
    
        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
        }
    
        @Override
        public Fragment getItem(int position) {
            Bundle args = new Bundle();
            if(mIsLandscape){
                Fragment doublePageFragment = new DoublePageFragment();
                args.putInt(DoublePageFragment.ARG_DOUBLEPAGE_NUM, position + 1);
                doublePageFragment.setArguments(args);
                return doublePageFragment;
            }else{
                Fragment pageFragment = new PageFragment();
                args.putInt(PageFragment.ARG_PAGE_NUM, position + 1);
                pageFragment.setArguments(args);
                return pageFragment;
            }
        }
    
        @Override
        public int getCount() {
            return (mIsLandscape) ? mNbDoublePages:mNbPages;
    
        }
    
                /* j'ai essayé cette méthode mais ça ne fonctionne pas :( */
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
                FragmentManager manager = ((Fragment) object).getFragmentManager();
                FragmentTransaction trans = manager.beginTransaction();
                trans.remove((Fragment) object);
                trans.commit();
    
            super.destroyItem(container, position, object);
        }
    
        @Override
        public int getItemPosition(Object object){
            return PagerAdapter.POSITION_NONE;
        }
    
        @Override
        public CharSequence getPageTitle(int position) {
            return "p." + position + 1;
        }
    }
    
    public boolean isLandscape() {
        return mIsLandscape;
    }
    
    public ImageView getSinglePage(int position) {
        return mPageFactory.getPage(position);
    }
    
    
    public LinearLayout getDoublePage(int position) {
        return mDoublePageFactory.getDoublePage(position);
    }
    }
    
    
    public class PageFragment extends Fragment {    
    private PlayerFragmentActivity mPlayerFragmentActivity;
    public static final String ARG_PAGE_NUM = "page_number";
    public static final String ARG_WOBOOK_DIRECTORY = "book_directory";
    public static final String ARG_NB_PAGE_COLUMNS = "nb_page_columns";
    public static final String ARG_NB_PAGE_ROWS = "nb_page_rows";
    
    @Override
    public ImageView onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        mPlayerFragmentActivity = ((PlayerFragmentActivity) getActivity());
        return mPlayerFragmentActivity.getSinglePage(getArguments().getInt(ARG_PAGE_NUM));
    }
    
    @Override
    public void onStop(){
        super.onStop();
        mPlayerFragmentActivity = null;
    }
    
    }

我已经读到框架中的FragmentManager负责保存状态并恢复寻呼机生成的任何活动片段。所以我猜当方向改变时,碎片管理者说

嘿!我已经创建了2个项目,所以我不需要创建新闻, 我们去拿吧

但事实上,它从旧的定向模式中获得了两个项目(页面/双页面)。因此,我需要找到一种方法,在方向发生变化时删除FragmentManager保存的片段

我也做了测试。这个问题似乎与


致以最诚挚的问候

尝试将方向限制为纵向或横向模式。因为我们只能在精确模式下使用“查看寻呼机”。

您如何解决此问题?