An efficient TabLayout library implemented with RecyclerView.

Overview

RecyclerTabLayout

Android Arsenal

An efficient TabLayout library implemented with RecyclerView.

Features

  • Efficient when having many tabs
  • Easy setup with ViewPager (same as TabLayout of Android Design Support Library)
  • RTL layout support

UseCase

  • Many tabs layout
  • Infinite loop scrolling (imitated)

Demos

Years

Loop

Basic

Icon

Samples

Getting started

In your build.gradle:

repositories {
    jcenter()
}

dependencies {
   compile 'com.nshmura:recyclertablayout:1.5.0'
}

Define RecyclerTabLayout in xml layout with custom attributes.

<com.nshmura.recyclertablayout.RecyclerTabLayout
        android:id="@+id/recycler_tab_layout"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        rtl_tabIndicatorColor="?attr/colorAccent"
        rtl_tabIndicatorHeight="2dp"
        rtl_tabBackground="?attr/selectableItemBackground"
        rtl_tabTextAppearance="@android:style/TextAppearance.Small"
        rtl_tabSelectedTextColor="?android:textColorPrimary"
        rtl_tabMinWidth="72dp"
        rtl_tabMaxWidth="264dp"
        rtl_tabPaddingStart="12dp"
        rtl_tabPaddingTop="0dp"
        rtl_tabPaddingEnd="12dp"
        rtl_tabPaddingBottom="0dp"
        rtl_tabPadding="0dp"/>

Set up with the ViewPager.

ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
viewPager.setAdapter(adapter);

RecyclerTabLayout recyclerTabLayout = (RecyclerTabLayout) findViewById(R.id.recycler_tab_layout);
recyclerTabLayout.setUpWithViewPager(viewPager);

Or set up with ViewPager and Custom RecyclerView.Adapter that's extends RecyclerTabLayout.Adapter.

ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
viewPager.setAdapter(adapter);

RecyclerTabLayout recyclerTabLayout = (RecyclerTabLayout) findViewById(R.id.recycler_tab_layout);
recyclerTabLayout.setUpWithAdapter(new CustomRecyclerViewAdapter(viewPager));

Here's sample of custom RecyclerView adapter.

public class CustomRecyclerViewAdapter extends RecyclerTabLayout.Adapter<CustomRecyclerViewAdapter.ViewHolder> {

    public DemoCustomView01Adapter(ViewPager viewPager) {
        super(viewPager);
        ...
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // Inflate your view.
        View view = ...;
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // Bind data
        ...
        
        if (position == getCurrentIndicatorPosition()) {
            //Highlight view
        }
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        ...
        
        public ViewHolder(View itemView) {
            super(itemView);
        ...
        }
    }
}

Attributes

attr description
rtl_tabIndicatorColor Indicator color
rtl_tabIndicatorHeight Indicator height
rtl_tabBackground Background drawable of each tab
rtl_tabTextAppearance TextAppearence of each tab
rtl_tabSelectedTextColor Text color of selected tab
rtl_tabOnScreenLimit The number of OnScreen tabs. If this value is larger than 0, rtl_tabMinWidth and rtl_tabMaxWidth are ignored.
rtl_tabMinWidth Minimum width of each tab
rtl_tabMaxWidth Maximum width of each tab
rtl_tabPaddingStart The padding of the start edge of each tab
rtl_tabPaddingTop The padding of the top edge of each tab
rtl_tabPaddingEnd The padding of the end edge of each tab
rtl_tabPaddingBottom The padding of the bottom edge of each tab
rtl_tabPadding The padding of all four edges of each tab
rtl_scrollEnabled Sets whether tab scrolling is enabled

default attribute

Thanks

The demo app uses the following resources.

color-names by codebrainz
https://github.com/codebrainz/color-names

Material Design icons by Google
https://github.com/google/material-design-icons

License

Copyright (C) 2017 nshmura

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Tabs not scrolled on init on support library 23.3.0

    Tabs not scrolled on init on support library 23.3.0

    If you set current pager item that is outside TabLayout (selectedView == null), tabs dont scroll to that item position. This happens when using 23.3.0 support library and only at view initialization. Once you move pager, tabs jump to the correct position.

    Support Library 23.3.0 LinearLayoutManager has a new feature called setAutoMeasureEnabled which is default enabled. This seems to cause this issue on init.

    The solution is to set it to false in the RecyclerTabLayout constructor when setting LinearLayoutManager.

           /.../
            mIndicatorPaint = new Paint();
            mLinearLayoutManager = new LinearLayoutManager(getContext());
            mLinearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
            mLinearLayoutManager.setAutoMeasureEnabled(false);
            setLayoutManager(mLinearLayoutManager);
            setItemAnimator(null);
            /.../
    
    opened by gregacucnik 7
  • Was there any possible load image Picasso or Glide Recycler Tablayout ?

    Was there any possible load image Picasso or Glide Recycler Tablayout ?

    I have following the example of customview01 by using the this DemoCustomView01Activity.class then in adapter DemoCustomView01Adapter which I used picasso to load image by Picasso.with(context).load(item.getUrl()).into(holder.image); I think will load image into imageview. But the result it was not..anybody can help me about this one please

    opened by araurangel 3
  • requestLayout() improperly called

    requestLayout() improperly called

    I am getting this warning , may be you want to look at it

    W/View: requestLayout() improperly called by com.nshmura.recyclertablayout.RecyclerTabLayout{10a88d34 VFED.... ......ID 30,0-1050,144 #7f0e0093 app:id/recycler_tab_layout} during layout: running second layout pass

    Android SDK : 24.0.1

    opened by HashirLabs 2
  • handle NO_POSITION when clicked

    handle NO_POSITION when clicked

    getAdapterPosition() may return NO_POSITION which will cause scrolling to position 0

    see: http://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder.html#getAdapterPosition%28%29

    opened by iodragon 2
  • Text Size

    Text Size

    Hi. I have tried to change text size of each tab. How can I chance it?.

    Here my code. I thought I can set it through "tabTextAppearance". But it did not affect :(

    android:id="@+id/home_screen_recycler_tab_layout" android:layout_width="match_parent" android:layout_height="50dp" android:background="@color/engly_light_purple" app:rtl_tabIndicatorColor="@color/subtitle_dark_purple" app:rtl_tabIndicatorHeight="50dp" app:rtl_tabSelectedTextColor="@color/white" app:rtl_tabTextAppearance="@dimen/home_screen_home_catagories"

    opened by zulfuadar 1
  • Any way to center tabs?

    Any way to center tabs?

    I have a RecyclerTabLayout with only two tabs and texts not too long. I'd like to know if it's possible to center-align tabs, since right now they appear left aligned

    opened by amanzan 1
  • How to Change text color of unselected tabs

    How to Change text color of unselected tabs

    Hello, I'm using this infinite loop demo. And I want to change unselected tab text color. I know that there is an attribute called "rtl_tabSelectedTextColor". Is there something to achieve this?

    opened by DaurenD 1
  • Lag when switching from last tab

    Lag when switching from last tab

    I currently use the loop method to infinitely scroll through tabs. It all works fine when I switch between fragments when swiping the viewpager itself, however, when I switch from the last to the first tab or the last to the previous tab by clicking on the tabs in the RecyclerTabLayout, some lag occurs.

    opened by JelleBlaauw 1
  • Stop scrolling before scrolling to tab

    Stop scrolling before scrolling to tab

    Problem

    I think RecyclerTabLayout should stop scrolling when swiping ViewPager to next page, but it doesn't stop.

    Solution

    call stopScroll() in RecyclerTabLayout#scrollToTab(int position, float positionOffset, boolean fitIndicator)

    Result

    Before

    ### After
    opened by takuaraki 1
  • CrashHandler: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/internal/widget/TintManager;

    CrashHandler: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/internal/widget/TintManager;

    06-29 10:47:50.354 23962-23962/cn.com.kpcq.xunjian.jinan E/CrashHandler: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/internal/widget/TintManager; at com.nshmura.recyclertablayout.RecyclerTabLayout$DefaultAdapter.onCreateViewHolder(RecyclerTabLayout.java:479) at com.nshmura.recyclertablayout.RecyclerTabLayout$DefaultAdapter.onCreateViewHolder(RecyclerTabLayout.java:435)

    line 479

    if (mTabBackgroundResId != 0) { tabTextView.setBackgroundDrawable( 479 TintManager.getDrawable(tabTextView.getContext(), mTabBackgroundResId)); }

    opened by ghost 1
  • Fix

    Fix "Invalid indicator position"

    Sometimes when I change position of ViewPager I see that current tab at RecyclerTabLayout stay the same. I've figure out after some debugging where is problem. See at method updateCurrentIndicatorPosition. This method don't change adapter's indicatorPosition if dx is 0. So RecyclerTabLayout's position and ViewPager's position do not match. My commit fix this issue. I am comparing not only dx but position to be know we need call notifyDataSetChanged.

    Closes https://github.com/nshmura/RecyclerTabLayout/issues/49

    opened by rt1shnik 0
  • Invalid indicator position

    Invalid indicator position

    Sometimes when I change position of ViewPager I see that current tab at RecyclerTabLayout stay the same. I've figure out after some debugging where is problem. See at method updateCurrentIndicatorPosition. This method don't change adapter's indicatorPosition if dx is 0. So RecyclerTabLayout's position and ViewPager's position do not match.
    https://github.com/nshmura/RecyclerTabLayout/blob/16e414044ea79d984a2c3c9848cd029f29ae5587/library/src/main/java/com/nshmura/recyclertablayout/RecyclerTabLayout.java#L310-L325

    opened by rt1shnik 0
  • Initial tab indicator is wrong with FragmentStatePagerAdapter

    Initial tab indicator is wrong with FragmentStatePagerAdapter

    Initial tab position (use getCenterPosition() ) works fine, but initial tab indicator is wrong, indicates previous one.

    with RecyclerTabLayout v1.3.0 and FragmentStatePagerAdapter. ( v1.2.0 or previous versions, works fine)

    Thanks.

    opened by alpha2048 0
  • android.view.InflateException: Binary XML file line #19: Binary XML file line #19

    android.view.InflateException: Binary XML file line #19: Binary XML file line #19

    android.view.InflateException: Binary XML file line #19: Binary XML file line #19: Error inflating class com.nshmura.recyclertablayout.RecyclerTabLayout Caused by: android.view.InflateException: Binary XML file line #19: Error inflating class com.nshmura.recyclertablayout.RecyclerTabLayout Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Constructor.newInstance0(Native Method) at java.lang.reflect.Constructor.newInstance(Constructor.java:343) at android.view.LayoutInflater.createView(LayoutInflater.java:647) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:790) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730) at android.view.LayoutInflater.rInflate(LayoutInflater.java:863) at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824) at android.view.LayoutInflater.rInflate(LayoutInflater.java:866) at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824) at android.view.LayoutInflater.inflate(LayoutInflater.java:515) at android.view.LayoutInflater.inflate(LayoutInflater.java:423) at com.hyphenate.chatuidemo.ui.PacketsFragment.onCreateView(PacketsFragment.java:50) at android.support.v4.app.Fragment.performCreateView(Fragment.java:2343) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1419) at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740) at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:794) at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2580) at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367) at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2229) at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3221) at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3171) at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:192) at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:552) at com.hyphenate.chatuidemo.ui.BaseActivity.onStart(BaseActivity.java:36) at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1391) at android.app.Activity.performStart(Activity.java:7157) at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2937) at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180) at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) Caused by: java.lang.UnsupportedOperationException: Failed to resolve attribute at index 2: TypedValue{t=0x2/d=0x7f03004d a=4} at android.content.res.TypedArray.getColor(TypedArray.java:477) at com.nshmura.recyclertablayout.RecyclerTabLayout.getAttributes(RecyclerTabLayout.java:101) at com.nshmura.recyclertablayout.RecyclerTabLayout.(RecyclerTabLayout.java:85) at com.nshmura.recyclertablayout.RecyclerTabLayout.(RecyclerTabLayout.java:78)

    the line 19 is "<com.nshmura.recyclertablayout.RecyclerTabLayout"

    opened by MP4Four 4
Owner
Shinichi Nishimura
Backend Software Engineer
Shinichi Nishimura
Memory efficient android library for managing individual fragment backstack.

fragstack : Android library for managing individual fragment backstack. An Easy to use library for managing individual fragment back stack as Instagra

Abhishesh 21 Feb 6, 2021
Ahmad Shahwaiz 1 Jan 26, 2022
Android Navigation Fragment Share Element Example: Use Share Element Transition with recyclerView Item and ViewPager2 Item.

Android-Navigation-Fragment-Share-Element-Example 说明 Android 使用Navigation导航切换Fragment中使用共享元素过渡动画的例子:将在listFragment的RecyclerView的Item共享元素过渡到pagerFragme

null 3 Sep 28, 2022
🎉 [Android Library] A light-weight library to easily make beautiful Navigation Bar with ton of 🎨 customization option.

Bubble Navigation ?? A light-weight library to easily make beautiful Navigation Bars with a ton of ?? customization options. Demos FloatingTopBarActiv

Gaurav Kumar 1.7k Dec 31, 2022
An Android library that allows you to easily create applications with slide-in menus. You may use it in your Android apps provided that you cite this project and include the license in your app. Thanks!

SlidingMenu (Play Store Demo) SlidingMenu is an Open Source Android library that allows developers to easily create applications with sliding menus li

Jeremy Feinstein 11.1k Dec 27, 2022
Android Library for making animated tutorials inside your app

##SlidingTutorial Cleveroad introduces Sliding Tutorial Library for Android Hey guys, hope you haven’t started developing a tutorial for your Android

Cleveroad 2.5k Dec 31, 2022
Paging indicator widgets compatible with the ViewPager from the Android Support Library and ActionBarSherlock.

Android ViewPagerIndicator Paging indicator widgets that are compatible with the ViewPager from the Android Support Library to improve discoverability

Jake Wharton 10.2k Dec 26, 2022
The flexible, easy to use, all in one drawer library for your Android project. Now brand new with material 2 design.

MaterialDrawer ... the flexible, easy to use, all in one drawer library for your Android project. What's included ?? • Setup ??️ • Migration Guide ??

Mike Penz 11.6k Dec 27, 2022
An Android library for managing multiple stacks of fragments

FragNav Android library for managing multiple stacks of fragments (e.g., Bottom Navigation , Navigation Drawer). This library does NOT include the UI

Nic Capdevila 1.5k Jan 6, 2023
A flexible, easy to use, unique drawer library for your Android project.

Duo Navigation Drawer This Android library provides an easy way to create an alternative navigation drawer for android. Instead of a drawer that slide

PSD 1.1k Dec 21, 2022
Alligator is a modern Android navigation library that will help to organize your navigation code in clean and testable way.

Alligator Alligator is a modern Android navigation library that will help to organize your navigation code in clean and testable way. Features Any app

Artur Artikov 290 Dec 9, 2022
This library will help to show the polyline in dual color similar as Uber.

Dual-color-Polyline-Animation This library will help to show the polyline in dual color similar as Uber with animation in the demo. Demo Steps: Pass t

Pritam Dasgupta 75 Nov 23, 2022
A sleek, out of the box, easy to understand and use, swipe gesture based Navigational Library for android.

Facilis Swipe gesture based navigational library for Android. Watch Demo Video: Getting Started To get this project into your build: Gradle Add it in

Prem Suman 35 Feb 15, 2022
🛸Voyager is a pragmatic navigation library built for, and seamlessly integrated with, Jetpack Compose.

Voyager is a pragmatic navigation library built for, and seamlessly integrated with, Jetpack Compose.

Adriel Café 831 Dec 26, 2022
A small navigation library for Android to ease the use of fragment transactions & handling backstack (also available for Jetpack Compose).

A small navigation library for Android to ease the use of fragment transactions & handling backstack (also available for Jetpack Compose).

Kaustubh Patange 88 Dec 11, 2022
A simple navigation library for Android 🗺️

Enro ??️ A simple navigation library for Android "The novices’ eyes followed the wriggling path up from the well as it swept a great meandering arc ar

Isaac Udy 216 Dec 16, 2022
A lightweight library to help you navigate in compose with well typed functions.

TypedNavigation A lightweight library to help you navigate in compose with well typed functions. Installation: You can add this library to your projec

xmartlabs 23 Apr 7, 2022
[ACTIVE] Simple Stack, a backstack library / navigation framework for simpler navigation and state management (for fragments, views, or whatevers).

Simple Stack Why do I want this? To make navigation to another screen as simple as backstack.goTo(SomeScreen()), and going back as simple as backstack

Gabor Varadi 1.3k Jan 2, 2023
A library that you can use for bottom navigation bar. Written with Jetpack Compose

FancyBottomNavigationBar A library that you can use for bottom navigation bar. W

Alperen Çevlik 3 Jul 27, 2022