androidandroid-fragmentsandroid-viewpagerfragmenttransaction

ViewPager inside Fragment disappear after transaction.remove() (Maintain instance?)


I'm using Google API 8(Android 2.2) with v4 packages.

Hi, here is my problem:

I have a FragmentActivity that has a menu who always stays on screen and a little container(a FrameLayout) where a I put many fragments. My application works fine when I'm hiding and showing fragments but it crashes after I load all fragments because I have a limited memory to use. In this case, I had to remove some of the fragments when loading others, so the application doesn't crash. But here comes another problem, my pagers doesn't reload after I remove them, all others fragments works fine. Only my pagers doesn't show, they don't crash, just disappear. Here goes some code to give you a clue of what my problem is about:

MyFragmentActivity.java has this layout:

 <LinearLayout

        ...(some code from menu that doesn't matter)

        <FrameLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
        </FrameLayout>
    </LinearLayout>

In that FrameLayout, I put all my fragments. The pager fragments is one of them and its layout looks like:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <android.support.v4.view.ViewPager
        android:id="@+android:id/some_pager"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
</LinearLayout>

And I implemented this abstract class AbstractPagerFragment:

import java.util.List;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public abstract class AbstractPagerFragment extends Fragment {


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment

        View fragment = inflater.inflate(getLayoutID(), container,false);
        PagerAdapter mPagerAdapter = initializePager();
        ViewPager pager = (ViewPager) fragment.findViewById(getPagerID());
        pager.setAdapter(mPagerAdapter);
        return fragment;
    }

    private PagerAdapter initializePager() {
        PagerAdapter mPagerAdapter = new templateDigital.util.PagerAdapter(getFragmentManager(), getFragments());
        return mPagerAdapter;

    }

    public abstract List<Fragment> getFragments();

    public abstract int getLayoutID();

    public abstract int getPagerID();

}

This uses my PagerAdapter that looks like:

import java.util.List;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class PagerAdapter extends FragmentPagerAdapter{

    private List<Fragment> fragments;

    public PagerAdapter(FragmentManager fManager, List<Fragment> fragments) {
        super(fManager);
        this.fragments = fragments;
    }


    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }


    @Override
    public int getCount() {
        return fragments.size();
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
}

Now, let's implements my AbstractPagerFragment:

import templateDigital.main.R;
import templateDigital.util.fragments.AbstractPagerFragment;
import templateDigital.util.fragments.GenericFragment;
import android.support.v4.app.Fragment;

public class ConcretePagerFragment extends AbstractPagerFragment {

    private List<Fragment> fragments;

    public ConcretePagerFragment() {
        fragments = new ArrayList<Fragment>();
        fragments.add(new GenericFragment(R.layout.concept_page1_fragment));
        fragments.add(new GenericFragment(R.layout.concept_page2_fragment));
        fragments.add(new GenericFragment(R.layout.concept_page3_fragment));

        //GenericFragments is a class that extends Fragments and just inflate a layout with a background image.
    }

    @Override
    public List<Fragment> getFragments() {
        return fragments;
    }

    @Override
    public int getLayoutID() {
        return R.layout.pager_fragment;
    }

    @Override
    public int getPagerID() {
        return R.id.some_pager; // the pager inside the layout
    }
}

Okay, now I add it from my content(FrameLayout) like this( myFragment is a PagerFragment, and myTag is a string that represents its tag defined by me):

FragmentTransaction transaction = fragmentManager.beginTransaction();
    if (fragmentManager.findFragmentByTag(myTag) == null) {
        transaction.add(R.id.content,myFragment, myTag);
    }

    transaction.setCustomAnimations(R.anim.fade_in, R.anim.fade_out);
    hideAllOtherFragments(myTag, transaction); //Here I hide all other fragments, the code is okay. Trust me.
    transaction.show(myFragment());
    transaction.commit();

And this is how I remove it:

...
transaction.remove(myFragment);
...

But when it should load again after I navigate back to the fragment in the menu, using the same method I used in the first time(code above), the pager doesn't show anymore. Can anyone resolve this?

If you read all of this, thank you, you are a champion.


Solution

  • Actually, if you want to implement ViewPager with fragments, you should add a TabHost, a TabWidget a FrameLayout and a ViewPager.

    The TabHost will be the container for a tabbed window view. This object holds two children: a set of tab labels that the user clicks to select a specific tab, and the FrameLayout is an object that displays the contents of that page. And after you have to create a TabAdapter(that is something like your PagerAdapter), and add the fragments for each tab by calling mTabsAdapter.addTab and sending the Fragment as parameter