用 Fragment 替换 ViewPager - 然后导航回去 [英] Replacing ViewPager with Fragment - Then Navigating Back

查看:25
本文介绍了用 Fragment 替换 ViewPager - 然后导航回去的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个活动,它最初托管一个 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.

当我用 B 替换 A,然后按返回时,我希望导航回 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();

    }

寻呼适配器:

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";
        }
    }
}

main 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 相关的问题中有所描述:popBackStack 后未恢复 ViewPager 中的片段

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);

这篇关于用 Fragment 替换 ViewPager - 然后导航回去的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆