Search code examples
androidandroid-viewpagerfragmentonsaveinstancestate

Fragment's onCreate is being called before transaction.commit


I have multiple fragments in viewpager. Fragment A, Fragment B , Fragment C and Fragment D. Fragment C is replacing itself with another fragment which extends list fragment. I want to replace the fragment when only Fragment C is visible. because there is some background AsyncTask being performed which should be done when the fragment C is selected. I have replaced the fragment which works fine. But the problem is that its state is being saved. Because whenever Fragment C's neighbor is called The fragment replaced inside Fragment C is also called automatically

I have implemented all code. I Just dont want to call the replacing fragment when Fragment C's neighbor Fragment is called

public class VendorsListFragment extends Fragment {

private static final String TAG = VendorsActivity.class.getSimpleName();

@BindView(R.id.layoutAdViewBottomVendorActivity)
AdView mAdView;
View view;
boolean isLaunched= false;
boolean isRejected= false;

public VendorsListFragment() {
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.activity_vendors, container, false);
    ButterKnife.bind(this, view);
    return view;
}

public void callNewFragment() {

        FragmentManager manager = getChildFragmentManager();
        FragmentTransaction ft = manager.beginTransaction();
        VendorFragment vendorFragment = new VendorFragment();

        ft.remove(vendorFragment);
        ft.replace(R.id.vendorFragmentContainer, new VendorFragment());
        //container is the ViewGroup of current fragment
        ft.addToBackStack(null);
        ft.commit();
        ft.commitAllowingStateLoss();
}
}

Activity which has ViewPager has following code

public class NetworkToolsActivity extends AppCompatActivity  {

TabLayout tabHost;
public ViewPager pager;
ViewPagerAdapter adapter;
private Resources res;
int tabPosition;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    initializeMainContext(this);

    setContentView(R.layout.activity_network_tools);
    res = this.getResources();
    Intent mIntent = getIntent();
    int selectedTab = mIntent.getIntExtra("tabPosition", 0);

    Toolbar toolbar = (Toolbar) this.findViewById(R.id.toolbar);
    toolbar.setTitleTextColor(Color.WHITE);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setDisplayShowHomeEnabled(true);
    this.setSupportActionBar(toolbar);
    tabHost = findViewById(R.id.tabHost);
    pager = (ViewPager) this.findViewById(R.id.pager );
    adapter = new ViewPagerAdapter(getSupportFragmentManager());
    pager.setAdapter(adapter);

    final int pageMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getResources()
            .getDisplayMetrics());
    pager.setPageMargin(pageMargin);

    tabHost.setupWithViewPager(pager);
    pager.setCurrentItem(selectedTab);
    pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            if (position==6){
                VendorsListFragment frag  = (VendorsListFragment)adapter.getItem(position);
                frag.callNewFragment();
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

} 
}

ViewPager Adapter Class

public class ViewPagerAdapter extends FragmentStatePagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
    super(fm);
}

@Override
public Fragment getItem(int position) {
    Fragment frag = null;
    switch (position) {
        case 0:
            frag = new SpeedTestFragment();
            break;
        case 1:
            frag = new LanScanFragment();
            break;
        case 2:
            frag = new IpToolFragment();
            break;
        case 3:
            frag = new RouterFinderFragment();
            break;
        case 4:
            frag = new NetworkInformationFragment();
            break;
        case 5:
            frag = new ChannelRatingFragment();
            break;

        case 6:
            frag = new VendorsListFragment();
            break;
        case 7:
            frag = new AccessPointsFragment();
            break;
        case 8:
            frag = new ChannelRatingFragment();
            break;
        case 9:
            frag = new ChannelGraphFragment();
            break;
        case 10:
            frag = new TimeGraphFragment();
            break;

    }

    return frag;
}

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

@Nullable
@Override
public CharSequence getPageTitle(int position) {
    CharSequence sequence = null;
    switch (position) {
        case 0:
            sequence = "Speed Test";
            break;
        case 1:
            sequence = "Lan Scan";
            break;
        case 2:
            sequence = "Ip Tools";
            break;
        case 3:
            sequence = "Router Finder";
            break;
        case 4:
            sequence = "Network Information";
            break;
        case 5:
            sequence = "Available Channels";
            break;
        case 6:
            sequence = "Vendors";
            break;
        case 7:
            sequence = "Access Point";
            break;
        case 8:
            sequence = "Channel Rating";
            break;
        case 9:
            sequence = "Channel Graph";
            break;
        case 10:
            sequence = "Time Graph";
            break;

    }
    return sequence;
}

}


Solution

  • You need to get ViewPager's CurrentItem to see if it is at 3rd position.

    if (getActivity() != null && ((YourActivity)getActivity()).viewPager.getCurrentItem() == 2){
        // Call ReplaceFragment here
    }
    

    inside Activity you need to implement ViewPager OnPageChangeListener. It has onPageSelected method which gives you the position of the page. It will always get called whenever you change your fragment.

    EDIT

    inside onPageSelected

    if (position == 2){
       YourFragment frag  = (YourFragment)adapter.getItem(position)
       frag.callNewFragment()
    }
    

    EDIT 2

    import android.os.Parcelable;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentStatePagerAdapter;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class ViewPagerAdapter extends FragmentStatePagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();
    
    public ViewPagerAdapter(FragmentManager fm) {
        super(fm);
        mFragmentList.clear();
        mFragmentTitleList.clear();
    }
    
    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }
    
    @Override
    public int getCount() {
        return mFragmentList.size();
    }
    
    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }
    
    @Override
    public Parcelable saveState() {
        return null;
    }
    
    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
    }
    

    and then add fragment like below:

    adapter.addFragment(new SpeedTestFragment(), "Speed Test");
    
    // add all 11 like above
    adapter.notifyDataSetChanged();