Fragment onCreateView getting called multiple time so that new instance of fragment is created every time

937 Views Asked by At

I am trying to add the fragments on page change of view pager. but every time when i scroll the view pager, new instant of fragment is created.

public void initializeViewPager(int currentPage, String selectedCardNumber) {
    currentPosition = currentPage;
    FragmentPagerAdapter journeyViewPagerAdapter =
            new ViewPagerAdapter(getSupportFragmentManager());


    ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            //Default Implementation
        }

        @Override
        public void onPageSelected(int position) {
            currentPosition = position;
            addFragments(position, selectedCardNumber);
            handleScrollState();
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            //Default Implementation
        }
    };

    viewPager.addOnPageChangeListener(onPageChangeListener);
    initCarousalAdapter();

}

addFragments() method

private void addFragments(int position, final String selectedCardNumber) {

    FragmentTransaction fragTransaction = getSupportFragmentManager().beginTransaction();
    Bundle bundle = new Bundle();
    bundle.putInt(ApplicationConstants.SELECTED__TYPE, position);
    bundle.putString(DataConstants.SELECTED__NUMBER, selectedCardNumber);

    switch (position) {
        case 1:
            OffersFragmentOne fragment = OffersFragmentOne.getInstance();
            fragment.setArguments(bundle);
            fragTransaction.replace(R.id.btmt_fragment_container, fragment);
            break;

        case 2:
            OffersFragmentTwo mtFragment = OffersFragmentTwo.getInstance();
            mtFragment.setArguments(bundle);
            fragTransaction.replace(R.id.btmt_fragment_container, mtFragment);
            break;

        case 3:
            OffersFragmentThree poFragment = OffersFragmentThree.getInstance();
            poFragment.setArguments(bundle);
            fragTransaction.replace(R.id.btmt_fragment_container, poFragment);
            break;
        default:
            //Default Implementation
    }

    fragTransaction.commit();
}

getInstance() method

private static OffersFragmentOne offersFragmentOne;

public static OffersFragmentOne getInstance() {
    if (OffersFragmentOne == null) {
        offersFragmentOne = new OffersFragmentOne();
    }
    return offersFragmentOne;
}

ViewPagerAdapter.java

public class ViewPagerAdapter extends FragmentPagerAdapter {

private final int[] carousalImages = {R.drawable.ic_po_carousal_banner, 
R.drawable.ic_bt_carousal_banner,
    R.drawable.ic_mt_carousal_banner, R.drawable.ic_po_carousal_banner, 
R.drawable.ic_bt_carousal_banner};

public ViewPagerAdapter(FragmentManager fragmentManager) {
    super(fragmentManager);
}

@Override
public Fragment getItem(int position) {
    CarousalFragment frag = new CarousalFragment();
    CarousalFragmentPresenter.createAndAttach(frag, carousalImages[position]);
    return frag;
}

@Override
public int getCount() {
    return carousalImages != null ? carousalImages.length : 0;
}
}
2

There are 2 best solutions below

1
Akriti Sondhi On

How about creating the fragment instances in the container activity or so of the view pager? That way they should be created only when the container is created.

EDIT: Adding example code. Example:

public class ContainerActivity extends AppCompatActivity {
    private FragmentOne fragmentOne;
    private FragmentTwo fragmentTwo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.container_with_view_pager);
        fragmentOne = FragmentOne.getInstance();
        fragmentTwo = FragmentTwo.getInstance();

        ViewPager viewPager = findViewById(R.id.viewpager);
        setupViewPager(viewPager);
    }

    private void setupViewPager(ViewPager viewPager) {
        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
        adapter.addFragment(fragmentOne, "Fragment One");
        adapter.addFragment(fragmentTwo, "Fragment Two");
        viewPager.setAdapter(adapter);
    }
}
1
Kishore Jethava On

You should write your switch case in getItem and don't required bundle and fragment transaction because getItem itself returns selected Fragment and will bind with ViewPager

@Override
public Fragment getItem(int position) {
switch (position) {
    case 0:
        CarousalFragment();
        break;
    case 1:
        OffersFragmentOne.getInstance();
        break;

    case 2:
        OffersFragmentTwo.getInstance();

        break;

    case 3:
        OffersFragmentThree.getInstance();
        break;
    default:
        //Default Implementation
}
}

OnPageChangeListener just give you the position of selected and scrolled item or fragment, so don't required to add fragment from onPageSelected

ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        //Default Implementation
    }

    @Override
    public void onPageSelected(int position) {

    }

    @Override
    public void onPageScrollStateChanged(int state) {
        //Default Implementation
    }
};