开发者

Replace fragment with another fragment inside ViewPager

I'm using a ViewPager together with a FragmentPagerAdapter to host three different fragments

[Fragment1][Fragment2][Fragment3]

What I'm trying to achieve is to successfully replace Fragment1 with a whole new fragment, Fragment4, if a specific task succeeds.

When I use..

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.fragment1_layout_id, fragment4);
transaction.commit();

..the fragment is replaced beautifully and Fragment4 is shown instead of Fragment1. Though as soon as I swipe all the way to Fragment3 and then back to Fragment4, Fragment1 has made a comeback.

Then again, if I use..

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.remove(fragment1);
transaction.commit();

..Fragment1 is removed and when I come back Fragment4 is there. So the problem with this solution is that I couldn't find a way to immediately show Fragment4 as Fragment1 is removed, even if I tried:

transaction.add(fragment4);
transaction.show(fragment4);

And here's how my FragmentPagerAdapter implementation looks like at the moment, without any transaction managing:

public static class PagerAdapter extends FragmentPagerAdapter {

    public PagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public int getCount() {
        return VIEW_COUNT;
    }

    @Override
    public Fragment getItem(int position) {

        Fragment fragment = null;

        switch (position) {
        case 0:
            fragment = Fragment1.newInstance(context_);
            break;

        case 1:
            fragment = Fragment2.newInstance(context_);
            break;

        case 2:
            fragment = Fragment3.newInstance(context_);
            break;

        default:
            break;
        }

        return fragment;
    }
}

Edit.

So it seems like I wasn't totally clear with my question. I decided to remove all the spaghetti I managed to create earlier and tried to state that I had left them off (see bolded text above).

Anyway here's pretty much what I have been trying to do inside getItem():

@Override
public Fragment getItem(int position) {

    Fragment fragment = null;

    switch (position) {
    case 0:

        if (!app.isUserLoggedIn) {
            if (loginFragment_ == null) {
                loginFragment_ = LoginFragment.newInstance(context_);
                transaction_ = fragmentManager_.beginTransaction();

                if (logoutFragment_ != null) {
                    transaction_.remove(logoutFragment_);
                    logoutFragment_ = null;
                }

                transaction_.add(loginFragment_, "login");
                transaction_.commit();
            }

            if (fragmentManager_.findFragmentByTag("login") == null)
                fragment = LoginFragment.newInstance(context_);
            else
                fragment = fragmentManager_.findFragmentByTag("login");

        } else {
            if (logoutFragment_ == null) {                      
                logoutFragment_ = LogoutFragment.newInstance(context_);
                transaction_ = fragmentManager_.beginTransaction();

                if (loginFragment_ != null) {
                    transaction_.remove(loginFragment_);
                    loginFragment_ = null;
                }

                transaction_.add(logoutFragment_, "logout");
                transaction_.commit();
            }

            if (fragmentManager_.findFragmentByTag("logout") == null)
                fragment = LogoutFragment.newInstance(context_);
            else
                fragment = fragmentManager_.findFragmentByTag("logout");
        }
        break;

    case 1:
        fragment = HomeFragment.newInstance(context_);
        break;

    case 2:
        fragment = RegisterFragment.newInstance(context_);
        break;

    default:
        break;
    }

    return fragment;
}

With this code I get nothing done, but开发者_开发百科 if someone sees what I'm doing wrong and would like to point me in the correct direction, I'd appreciate it a lot!


Try using FragmentStatePagerAdapter

http://android-developers.blogspot.com/2011_08_01_archive.html

coz it will remove the fragment as you swipe through the view(also when you call getitem), so you don't need to explicitly remove them yourself.

I've been having the same problem it works for me.

I try your code and remove the if (fragment!=null) block and it works.


Like Maurycy said, you need to call mAdapter.notifyDataSetChanged() whenever you want to tell the ViewPager that the fragments have been replaced. However, you also need to override the getItemPosition() abstract function in your adapter and return POSITION_NONE when called with an old, to be hidden, fragment as argument. Otherwise, ViewPager will retain all current fragments.

For more information and example code, see this answer to a related question.


Shouldn't your getItem statement be returning fragment4 for case 0 in some circumstances?


Hey I have solved this problem by using a List inside my FragmentPagerAdapter to handle the various fragments and then my getItem is like so....

    public void addScreen(String tag, Class<?> clss, Bundle args){
        if(clss!=null){
            TabInfo info = new TabInfo(tag, clss, args);
            screens.add(info);
        }
    }
@Override
    public Fragment getItem(int position) {
        TabInfo info = screens.get(position);
        return Fragment.instantiate(context, info.clss.getName(), info.args);
    }

I then programmatically remove/add/rearrange the list items (fragments) then call on the handler

mAdapter.notifyDataSetChanged()


Try setting offScreenPageLimit to 5 (or based on your usecase) to avoid reloading of the fragment so that what you had replaced will stay instead of getting reloaded when you swipe.

    mViewPager.setOffscreenPageLimit(5);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜