Swiping between fragments in TabLayout goes slow

android swipe view example
android viewpager with tabs
android tabs

I have a TabLayout is set up with viewpager. The viewpager is set up with adapter. There are 11 fragments were added to adapter and each fragment has a recyclerview. When I run the app swiping between fragments goes slow. Can anyone tell me the reason of this issue?

my MainActivity:

    myTabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);


    mainViewPager = (ViewPager) findViewById(R.id.mainViewPager);
    tabLayoutAdapter = new TabLayoutAdapter(getSupportFragmentManager());
    tabLayoutAdapter.addFragment(new HomeFragment());
    tabLayoutAdapter.addFragment(new ClipFragment());
    tabLayoutAdapter.addFragment(new MovieFragment());
    tabLayoutAdapter.addFragment(new SerialFragment());
    tabLayoutAdapter.addFragment(new MusicFragment());
    tabLayoutAdapter.addFragment(new BookFragment());
    tabLayoutAdapter.addFragment(new PixFragment());
    tabLayoutAdapter.addFragment(new GameFragment());
    tabLayoutAdapter.addFragment(new NewsFragment());
    tabLayoutAdapter.addFragment(new LiveFragment());
    tabLayoutAdapter.addFragment(new AdvancedSearchFragment());
    mainViewPager.setAdapter(tabLayoutAdapter);
    myTabLayout.setupWithViewPager(mainViewPager);

my adapter:

public class TabLayoutAdapter extends FragmentStatePagerAdapter {
List<Fragment> tabPages = new ArrayList<>();

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

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

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

public void addFragment(Fragment page){
    tabPages.add(page);
}

}

sample fragment:

public class MovieFragment extends Fragment {
RecyclerView movieRecyclerView;
List<Movie> movieList;
MovieAdapter movieAdapter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.d("Fragment", "thread = " + Thread.currentThread().getName());
    Log.i("Fragment", "thread = " + Thread.currentThread().getName());
}


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


    View movieView = inflater.inflate(R.layout.tab_movie, container, false);
    return movieView;
}


@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    movieRecyclerView = (RecyclerView) view.findViewById(R.id.movieRecyclerView);
    movieList = new ArrayList<Movie>();
    movieAdapter = new MovieAdapter(view.getContext(), movieList);

    RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(view.getContext(), 2);
    movieRecyclerView.setLayoutManager(mLayoutManager);
    movieRecyclerView.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(10), false));
    movieRecyclerView.setItemAnimator(new DefaultItemAnimator());
    movieRecyclerView.setAdapter(movieAdapter);

    prepareMovies();



}

public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {

    private int spanCount;
    private int spacing;
    private boolean includeEdge;

    public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {
        this.spanCount = spanCount;
        this.spacing = spacing;
        this.includeEdge = includeEdge;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        int position = parent.getChildAdapterPosition(view); // item position
        int column = position % spanCount; // item column

        if (includeEdge) {
            outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)
            outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)

            if (position < spanCount) { // top edge
                outRect.top = spacing;
            }
            outRect.bottom = spacing; // item bottom
        } else {
            outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)
            outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f /    spanCount) * spacing)
            if (position >= spanCount) {
                outRect.top = spacing; // item top
            }
        }
    }
}



private void prepareMovies() {
    int[] covers = new int[]{
            R.drawable.bossbaby,
            R.drawable.abeautifulmind,
            R.drawable.despicableme,
            R.drawable.harrypotter,
            R.drawable.thegodfather,
            R.drawable.piratesofcaribbean,
            };

    Movie movie = new Movie("Boss Baby",10000,4.5,20000,16000, covers[0]);
    movieList.add(movie);
    movie = new Movie("A Beautiful mind",35100,4.9,40000,39000, covers[1]);
    movieList.add(movie);
    movie = new Movie("Despicable me",20000,4.7,33000,31000, covers[2]);
    movieList.add(movie);
    movie = new Movie("Harry Potter",90000,5.0,110000,105000, covers[3]);
    movieList.add(movie);
    movie = new Movie("The God Father",70000,4.9,90000,86700, covers[4]);
    movieList.add(movie);
    movie = new Movie("Pirates of caribbean",50000,4.6,70000,64000, covers[5]);
    movieList.add(movie);



    movieAdapter.notifyDataSetChanged();
}

private int dpToPx(int dp) {
    Resources r = getResources();
    return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
}

}


When you have many fragments and want to have optimization in its animation and interaction, then you can use viewpager.setOffscreenPageLimit(int numberOfPages);

setOffscreenPageLimit() will have default value 1 i.e viewpager will load only one page(fragment) on its either side and other pages will be recreated from the adapter when scrolled and hence it lags based on operations that page will do. So when you know the number of pages then using this method will help in smoothness of paging animations and interaction.

From Doc setOffscreenPageLimit()

Set the number of pages that should be retained to either side of the current page in the view hierarchy in an idle state. Pages beyond this limit will be recreated from the adapter when needed.

This is offered as an optimization. If you know in advance the number of pages you will need to support or have lazy-loading mechanisms in place on your pages, tweaking this setting can have benefits in perceived smoothness of paging animations and interaction. If you have a small number of pages (3-4) that you can keep active all at once, less time will be spent in layout for newly created view subtrees as the user pages back and forth

Refresh Fragment at reload, An adapter handles all the transactions between different Fragments. This way Step 6: Go to MainActivity and find the TabLayout . Then call  8 Swiping between fragments in TabLayout goes slow Aug 21 '18 6 Duplication in Checkbox selection in RecyclerView Oct 26 '17 5 FileProvider is very confusing Apr 6 '18


How do disable paging by swiping with finger in ViewPager but still , Using ViewPager to hold your Fragments is a very common pattern on Android. more and more Fragments on your ViewPager, it will slow down your app… Why don't we just inflate the view when the user swipe to that page? There you go, onResume() . Dart Excitement From Kotliner Perspective. If you want to create swipeable views with Tabs, you can combine ViewPager2, TabLayout and Fragments. To use TabLayout, add Material Components to your package. This makes the material TabLayout available in your project. implementation 'com.google.android.material:material:1.2.0-alpha01' Add TabLayout and ViewPage2 to your layout.


Along with @Khemraj answer, try the following also because when we come back to same recyclerview containing class then there are chances of issues regarding viewpager adapter

tabLayoutAdapter = new TabLayoutAdapter(getChildFragmentManager());

instead of

tabLayoutAdapter = new TabLayoutAdapter(getSupportFragmentManager());

How to Use ViewPager for Navigating between Fragments (With , My Activity has swipe-able tabs and each tab calls a different fragment. But when i swipe between tabs the transition seems a quite slow  The following sections show how you can add tabs to help facilitate navigation between pages. Add Tabs Using a TabLayout. A TabLayout provides a way to display tabs horizontally. When used together with a ViewPager2, a TabLayout can provide a familiar interface for navigating between pages in a swipe view. Figure 1: A TabLayout with four tabs.


Try following things to make navigation smoother :

1) on each fragment move code from onViewCreated to onActivityCreated, because it is methods gets called when fragment appeared completely :

 @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        // put code of setting data to views etc.
    }

2) implement following methods in FragmentStateAdapter class :

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
//        super.destroyItem(container, position, object);
    }

    // Force a refresh of the page when a different fragment is displayed
    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

3) Use some low resolution images in your fragment(if you are using them from resource folder). Dont use large resoultion like - 1024*960, try to compress them and then add.

4) Avoid using wrap_content in layout files of fragments. because then it takes time to calculate the width height , If you can provide match_parent or any specific value in dp, it will work much faster.

try these points may be these will help you.

Android Performance, Implement Swipe Views; Add Tabs Using a TabLayout use FragmentStatePagerAdapter to swipe across a collection of Fragment objects:. Slide between fragments using ViewPager Screen slides are transitions between one entire screen to another and are common with UIs like setup wizards or slideshows. This lesson shows you how to do screen slides with a ViewPager provided by the support library .


Android ViewPager and Performance Improvements, This topic teaches you how to create a tab layout with swipe views for Here's how you might use it to swipe across a collection of Fragment  Dismiss Join GitHub today. GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.


Create swipe views with tabs using ViewPager, Layout that allows the user to swipe left and right through "pages" of content which are usually ViewPager with any number of fragments as pages which can be swiped between. See Google Play Style Tabs using TabLayout for a walkthrough. getRegisteredFragment(0); // gets first Fragment item within the pager. Android Tabs with Fragments and ViewPager In android, we can create swipeable tabs layout using Swipe Views to switch between the tabs in the android application. The Swipe Views in android provides navigation between the sibling screens such as tabs with a horizontal finger gesture, sometimes it is called horizontal paging.


Create swipe views with tabs using ViewPager2, However when loading this activity, I get extremely slow on swiping/sliding the viewpager items. Slide between fragments using ViewPager, This navigation pattern is also This topic teaches you how to create a tab layout with swipe views for much diversity when it comes to Android devices and given the varying price  Refactor TabLayout interfaces. ViewPager2 introduces changes to TabLayout integration. If you currently use a ViewPager with a TabLayout object to display horizontal tabs for navigation, you need to refactor the TabLayout object for integration with ViewPager2. TabLayout has been decoupled from ViewPager2 and is now available as part of