Viewpager Fragment 1 onCreateView is not always being called

339 views Asked by At

When I swipe to or select Fragment1 (Fragment Numbers are 0-3) from its adjacent Fragments(0 , 2) in viewPager its onCreateView, or onCreate function is not being called.

But when I swipe back from Fragment3 or select Fragment1 when Fragment3 is active then both of these functions are being called. I am confused about why not from the adjacent Fragments its being called.

this is the code of Fragment who's onCreateView is not being called properly

`public class Fragment1 extends Fragment {

ShimmerFrameLayout shimmerFrameLayout ;
ConstraintLayout contentLayout;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Toast.makeText(getActivity(), "US News", Toast.LENGTH_SHORT).show();
    Log.d("Called", "onCreate: ");
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.us_news_fragment_layout , container , false);
    shimmerFrameLayout = view.findViewById(R.id.usNewsShimmerLayoutId);
    contentLayout = view.findViewById(R.id.usNewsLayoutId);

    shimmerFrameLayout.startShimmerAnimation();

    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
           shimmerFrameLayout.stopShimmerAnimation();
           shimmerFrameLayout.setVisibility(View.GONE);
           contentLayout.setVisibility(View.VISIBLE);
        }
    },3000);
    return view;
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    Log.d("USNews", "onCreateView: ");
}

}`

This is the code in the main Activity for handling the events related to the viewpager

 viewPager = findViewById(R.id.homeViewPagerId);
    tabLayout.setupWithViewPager(viewPager);
    tabLayout.addTab(tabLayout.newTab().setText("Home"));
    tabLayout.addTab(tabLayout.newTab().setText("US News"));
    tabLayout.addTab(tabLayout.newTab().setText("Politics"));
    tabLayout.addTab(tabLayout.newTab().setText("Live"));
    tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
    tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            int position = tab.getPosition();
            viewPager.setCurrentItem(position);
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

    homePagerAdapter = new HomePagerAdapter(getSupportFragmentManager() , tabLayout.getTabCount());
    viewPager.setAdapter(homePagerAdapter);
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

// Toast.makeText(MainActivity.this, String.valueOf(tabLayout.getTabAt(position).getText()) + " is Active Now", Toast.LENGTH_SHORT).show(); homePagerAdapter.getItem(position); }

        @Override
        public void onPageSelected(int position) {
            homePagerAdapter.getItem(position);
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

    homePagerAdapter.notifyDataSetChanged();

And this is the adapter of the ViewPager i am using

public class HomePagerAdapter extends FragmentStatePagerAdapter {
int NUM_OF_TABS;
private String[] tabTitles = new String[]{"Home", "US News", "Politics" , "Live"};
public HomePagerAdapter(@NonNull FragmentManager fm , int numberOfTabs) {
    super(fm);
    this.NUM_OF_TABS = numberOfTabs;
}

@Nullable
@Override
public CharSequence getPageTitle(int position) {
    return tabTitles[position];
}

@NonNull
@Override
public Fragment getItem(int position) {
    switch (position){
        case 0:
            Fragment0 homeFragment = new Fragment0 ();
            return  homeFragment;
        case 1:
            Fragment1 usNewsFragment = new Fragment1 ();
            return usNewsFragment;
        case 2:
            Fragment2 politicsFragment = new Fragment2 ();
            return politicsFragment;
        case 3:
            Fragment3 liveFragment = new Fragment3 ();
            return  liveFragment;
        default:
            return null;
    }
}

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

}

Please assist me about this. I'll be very thankful to you.

Thanks in advance

1

There are 1 answers

8
snachmsm On

maybe this layout is already created and drawn? ViewPager have some handy option - keeps at least two additional Views/Fragments in memory for fast switching between pages. you can change this value to some higher only by calling setOffscreenPageLimit. by default its set to 1 - means that ViewPager keeps up to 3 Fragments - one to the left, one to the right and one currently visible on screen. with finger fling UI can just slide left/right page without drawing it from scratch (making almost always some small glitch/hang)

I bet you have two onCreate calls on start of your Activity - Fragment0s and Fragment1s. when you switch to Fragment1 you will see Fragment2 log, as ViewPager will prepare it for potential next swipe-left gesture. you can always use setOffscreenPageLimit(Integer.MAX_VALUE); for forcing all Fragments to be drawn at start and kept in memory (but only if these Fragments aren't to heavy, according to your tab names they might be...)

also homePagerAdapter.getItem(position); call in onPageSelected and onPageScrolled is unnecessary - it is creating new Frament and returning it, thats all, it isn't used. thats ViewPagers job to call this method (from attached adapter), take this Fragment and draw (on the screen or just render in memory for potential future use when user swipe left/right)