Full Code of ogaclejapan/SmartTabLayout for AI

master 712e81a92f1e cached
95 files
171.7 KB
45.8k tokens
261 symbols
1 requests
Download .txt
Repository: ogaclejapan/SmartTabLayout
Branch: master
Commit: 712e81a92f1e
Files: 95
Total size: 171.7 KB

Directory structure:
gitextract_8nyfmi02/

├── .gitignore
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── README.md
├── build.gradle
├── demo/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── ogaclejapan/
│           │           └── smarttablayout/
│           │               └── demo/
│           │                   ├── Demo.java
│           │                   ├── DemoActivity.java
│           │                   ├── DemoFragment.java
│           │                   ├── DemoLikeMediumActivity.java
│           │                   ├── DemoRtlActivity.java
│           │                   ├── DemoTabWithNotificationMarkActivity.java
│           │                   ├── MainActivity.java
│           │                   └── TintableImageView.java
│           └── res/
│               ├── color/
│               │   ├── custom_tab.xml
│               │   ├── custom_tab_icon.xml
│               │   └── custom_tab_like_a_medium.xml
│               ├── drawable/
│               │   ├── custom_circle.xml
│               │   ├── custom_icon.xml
│               │   ├── custom_tab.xml
│               │   └── shape_notification_mark.xml
│               ├── layout/
│               │   ├── activity_demo.xml
│               │   ├── activity_demo_tab_with_notification_mark.xml
│               │   ├── activity_like_a_medium.xml
│               │   ├── activity_main.xml
│               │   ├── activity_rtl.xml
│               │   ├── custom_tab.xml
│               │   ├── custom_tab_circle.xml
│               │   ├── custom_tab_icon1.xml
│               │   ├── custom_tab_icon2.xml
│               │   ├── custom_tab_icon_and_notification_mark.xml
│               │   ├── custom_tab_icon_and_text.xml
│               │   ├── custom_tab_like_a_medium.xml
│               │   ├── custom_tab_margin.xml
│               │   ├── demo_always_in_center.xml
│               │   ├── demo_basic.xml
│               │   ├── demo_basic_title_offset_auto_center.xml
│               │   ├── demo_custom_tab_colors.xml
│               │   ├── demo_custom_tab_icon_and_notification_mark.xml
│               │   ├── demo_custom_tab_icon_and_text.xml
│               │   ├── demo_custom_tab_icons1.xml
│               │   ├── demo_custom_tab_icons2.xml
│               │   ├── demo_custom_tab_margin.xml
│               │   ├── demo_custom_tab_text.xml
│               │   ├── demo_distribute_evenly.xml
│               │   ├── demo_indicator_trick1.xml
│               │   ├── demo_indicator_trick2.xml
│               │   ├── demo_like_a_medium_tag.xml
│               │   ├── demo_rtl.xml
│               │   ├── demo_smart_indicator.xml
│               │   └── fragment_demo.xml
│               ├── menu/
│               │   ├── menu_demo.xml
│               │   └── menu_main.xml
│               └── values/
│                   ├── attrs.xml
│                   ├── colors.xml
│                   ├── dimens.xml
│                   ├── ids.xml
│                   ├── strings.xml
│                   └── styles.xml
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── library/
│   ├── .gitignore
│   ├── LICENSE
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── ogaclejapan/
│           │           └── smarttablayout/
│           │               ├── SmartTabIndicationInterpolator.java
│           │               ├── SmartTabLayout.java
│           │               ├── SmartTabStrip.java
│           │               └── Utils.java
│           └── res/
│               └── values/
│                   └── attrs.xml
├── publish.gradle
├── settings.gradle
└── utils-v4/
    ├── .gitignore
    ├── LICENSE
    ├── build.gradle
    ├── proguard-rules.pro
    └── src/
        └── main/
            ├── AndroidManifest.xml
            └── java/
                └── com/
                    └── ogaclejapan/
                        └── smarttablayout/
                            └── utils/
                                ├── PagerItem.java
                                ├── PagerItems.java
                                ├── ViewPagerItem.java
                                ├── ViewPagerItemAdapter.java
                                ├── ViewPagerItems.java
                                └── v4/
                                    ├── Bundler.java
                                    ├── FragmentPagerItem.java
                                    ├── FragmentPagerItemAdapter.java
                                    ├── FragmentPagerItems.java
                                    └── FragmentStatePagerItemAdapter.java

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# https://github.com/github/gitignore
# https://github.com/hsz/idea-gitignore


### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm

*.iml

## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:

# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries

# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml

# Gradle:
# .idea/gradle.xml
# .idea/libraries

# Mongo Explorer plugin:
# .idea/mongoSettings.xml

## File-based project format:
*.ipr
*.iws

## Plugin-specific files:

# IntelliJ
/out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties


### Android template
# Built application files
*.apk
*.ap_

# Files for the Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/

# Gradle files
.gradle/
build/
/*/build/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log



================================================
FILE: CHANGELOG.md
================================================
# Version 2.0.0

* Migrate to androidx 1.0.0
* Remove util-v13 library

# Version 1.7.0

* Update support library version to 28.0.0
* Change target sdk version to 28
* Change min sdk version to 14
* Deprecated util-v13 library

# Version 1.6.1

* Fixed issue with center last item in always in center tablayout #160

# Version 1.6.0

* Add `stl_indicatorWidth` to custom indicator's width #106

# Version 1.5.1

* Fixed indicator position of auto_center #100

# Version 1.5.0

* Add `stl_drawDecorationAfterTab` attribute for change the drawing order #58
* Add `stl_titleOffset` attribute for adjust the slide position #89
* Fixed a condition code of onSizeChanged for always in center

# Version 1.4.2

* Change the call order of OnTabClickListener when press the tab #74

# Version 1.4.1

* Update android support library version to 22.2.1

# Version 1.4.0

* Add TabClickListener interface #68

# Version 1.3.0

* RTL support #48
* Add `stl_clickable` attribute.

# Version 1.2.3

* Modify to ensure the first scroll #54

# Version 1.2.2

* Fix bug when indicatorAlwaysInCenter is true and tabHost has only two tabs #50

# Version 1.2.1

* Add custom ScrollListener interface #46

# Version 1.2.0

* Support the margin of each tab.
* Add `stl_indicatorWithoutPadding` and `stl_indicatorGravity` attributes.
* Add `stl_overlineColor` and `stl_overlineThickness` attributes.

# Version 1.1.3

* Allow to set the background on default tab #13

# Version 1.1.2

* Added setter for tab text colors #10
* Allow to set a String title dynamically on PagerItems. #7

# Version 1.1.1

* Enable the format of ‘reference’ for defaultTextColor to support ColorStateList #3

# Version 1.1.0

* Supported Icon Tab. #1


# Version 1.0.0

* Initial release.


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

If you would like to contribute code to SmartTabLayout you can do so through GitHub by
forking the repository and sending a pull request.

When submitting code, please make every effort to follow existing conventions
and style in order to keep the code as readable as possible.

## Coding Style

* Use the AndroidModernStyle of [Android Code Styles](https://github.com/ogaclejapan/android-code-styles) repository


================================================
FILE: LICENSE.txt
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright (C) 2015 ogaclejapan
   Copyright (C) 2013 The Android Open Source Project

   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.


================================================
FILE: README.md
================================================
# SmartTabLayout
[![Maven Central][maven_central_badge_svg]][maven_central_badge_app] [![Android Arsenal][android_arsenal_badge_svg]][android_arsenal_badge_link] [![Android Weekly][android_weekly_badge_svg]][android_weekly_badge_link]

![icon][demo_icon]

A custom ViewPager title strip which gives continuous feedback to the user when scrolling.

This library has been added some features and utilities based on [android-SlidingTabBasic][google_slidingtabbasic] project of Google Samples.


![SmartTabLayout Demo1][demo1_gif] ![SmartTabLayout Demo2][demo2_gif]
![SmartTabLayout Demo3][demo3_gif] ![SmartTabLayout Demo4][demo4_gif]
![SmartTabLayout Demo5][demo5_gif] ![SmartTabLayout Demo6][demo6_gif]
![SmartTabLayout Demo7][demo7_gif]


Try out the sample application on the Play Store.

[![Get it on Google Play][googleplay_store_badge]][demo_app]


# Usage

_(For a working implementation of this project see the demo/ folder.)_

Add the dependency to your build.gradle.

```
// For androidx (1.0.0)
dependencies {
    compile 'com.ogaclejapan.smarttablayout:library:2.0.0@aar'

    //Optional: see how to use the utility.
    compile 'com.ogaclejapan.smarttablayout:utils-v4:2.0.0@aar'
}

// For legacy android support library (28.0.0)
dependencies {
    compile 'com.ogaclejapan.smarttablayout:library:1.7.0@aar'

    //Optional: see how to use the utility.
    compile 'com.ogaclejapan.smarttablayout:utils-v4:1.7.0@aar'

    //Deprecated since 1.7.0
    compile 'com.ogaclejapan.smarttablayout:utils-v13:1.7.0@aar'
}
```

Include the SmartTabLayout widget in your layout.
This should usually be placed above the ViewPager it represents.

```xml

<com.ogaclejapan.smarttablayout.SmartTabLayout
    android:id="@+id/viewpagertab"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    app:stl_indicatorAlwaysInCenter="false"
    app:stl_indicatorWithoutPadding="false"
    app:stl_indicatorInFront="false"
    app:stl_indicatorInterpolation="smart"
    app:stl_indicatorGravity="bottom"
    app:stl_indicatorColor="#40C4FF"
    app:stl_indicatorThickness="4dp"
    app:stl_indicatorWidth="auto"
    app:stl_indicatorCornerRadius="2dp"
    app:stl_overlineColor="#4D000000"
    app:stl_overlineThickness="0dp"
    app:stl_underlineColor="#4D000000"
    app:stl_underlineThickness="1dp"
    app:stl_dividerColor="#4D000000"
    app:stl_dividerThickness="1dp"
    app:stl_defaultTabBackground="?attr/selectableItemBackground"
    app:stl_defaultTabTextAllCaps="true"
    app:stl_defaultTabTextColor="#FC000000"
    app:stl_defaultTabTextSize="12sp"
    app:stl_defaultTabTextHorizontalPadding="16dp"
    app:stl_defaultTabTextMinWidth="0dp"
    app:stl_distributeEvenly="false"
    app:stl_clickable="true"
    app:stl_titleOffset="24dp"
    app:stl_drawDecorationAfterTab="false"
    />

<androidx.viewpager.widget.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/viewpagertab"
    />

```

In your onCreate method (or onCreateView for a fragment), bind the widget to the ViewPager.
(If you use a utility together, you can easily add items to PagerAdapter)

e.g. ViewPager of v4.Fragment

```java

FragmentPagerItemAdapter adapter = new FragmentPagerItemAdapter(
        getSupportFragmentManager(), FragmentPagerItems.with(this)
        .add(R.string.titleA, PageFragment.class)
        .add(R.string.titleB, PageFragment.class)
        .create());

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

SmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpagertab);
viewPagerTab.setViewPager(viewPager);

```

(Optional) If you use an OnPageChangeListener with your view pager you should set it in the widget rather than on the pager directly.


```java

viewPagerTab.setOnPageChangeListener(mPageChangeListener);

```

(Optional) Using the FragmentPagerItemAdapter of utility, you will be able to get a position in the Fragment side.

```java

int position = FragmentPagerItem.getPosition(getArguments());

```

This position will help to implement the parallax scrolling header that contains the ViewPager :P

# Attributes

There are several attributes you can set:

| attr | description |
|:---|:---|
| stl_indicatorAlwaysInCenter | If set to true, active tab is always displayed in center (Like Newsstand google app), default false |
| stl_indicatorWithoutPadding | If set to true, draw the indicator without padding of tab, default false |
| stl_indicatorInFront | Draw the indicator in front of the underline, default false |
| stl_indicatorInterpolation | Behavior of the indicator: 'linear' or 'smart' |
| stl_indicatorGravity | Drawing position of the indicator: 'bottom' or 'top' or 'center', default 'bottom' |
| stl_indicatorColor | Color of the indicator |
| stl_indicatorColors | Multiple colors of the indicator, can set the color for each tab |
| stl_indicatorThickness | Thickness of the indicator |
| stl_indicatorWidth | Width of the indicator, default 'auto' |
| stl_indicatorCornerRadius | Radius of rounded corner the indicator |
| stl_overlineColor | Color of the top line |
| stl_overlineThickness | Thickness of the top line |
| stl_underlineColor | Color of the bottom line |
| stl_underlineThickness | Thickness of the bottom line |
| stl_dividerColor | Color of the dividers between tabs |
| stl_dividerColors | Multiple colors of the dividers between tabs, can set the color for each tab |
| stl_dividerThickness | Thickness of the divider |
| stl_defaultTabBackground | Background drawable of each tab. In general it set the StateListDrawable |
| stl_defaultTabTextAllCaps | If set to true, all tab titles will be upper case, default true |
| stl_defaultTabTextColor | Text color of the tab that was included by default |
| stl_defaultTabTextSize | Text size of the tab that was included by default |
| stl_defaultTabTextHorizontalPadding | Text layout padding of the tab that was included by default |
| stl_defaultTabTextMinWidth | Minimum width of tab |
| stl_customTabTextLayoutId | Layout ID defined custom tab. If you do not specify a layout, use the default tab |
| stl_customTabTextViewId | Text view ID in a custom tab layout. If you do not define with customTabTextLayoutId, does not work |
| stl_distributeEvenly | If set to true, each tab is given the same weight, default false |
| stl_clickable | If set to false, disable the selection of a tab click, default true |
| stl_titleOffset | If set to 'auto_center', the slide position of the tab in the middle it will keep to the center. If specify a dimension it will be offset from the left edge, default 24dp |
| stl_drawDecorationAfterTab | Draw the decoration(indicator and lines) after drawing of tab, default false |

*__Notes:__ Both 'stl_indicatorAlwaysInCenter' and 'stl_distributeEvenly' if it is set to true, it will throw UnsupportedOperationException.*

# How to customize the tab

The customization of tab There are three ways.

* Customize the attribute
* SmartTabLayout#setCustomTabView(int layoutResId, int textViewId)
* SmartTabLayout#setCustomTabView(TabProvider provider)

If set the TabProvider, can build a view for each tab.

```java

public class SmartTabLayout extends HorizontalScrollView {

    //...

    /**
     * Create the custom tabs in the tab layout. Set with
     * {@link #setCustomTabView(com.ogaclejapan.smarttablayout.SmartTabLayout.TabProvider)}
     */
    public interface TabProvider {

        /**
         * @return Return the View of {@code position} for the Tabs
         */
        View createTabView(ViewGroup container, int position, PagerAdapter adapter);

    }

    //...
}

```

# How to use the utility

Utility has two types available to suit the Android support library.

* utils-v4 library contains the PagerAdapter implementation class for _androidx.fragment.app.Fragment_
* (Deprecated) utils-v13 library contains the PagerAdapter implementation class for _android.app.Fragment_

The two libraries have different Android support libraries that depend,
but implemented functionality is the same.

## PagerAdapter for View-based Page

```java

ViewPagerItemAdapter adapter = new ViewPagerItemAdapter(ViewPagerItems.with(this)
        .add(R.string.title, R.layout.page)
        .add("title", R.layout.page)
        .create());

viewPager.setAdapter(adapter);

//...

public void onPageSelected(int position) {

  //.instantiateItem() from until .destroyItem() is called it will be able to get the View of page.
  View page = adapter.getPage(position);

}


```

## PagerAdapter for Fragment-based Page

Fragment-based PagerAdapter There are two implementations.
Please differences refer to the library documentation for Android.

* FragmentPagerItemAdapter extends FragmentPagerAdapter
* FragmentStatePagerItemAdapter extends FragmentStatePagerAdapter

```java

FragmentPagerItemAdapter adapter = new FragmentPagerItemAdapter(
        getSupportFragmentManager(), FragmentPagerItems.with(this)
        .add(R.string.title, PageFragment.class),
        .add(R.string.title, WithArgumentsPageFragment.class, new Bundler().putString("key", "value").get()),
        .add("title", PageFragment.class)
        .create());

viewPager.setAdapter(adapter);

//...

public void onPageSelected(int position) {

  //.instantiateItem() from until .destoryItem() is called it will be able to get the Fragment of page.
  Fragment page = adapter.getPage(position);

}

```

*__Notes:__ If using fragment inside a ViewPager, Must be use [Fragment#getChildFragmentManager()](https://developer.android.com/reference/androidx/fragment/app/Fragment.html#getChildFragmentManager).*


# Looking for iOS ?
 Check [WormTabStrip](https://github.com/EzimetYusup/WormTabStrip) out.
 
# LICENSE

```
Copyright (C) 2015 ogaclejapan
Copyright (C) 2013 The Android Open Source Project

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.
```

[demo1_gif]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/demo1.gif
[demo2_gif]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/demo2.gif
[demo3_gif]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/demo3.gif
[demo4_gif]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/demo4.gif
[demo5_gif]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/demo5.gif
[demo6_gif]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/demo6.gif
[demo7_gif]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/demo7.gif
[demo_app]: https://play.google.com/store/apps/details?id=com.ogaclejapan.smarttablayout.demo&referrer=utm_source%3Dgithub
[demo_icon]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/icon.png
[googleplay_store_badge]: http://www.android.com/images/brand/get_it_on_play_logo_large.png
[maven_central_badge_svg]: https://maven-badges.herokuapp.com/maven-central/com.ogaclejapan.smarttablayout/library/badge.svg?style=flat
[maven_central_badge_app]: https://maven-badges.herokuapp.com/maven-central/com.ogaclejapan.smarttablayout/library
[android_arsenal_badge_svg]: https://img.shields.io/badge/Android%20Arsenal-SmartTabLayout-brightgreen.svg?style=flat
[android_arsenal_badge_link]: http://android-arsenal.com/details/1/1683
[android_weekly_badge_svg]: https://img.shields.io/badge/AndroidWeekly-%23148-blue.svg
[android_weekly_badge_link]: http://androidweekly.net/issues/issue-148
[qiitanium]: https://github.com/ogaclejapan/Qiitanium
[google_slidingtabbasic]: https://github.com/googlesamples/android-SlidingTabsBasic


================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
ext {
  // Package information for bintray
  pkginfo = [name       : ARTIFACT_NAME,
             description: ARTIFACT_DESCRIPTION,
             site       : SITE_URL,
             issue      : ISSUE_URL,
             vcs        : SCM_URL]
}

buildscript {
  repositories {
    google()
    mavenCentral()
    maven {
      url "https://plugins.gradle.org/m2/"
    }
    jcenter()
  }
  dependencies {
    classpath 'com.android.tools.build:gradle:3.3.1'
    classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
    classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
    classpath 'com.github.ben-manes:gradle-versions-plugin:0.21.0'
    classpath 'gradle.plugin.com.hierynomus.gradle.plugins:license-gradle-plugin:0.15.0'

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
  }
}

allprojects {

  version = VERSION_NAME
  group = GROUP

  repositories {
    google()
    mavenCentral()
    jcenter()
  }
}

task clean(type: Delete) {
  delete rootProject.buildDir
}


================================================
FILE: demo/.gitignore
================================================
/build


================================================
FILE: demo/build.gradle
================================================
apply plugin: 'com.android.application'

android {
  compileSdkVersion COMPILE_SDK_VERSION as int

  defaultConfig {
    minSdkVersion 14
    targetSdkVersion COMPILE_SDK_VERSION as int
    versionCode VERSION_CODE as int
    versionName VERSION_NAME
  }

  def secretFile = file("${rootDir}/secret.gradle")
  if (secretFile.exists()) {
    apply from: secretFile.absolutePath
    signingConfigs {
      release {
        storeFile project.ext.storeFile
        storePassword project.ext.storePassword
        keyAlias project.ext.keyAlias
        keyPassword project.ext.keyPassword
      }
    }
  }

  buildTypes {
    release {
      if (secretFile.exists()) {
        signingConfig signingConfigs.release
      }
      minifyEnabled false
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
  }
}

dependencies {
  implementation project(':library')
  implementation project(':utils-v4')
  implementation "androidx.appcompat:appcompat:${ANDROIDX_APPCOMPAT_VERSION}"
}


================================================
FILE: demo/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/msk/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: demo/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.ogaclejapan.smarttablayout.demo"
  >

  <application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    >

    <activity
      android:name=".MainActivity"
      android:label="@string/app_name"
      >
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
    </activity>

    <activity
      android:name=".DemoActivity"
      android:label="@string/app_name"
      android:parentActivityName=".MainActivity"
      android:theme="@style/AppTheme.NoActionBar"
      />

    <activity
      android:name=".DemoRtlActivity"
      android:label="@string/app_name"
      android:parentActivityName=".MainActivity"
      android:theme="@style/AppTheme.NoActionBar"
      />

    <activity
      android:name=".DemoLikeMediumActivity"
      android:label="@string/app_name"
      android:parentActivityName=".MainActivity"
      android:theme="@style/AppTheme.NoActionBar"
      />

    <activity
      android:name=".DemoTabWithNotificationMarkActivity"
      android:label="@string/app_name"
      android:parentActivityName=".MainActivity"
      android:theme="@style/AppTheme.NoActionBar"
      />

  </application>

</manifest>


================================================
FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/Demo.java
================================================
package com.ogaclejapan.smarttablayout.demo;

import android.content.Context;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.ogaclejapan.smarttablayout.SmartTabLayout;

import androidx.viewpager.widget.PagerAdapter;

public enum Demo {

  BASIC(R.string.demo_title_basic, R.layout.demo_basic),

  BASIC2(R.string.demo_title_basic2, R.layout.demo_basic_title_offset_auto_center),

  SMART_INDICATOR(R.string.demo_title_smart_indicator, R.layout.demo_smart_indicator),

  DISTRIBUTE_EVENLY(R.string.demo_title_distribute_evenly, R.layout.demo_distribute_evenly) {
    @Override
    public int[] tabs() {
      return tab3();
    }
  },

  ALWAYS_IN_CENTER(R.string.demo_title_always_in_center, R.layout.demo_always_in_center),

  CUSTOM_TAB(R.string.demo_title_custom_tab_text, R.layout.demo_custom_tab_text),

  CUSTOM_TAB_COLORS(R.string.demo_title_custom_tab_colors, R.layout.demo_custom_tab_colors),

  CUSTOM_TAB_ICONS1(R.string.demo_title_custom_tab_icons1, R.layout.demo_custom_tab_icons1) {
    @Override
    public int[] tabs() {
      return new int[] {
          R.string.demo_tab_no_title,
          R.string.demo_tab_no_title,
          R.string.demo_tab_no_title,
          R.string.demo_tab_no_title
      };
    }

    @Override
    public void setup(SmartTabLayout layout) {
      super.setup(layout);

      final LayoutInflater inflater = LayoutInflater.from(layout.getContext());
      final Resources res = layout.getContext().getResources();

      layout.setCustomTabView(new SmartTabLayout.TabProvider() {
        @Override
        public View createTabView(ViewGroup container, int position, PagerAdapter adapter) {
          ImageView icon = (ImageView) inflater.inflate(R.layout.custom_tab_icon1, container,
              false);
          switch (position) {
            case 0:
              icon.setImageDrawable(res.getDrawable(R.drawable.ic_home_white_24dp));
              break;
            case 1:
              icon.setImageDrawable(res.getDrawable(R.drawable.ic_search_white_24dp));
              break;
            case 2:
              icon.setImageDrawable(res.getDrawable(R.drawable.ic_person_white_24dp));
              break;
            case 3:
              icon.setImageDrawable(res.getDrawable(R.drawable.ic_flash_on_white_24dp));
              break;
            default:
              throw new IllegalStateException("Invalid position: " + position);
          }
          return icon;
        }
      });
    }
  },

  CUSTOM_TAB_ICONS2(R.string.demo_title_custom_tab_icons2, R.layout.demo_custom_tab_icons2) {
    @Override
    public int[] tabs() {
      return new int[] {
          R.string.demo_tab_no_title,
          R.string.demo_tab_no_title,
          R.string.demo_tab_no_title,
          R.string.demo_tab_no_title
      };
    }

    @Override
    public void setup(SmartTabLayout layout) {
      super.setup(layout);

      final LayoutInflater inflater = LayoutInflater.from(layout.getContext());
      final Resources res = layout.getContext().getResources();

      layout.setCustomTabView(new SmartTabLayout.TabProvider() {
        @Override
        public View createTabView(ViewGroup container, int position, PagerAdapter adapter) {
          ImageView icon = (ImageView) inflater.inflate(R.layout.custom_tab_icon2, container,
              false);
          switch (position) {
            case 0:
              icon.setImageDrawable(res.getDrawable(R.drawable.ic_home_white_24dp));
              break;
            case 1:
              icon.setImageDrawable(res.getDrawable(R.drawable.ic_search_white_24dp));
              break;
            case 2:
              icon.setImageDrawable(res.getDrawable(R.drawable.ic_person_white_24dp));
              break;
            case 3:
              icon.setImageDrawable(res.getDrawable(R.drawable.ic_flash_on_white_24dp));
              break;
            default:
              throw new IllegalStateException("Invalid position: " + position);
          }
          return icon;
        }
      });
    }
  },

  CUSTOM_TAB_ICON_AND_TEXT(R.string.demo_title_custom_tab_icon_and_text,
      R.layout.demo_custom_tab_icon_and_text) {
    @Override
    public int[] tabs() {
      return tab3();
    }
  },

  CUSTOM_TAB_ICON_AND_NOTIFICATION_MARK(R.string.demo_title_custom_tab_icon_and_notification_mark,
      R.layout.demo_custom_tab_icon_and_notification_mark) {
    @Override
    public int[] tabs() {
      return tab3();
    }

    @Override
    public void startActivity(Context context) {
      DemoTabWithNotificationMarkActivity.startActivity(context, this);
    }
  },

  CUSTOM_TAB_MARGIN(R.string.demo_title_custom_tab_margin, R.layout.demo_custom_tab_margin),

  INDICATOR_TRICK1(R.string.demo_title_indicator_trick1, R.layout.demo_indicator_trick1),

  INDICATOR_TRICK2(R.string.demo_title_indicator_trick2, R.layout.demo_indicator_trick2),

  RIGHT_TO_LEFT(R.string.demo_title_right_to_left, R.layout.demo_rtl) {
    @Override
    public void startActivity(Context context) {
      DemoRtlActivity.startActivity(context, this);
    }
  },

  LIKE_MEDIUM_TAG(R.string.demo_title_advanced_medium, R.layout.demo_like_a_medium_tag) {
    @Override
    public int[] tabs() {
      return new int[] {
          R.string.demo_tab_like_a_medium_top,
          R.string.demo_tab_like_a_medium_latest
      };
    }

    @Override
    public void startActivity(Context context) {
      DemoLikeMediumActivity.startActivity(context, this);
    }
  };

  public final int titleResId;
  public final int layoutResId;

  Demo(int titleResId, int layoutResId) {
    this.titleResId = titleResId;
    this.layoutResId = layoutResId;
  }

  public static int[] tab10() {
    return new int[] {
        R.string.demo_tab_1,
        R.string.demo_tab_2,
        R.string.demo_tab_3,
        R.string.demo_tab_4,
        R.string.demo_tab_5,
        R.string.demo_tab_6,
        R.string.demo_tab_7,
        R.string.demo_tab_8,
        R.string.demo_tab_9,
        R.string.demo_tab_10
    };
  }

  public static int[] tab3() {
    return new int[] {
        R.string.demo_tab_8,
        R.string.demo_tab_9,
        R.string.demo_tab_10
    };
  }

  public void startActivity(Context context) {
    DemoActivity.startActivity(context, this);
  }

  public void setup(final SmartTabLayout layout) {
    //Do nothing.
  }

  public int[] tabs() {
    return tab10();
  }

}


================================================
FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoActivity.java
================================================
package com.ogaclejapan.smarttablayout.demo;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.ViewGroup;

import com.ogaclejapan.smarttablayout.SmartTabLayout;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItemAdapter;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.viewpager.widget.ViewPager;

public class DemoActivity extends AppCompatActivity {

  private static final String KEY_DEMO = "demo";

  public static void startActivity(Context context, Demo demo) {
    Intent intent = new Intent(context, DemoActivity.class);
    intent.putExtra(KEY_DEMO, demo.name());
    context.startActivity(intent);
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_demo);

    Demo demo = getDemo();

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    toolbar.setTitle(demo.titleResId);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    ViewGroup tab = (ViewGroup) findViewById(R.id.tab);
    tab.addView(LayoutInflater.from(this).inflate(demo.layoutResId, tab, false));

    ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
    SmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpagertab);
    demo.setup(viewPagerTab);

    FragmentPagerItems pages = new FragmentPagerItems(this);
    for (int titleResId : demo.tabs()) {
      pages.add(FragmentPagerItem.of(getString(titleResId), DemoFragment.class));
    }

    FragmentPagerItemAdapter adapter = new FragmentPagerItemAdapter(
        getSupportFragmentManager(), pages);

    viewPager.setAdapter(adapter);
    viewPagerTab.setViewPager(viewPager);

  }

  private Demo getDemo() {
    return Demo.valueOf(getIntent().getStringExtra(KEY_DEMO));
  }
}


================================================
FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoFragment.java
================================================
package com.ogaclejapan.smarttablayout.demo;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem;

import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class DemoFragment extends Fragment {

  @Override
  public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
      @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_demo, container, false);
  }

  @Override
  public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    int position = FragmentPagerItem.getPosition(getArguments());
    TextView title = (TextView) view.findViewById(R.id.item_title);
    title.setText(String.valueOf(position));
  }

}


================================================
FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoLikeMediumActivity.java
================================================
package com.ogaclejapan.smarttablayout.demo;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.ViewGroup;

import com.ogaclejapan.smarttablayout.SmartTabLayout;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItemAdapter;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.viewpager.widget.ViewPager;

public class DemoLikeMediumActivity extends AppCompatActivity {

  private static final String KEY_DEMO = "demo";

  public static void startActivity(Context context, Demo demo) {
    Intent intent = new Intent(context, DemoLikeMediumActivity.class);
    intent.putExtra(KEY_DEMO, demo.name());
    context.startActivity(intent);
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_like_a_medium);

    Demo demo = getDemo();

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    toolbar.setTitle(demo.titleResId);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    ViewGroup tab = (ViewGroup) findViewById(R.id.tab);
    tab.addView(LayoutInflater.from(this).inflate(demo.layoutResId, tab, false));

    ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
    SmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpagertab);
    demo.setup(viewPagerTab);

    FragmentPagerItems pages = new FragmentPagerItems(this);
    for (int titleResId : demo.tabs()) {
      pages.add(FragmentPagerItem.of(getString(titleResId), DemoFragment.class));
    }

    FragmentPagerItemAdapter adapter = new FragmentPagerItemAdapter(
        getSupportFragmentManager(), pages);

    viewPager.setAdapter(adapter);
    viewPagerTab.setViewPager(viewPager);

  }

  private Demo getDemo() {
    return Demo.valueOf(getIntent().getStringExtra(KEY_DEMO));
  }
}


================================================
FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoRtlActivity.java
================================================
package com.ogaclejapan.smarttablayout.demo;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.ViewGroup;

import com.ogaclejapan.smarttablayout.SmartTabLayout;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItemAdapter;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.viewpager.widget.ViewPager;

public class DemoRtlActivity extends AppCompatActivity {

  private static final String KEY_DEMO = "demo";

  public static void startActivity(Context context, Demo demo) {
    Intent intent = new Intent(context, DemoRtlActivity.class);
    intent.putExtra(KEY_DEMO, demo.name());
    context.startActivity(intent);
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_rtl);

    Demo demo = getDemo();

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    toolbar.setTitle(demo.titleResId);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    ViewGroup tab = (ViewGroup) findViewById(R.id.tab);
    tab.addView(LayoutInflater.from(this).inflate(demo.layoutResId, tab, false));

    ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
    final SmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpagertab);
    demo.setup(viewPagerTab);

    FragmentPagerItems pages = new FragmentPagerItems(this);
    for (int titleResId : demo.tabs()) {
      pages.add(FragmentPagerItem.of(getString(titleResId), DemoFragment.class));
    }

    FragmentPagerItemAdapter adapter = new FragmentPagerItemAdapter(
        getSupportFragmentManager(), pages);

    viewPager.setAdapter(adapter);
    viewPagerTab.setViewPager(viewPager);

  }

  private Demo getDemo() {
    return Demo.valueOf(getIntent().getStringExtra(KEY_DEMO));
  }
}


================================================
FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoTabWithNotificationMarkActivity.java
================================================
package com.ogaclejapan.smarttablayout.demo;

import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.ogaclejapan.smarttablayout.SmartTabLayout;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItemAdapter;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems;

import java.util.Random;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

public class DemoTabWithNotificationMarkActivity extends AppCompatActivity implements
    SmartTabLayout.TabProvider {

  private static final String KEY_DEMO = "demo";

  public static void startActivity(Context context, Demo demo) {
    Intent intent = new Intent(context, DemoTabWithNotificationMarkActivity.class);
    intent.putExtra(KEY_DEMO, demo.name());
    context.startActivity(intent);
  }

  private Random random = new Random(System.currentTimeMillis());

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_demo_tab_with_notification_mark);

    final Demo demo = getDemo();

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    toolbar.setTitle(demo.titleResId);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    ViewGroup tab = (ViewGroup) findViewById(R.id.tab);
    tab.addView(LayoutInflater.from(this).inflate(demo.layoutResId, tab, false));

    ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
    final SmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpagertab);
    viewPagerTab.setCustomTabView(this);

    FragmentPagerItems pages = new FragmentPagerItems(this);
    for (int titleResId : demo.tabs()) {
      pages.add(FragmentPagerItem.of(getString(titleResId), DemoFragment.class));
    }

    FragmentPagerItemAdapter adapter = new FragmentPagerItemAdapter(
        getSupportFragmentManager(), pages);

    viewPager.setAdapter(adapter);
    viewPagerTab.setViewPager(viewPager);

    viewPagerTab.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
      @Override
      public void onPageSelected(int position) {
        super.onPageSelected(position);
        View tab = viewPagerTab.getTabAt(position);
        View mark = tab.findViewById(R.id.custom_tab_notification_mark);
        mark.setVisibility(View.GONE);
      }
    });

    findViewById(R.id.test).setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        int position = Math.abs(random.nextInt()) % demo.tabs().length;
        View tab = viewPagerTab.getTabAt(position);
        View mark = tab.findViewById(R.id.custom_tab_notification_mark);
        mark.setVisibility(View.VISIBLE);
      }
    });

  }

  @Override
  public View createTabView(ViewGroup container, int position, PagerAdapter adapter) {
    LayoutInflater inflater = LayoutInflater.from(container.getContext());
    Resources res = container.getContext().getResources();
    View tab = inflater.inflate(R.layout.custom_tab_icon_and_notification_mark, container, false);
    View mark = tab.findViewById(R.id.custom_tab_notification_mark);
    mark.setVisibility(View.GONE);
    ImageView icon = (ImageView) tab.findViewById(R.id.custom_tab_icon);
    switch (position) {
      case 0:
        icon.setImageDrawable(res.getDrawable(R.drawable.ic_home_white_24dp));
        break;
      case 1:
        icon.setImageDrawable(res.getDrawable(R.drawable.ic_search_white_24dp));
        break;
      case 2:
        icon.setImageDrawable(res.getDrawable(R.drawable.ic_person_white_24dp));
        break;
      default:
        throw new IllegalStateException("Invalid position: " + position);
    }
    return tab;
  }

  private Demo getDemo() {
    return Demo.valueOf(getIntent().getStringExtra(KEY_DEMO));
  }
}


================================================
FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/MainActivity.java
================================================
package com.ogaclejapan.smarttablayout.demo;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity implements AbsListView.OnItemClickListener {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ListView listView = (ListView) findViewById(R.id.list);
    listView.setOnItemClickListener(this);

    ArrayAdapter<String> demoAdapter = new ArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1);

    for (Demo demo : Demo.values()) {
      demoAdapter.add(getString(demo.titleResId));
    }

    listView.setAdapter(demoAdapter);
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return super.onCreateOptionsMenu(menu);
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
      case R.id.menu_github:
        openGitHub();
        return true;
      default:
        return super.onOptionsItemSelected(item);
    }
  }

  @Override
  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    Demo demo = Demo.values()[position];
    demo.startActivity(this);
  }

  private void openGitHub() {
    Uri uri = Uri.parse(getString(R.string.app_github_url));
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    startActivity(intent);
  }

}


================================================
FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/TintableImageView.java
================================================
package com.ogaclejapan.smarttablayout.demo;

import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.util.AttributeSet;

import androidx.appcompat.widget.AppCompatImageView;

/**
 * https://gist.github.com/tylerchesley/5d15d859be4f3ce31213
 */
public class TintableImageView extends AppCompatImageView {

  private ColorStateList tint;

  public TintableImageView(Context context) {
    super(context);
  }

  public TintableImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context, attrs, 0);
  }

  public TintableImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context, attrs, defStyle);
  }

  private void init(Context context, AttributeSet attrs, int defStyle) {
    TypedArray a = context.obtainStyledAttributes(
        attrs, R.styleable.TintableImageView, defStyle, 0);
    tint = a.getColorStateList(
        R.styleable.TintableImageView_tint);
    a.recycle();
  }

  @Override
  protected void drawableStateChanged() {
    super.drawableStateChanged();
    if (tint != null && tint.isStateful()) {
      updateTintColor();
    }
  }

  public void setColorFilter(ColorStateList tint) {
    this.tint = tint;
    super.setColorFilter(tint.getColorForState(getDrawableState(), 0));
  }

  private void updateTintColor() {
    int color = tint.getColorForState(getDrawableState(), 0);
    setColorFilter(color);
  }

}


================================================
FILE: demo/src/main/res/color/custom_tab.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="@color/text_enabled" android:state_selected="true"/>
  <item android:color="@color/text_disabled" android:state_selected="false"/>
</selector>


================================================
FILE: demo/src/main/res/color/custom_tab_icon.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="@color/icon_enabled" android:state_selected="true"/>
  <item android:color="@color/icon_disabled" android:state_selected="false"/>
</selector>

================================================
FILE: demo/src/main/res/color/custom_tab_like_a_medium.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="@color/medium_text_enabled" android:state_selected="true"/>
  <item android:color="@color/medium_text_disabled" android:state_selected="false"/>
</selector>

================================================
FILE: demo/src/main/res/drawable/custom_circle.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<shape
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="oval"
  >

  <solid android:color="@android:color/transparent"/>

  <stroke
    android:width="1dp"
    android:color="@color/icon_disabled"
    />
</shape>

================================================
FILE: demo/src/main/res/drawable/custom_icon.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@drawable/ic_flash_on_white_24dp" android:state_selected="true"/>
  <item android:drawable="@drawable/ic_home_white_24dp"/>
</selector>


================================================
FILE: demo/src/main/res/drawable/custom_tab.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_pressed="true">
    <shape android:shape="rectangle">
      <solid android:color="@color/black_20"/>
    </shape>
  </item>
  <item android:drawable="@color/transparent"/>
</selector>

================================================
FILE: demo/src/main/res/drawable/shape_notification_mark.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<shape
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="oval"
  >
  <solid android:color="@color/accent"/>
</shape>


================================================
FILE: demo/src/main/res/layout/activity_demo.xml
================================================
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  >

  <LinearLayout
    android:id="@+id/header"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/primary"
    >

    <androidx.appcompat.widget.Toolbar
      android:id="@id/toolbar"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:minHeight="?attr/actionBarSize"
      app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
      app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
      >

    </androidx.appcompat.widget.Toolbar>

    <FrameLayout
      android:id="@id/tab"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      />

  </LinearLayout>

  <androidx.viewpager.widget.ViewPager
    android:id="@id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/header"
    />

</RelativeLayout>


================================================
FILE: demo/src/main/res/layout/activity_demo_tab_with_notification_mark.xml
================================================
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  >

  <LinearLayout
    android:id="@+id/header"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/primary"
    >

    <androidx.appcompat.widget.Toolbar
      android:id="@id/toolbar"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:minHeight="?attr/actionBarSize"
      app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
      app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
      />

    <FrameLayout
      android:id="@id/tab"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      />

  </LinearLayout>

  <androidx.viewpager.widget.ViewPager
    android:id="@id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/header"
    />

  <Button
    android:id="@+id/test"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_margin="8dp"
    android:padding="8dp"
    android:text="Try notification mark"
    />

</RelativeLayout>


================================================
FILE: demo/src/main/res/layout/activity_like_a_medium.xml
================================================
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="@color/white"
  >

  <LinearLayout
    android:id="@+id/header"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >

    <androidx.appcompat.widget.Toolbar
      android:id="@id/toolbar"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:background="@color/transparent"
      android:minHeight="?attr/actionBarSize"
      app:popupTheme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
      app:theme="@style/ThemeOverlay.AppCompat.Light"
      />

    <FrameLayout
      android:id="@id/tab"
      android:layout_width="match_parent"
      android:layout_height="@dimen/tab_height"
      />

  </LinearLayout>

  <androidx.viewpager.widget.ViewPager
    android:id="@id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/header"
    />

</RelativeLayout>


================================================
FILE: demo/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  >

  <ListView
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

</FrameLayout>

================================================
FILE: demo/src/main/res/layout/activity_rtl.xml
================================================
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layoutDirection="rtl"
  >

  <LinearLayout
    android:id="@+id/header"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/primary"
    >

    <androidx.appcompat.widget.Toolbar
      android:id="@id/toolbar"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:minHeight="?attr/actionBarSize"
      app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
      app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
      />

    <FrameLayout
      android:id="@id/tab"
      android:layout_width="match_parent"
      android:layout_height="@dimen/tab_height"
      />

  </LinearLayout>

  <androidx.viewpager.widget.ViewPager
    android:id="@id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/header"
    />

</RelativeLayout>


================================================
FILE: demo/src/main/res/layout/custom_tab.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<TextView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/custom_text"
  android:layout_width="wrap_content"
  android:layout_height="match_parent"
  android:background="?attr/selectableItemBackground"
  android:gravity="center"
  android:paddingLeft="24dp"
  android:paddingRight="24dp"
  android:textColor="@color/custom_tab"
  android:textSize="14sp"
  >

</TextView>

================================================
FILE: demo/src/main/res/layout/custom_tab_circle.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<View
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="8dp"
  android:layout_height="8dp"
  android:layout_gravity="center_vertical"
  android:layout_marginLeft="1dp"
  android:layout_marginRight="1dp"
  android:background="@drawable/custom_circle"
  />



================================================
FILE: demo/src/main/res/layout/custom_tab_icon1.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<com.ogaclejapan.smarttablayout.demo.TintableImageView
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="wrap_content"
  android:layout_height="match_parent"
  android:background="?attr/selectableItemBackground"
  android:scaleType="center"
  app:tint="@color/custom_tab_icon"
  />



================================================
FILE: demo/src/main/res/layout/custom_tab_icon2.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<com.ogaclejapan.smarttablayout.demo.TintableImageView
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="48dp"
  android:layout_height="48dp"
  android:background="?attr/selectableItemBackground"
  android:padding="6dp"
  android:scaleType="center"
  app:tint="@color/custom_tab_icon"
  />



================================================
FILE: demo/src/main/res/layout/custom_tab_icon_and_notification_mark.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="?attr/selectableItemBackground"
  >

  <com.ogaclejapan.smarttablayout.demo.TintableImageView
    android:id="@+id/custom_tab_icon"
    android:layout_width="24dp"
    android:layout_height="24dp"
    android:layout_centerInParent="true"
    android:scaleType="center"
    app:tint="@color/custom_tab_icon"
    />

  <View
    android:id="@+id/custom_tab_notification_mark"
    android:layout_width="4dp"
    android:layout_height="4dp"
    android:layout_above="@id/custom_tab_icon"
    android:layout_toRightOf="@id/custom_tab_icon"
    android:background="@drawable/shape_notification_mark"
    android:visibility="gone"
    />

</RelativeLayout>


================================================
FILE: demo/src/main/res/layout/custom_tab_icon_and_text.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="?attr/selectableItemBackground"
  >

  <Space
    android:id="@+id/center_anchor"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_centerInParent="true"
    />

  <com.ogaclejapan.smarttablayout.demo.TintableImageView
    android:id="@+id/custom_tab_icon"
    android:layout_width="24dp"
    android:layout_height="24dp"
    android:layout_above="@id/center_anchor"
    android:layout_centerHorizontal="true"
    android:scaleType="center"
    android:src="@drawable/custom_icon"
    app:tint="@color/custom_tab_icon"
    />

  <TextView
    android:id="@+id/custom_tab_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/center_anchor"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="2dp"
    android:maxLines="1"
    android:textColor="@color/custom_tab"
    android:textSize="14sp"
    />

</RelativeLayout>


================================================
FILE: demo/src/main/res/layout/custom_tab_like_a_medium.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<TextView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/custom_text"
  android:layout_width="wrap_content"
  android:layout_height="match_parent"
  android:background="?attr/selectableItemBackground"
  android:gravity="center"
  android:paddingLeft="24dp"
  android:paddingRight="24dp"
  android:textAllCaps="true"
  android:textColor="@color/custom_tab_like_a_medium"
  android:textSize="14sp"
  android:textStyle="bold"
  >

</TextView>

================================================
FILE: demo/src/main/res/layout/custom_tab_margin.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<TextView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/custom_text"
  android:layout_width="wrap_content"
  android:layout_height="match_parent"
  android:layout_marginLeft="8dp"
  android:layout_marginRight="8dp"
  android:background="?attr/selectableItemBackground"
  android:gravity="center"
  android:paddingLeft="24dp"
  android:paddingRight="24dp"
  android:textColor="@color/custom_tab"
  android:textSize="14sp"
  >

</TextView>

================================================
FILE: demo/src/main/res/layout/demo_always_in_center.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="match_parent"
  android:layout_height="@dimen/tab_height"
  android:paddingBottom="4dp"
  app:stl_defaultTabTextColor="@color/white"
  app:stl_defaultTabTextMinWidth="120dp"
  app:stl_indicatorAlwaysInCenter="true"
  app:stl_indicatorColor="@color/accent"
  app:stl_indicatorCornerRadius="1.5dp"
  app:stl_indicatorInterpolation="smart"
  app:stl_indicatorThickness="3dp"
  app:stl_underlineColor="@color/transparent"
  />




================================================
FILE: demo/src/main/res/layout/demo_basic.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="match_parent"
  android:layout_height="@dimen/tab_height"
  android:background="@color/primary"
  app:stl_defaultTabTextColor="@color/white"
  app:stl_defaultTabTextHorizontalPadding="24dp"
  app:stl_indicatorColor="@color/accent"
  app:stl_indicatorInterpolation="linear"
  app:stl_indicatorThickness="3dp"
  app:stl_underlineThickness="1dp"
  />




================================================
FILE: demo/src/main/res/layout/demo_basic_title_offset_auto_center.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="match_parent"
  android:layout_height="@dimen/tab_height"
  app:stl_defaultTabTextColor="@color/white"
  app:stl_defaultTabTextHorizontalPadding="24dp"
  app:stl_indicatorColor="@color/accent"
  app:stl_indicatorInterpolation="linear"
  app:stl_indicatorThickness="3dp"
  app:stl_titleOffset="auto_center"
  app:stl_underlineThickness="1dp"
  />



================================================
FILE: demo/src/main/res/layout/demo_custom_tab_colors.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="match_parent"
  android:layout_height="@dimen/tab_height"
  app:stl_defaultTabTextColor="@color/white"
  app:stl_defaultTabTextHorizontalPadding="24dp"
  app:stl_dividerColors="@array/custom_tab_colors"
  app:stl_indicatorColors="@array/custom_tab_colors"
  app:stl_indicatorInterpolation="linear"
  app:stl_indicatorThickness="3dp"
  app:stl_underlineThickness="1dp"
  />




================================================
FILE: demo/src/main/res/layout/demo_custom_tab_icon_and_notification_mark.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="match_parent"
  android:layout_height="@dimen/tab_height"
  app:stl_distributeEvenly="true"
  app:stl_indicatorColor="@color/accent"
  app:stl_indicatorInterpolation="linear"
  app:stl_indicatorThickness="3dp"
  app:stl_underlineThickness="1dp"
  />


================================================
FILE: demo/src/main/res/layout/demo_custom_tab_icon_and_text.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="match_parent"
  android:layout_height="@dimen/tab_height_large"
  app:stl_customTabTextLayoutId="@layout/custom_tab_icon_and_text"
  app:stl_customTabTextViewId="@id/custom_tab_text"
  app:stl_distributeEvenly="true"
  app:stl_indicatorColor="@color/accent"
  app:stl_indicatorInterpolation="linear"
  app:stl_indicatorThickness="3dp"
  app:stl_underlineThickness="1dp"
  />


================================================
FILE: demo/src/main/res/layout/demo_custom_tab_icons1.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="match_parent"
  android:layout_height="@dimen/tab_height"
  app:stl_distributeEvenly="true"
  app:stl_dividerColor="@color/transparent"
  app:stl_dividerThickness="0dp"
  app:stl_indicatorColor="@color/transparent"
  app:stl_indicatorThickness="0dp"
  app:stl_underlineColor="@color/transparent"
  app:stl_underlineThickness="0dp"
  />




================================================
FILE: demo/src/main/res/layout/demo_custom_tab_icons2.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="wrap_content"
  android:layout_height="@dimen/tab_height"
  android:layout_gravity="center_horizontal"
  app:stl_dividerColor="@color/transparent"
  app:stl_dividerThickness="0dp"
  app:stl_indicatorColor="@color/white_20"
  app:stl_indicatorCornerRadius="18dp"
  app:stl_indicatorGravity="center"
  app:stl_indicatorInterpolation="linear"
  app:stl_indicatorThickness="36dp"
  app:stl_indicatorWithoutPadding="true"
  app:stl_underlineColor="@color/transparent"
  app:stl_underlineThickness="0dp"
  />




================================================
FILE: demo/src/main/res/layout/demo_custom_tab_margin.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="match_parent"
  android:layout_height="@dimen/tab_height"
  app:stl_customTabTextLayoutId="@layout/custom_tab_margin"
  app:stl_customTabTextViewId="@id/custom_text"
  app:stl_indicatorColor="@color/accent"
  app:stl_indicatorInterpolation="linear"
  app:stl_indicatorThickness="3dp"
  app:stl_underlineThickness="1dp"
  />




================================================
FILE: demo/src/main/res/layout/demo_custom_tab_text.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="match_parent"
  android:layout_height="@dimen/tab_height"
  app:stl_customTabTextLayoutId="@layout/custom_tab"
  app:stl_customTabTextViewId="@id/custom_text"
  app:stl_indicatorColor="@color/accent"
  app:stl_indicatorInterpolation="linear"
  app:stl_indicatorThickness="3dp"
  app:stl_underlineThickness="1dp"
  />




================================================
FILE: demo/src/main/res/layout/demo_distribute_evenly.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="match_parent"
  android:layout_height="@dimen/tab_height"
  android:paddingBottom="4dp"
  app:stl_defaultTabTextColor="@color/white"
  app:stl_distributeEvenly="true"
  app:stl_indicatorColor="@color/accent"
  app:stl_indicatorCornerRadius="1.5dp"
  app:stl_indicatorInterpolation="smart"
  app:stl_indicatorThickness="3dp"
  app:stl_underlineColor="@color/transparent"
  />




================================================
FILE: demo/src/main/res/layout/demo_indicator_trick1.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="match_parent"
  android:layout_height="@dimen/tab_height"
  android:clipToPadding="false"
  android:paddingLeft="4dp"
  android:paddingRight="4dp"
  app:stl_defaultTabTextColor="@color/white"
  app:stl_defaultTabTextHorizontalPadding="18dp"
  app:stl_dividerColor="@color/transparent"
  app:stl_dividerThickness="0dp"
  app:stl_indicatorColor="@color/black_20"
  app:stl_indicatorCornerRadius="18dp"
  app:stl_indicatorGravity="center"
  app:stl_indicatorInterpolation="smart"
  app:stl_indicatorThickness="36dp"
  app:stl_underlineColor="@color/transparent"
  app:stl_underlineThickness="0dp"
  />




================================================
FILE: demo/src/main/res/layout/demo_indicator_trick2.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="wrap_content"
  android:layout_height="16dp"
  android:layout_gravity="bottom|center_horizontal"
  app:stl_clickable="false"
  app:stl_customTabTextLayoutId="@layout/custom_tab_circle"
  app:stl_dividerColor="@color/transparent"
  app:stl_dividerThickness="0dp"
  app:stl_indicatorColor="@color/accent"
  app:stl_indicatorCornerRadius="4dp"
  app:stl_indicatorGravity="center"
  app:stl_indicatorInterpolation="linear"
  app:stl_indicatorThickness="8dp"
  app:stl_underlineColor="@color/transparent"
  app:stl_underlineThickness="0dp"
  />




================================================
FILE: demo/src/main/res/layout/demo_like_a_medium_tag.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="match_parent"
  android:layout_height="@dimen/tab_height"
  app:stl_customTabTextLayoutId="@layout/custom_tab_like_a_medium"
  app:stl_customTabTextViewId="@id/custom_text"
  app:stl_dividerColor="@color/transparent"
  app:stl_dividerThickness="0dp"
  app:stl_indicatorColor="@color/black"
  app:stl_indicatorCornerRadius="1dp"
  app:stl_indicatorGravity="top"
  app:stl_indicatorInterpolation="linear"
  app:stl_indicatorThickness="1dp"
  app:stl_indicatorWidth="48dp"
  app:stl_indicatorWithoutPadding="true"
  app:stl_overlineColor="@color/black_20"
  app:stl_overlineThickness="1dp"
  app:stl_underlineColor="@color/transparent"
  app:stl_underlineThickness="0dp"
  />




================================================
FILE: demo/src/main/res/layout/demo_rtl.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="match_parent"
  android:layout_height="@dimen/tab_height"
  app:stl_defaultTabTextColor="@color/white"
  app:stl_defaultTabTextHorizontalPadding="24dp"
  app:stl_indicatorColor="@color/accent"
  app:stl_indicatorInterpolation="linear"
  app:stl_indicatorThickness="3dp"
  app:stl_underlineThickness="1dp"
  />




================================================
FILE: demo/src/main/res/layout/demo_smart_indicator.xml
================================================
<com.ogaclejapan.smarttablayout.SmartTabLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@id/viewpagertab"
  android:layout_width="match_parent"
  android:layout_height="@dimen/tab_height"
  android:paddingBottom="4dp"
  app:stl_defaultTabTextColor="@color/white"
  app:stl_defaultTabTextHorizontalPadding="24dp"
  app:stl_indicatorColor="@color/accent"
  app:stl_indicatorCornerRadius="1.5dp"
  app:stl_indicatorInterpolation="smart"
  app:stl_indicatorThickness="3dp"
  app:stl_underlineColor="@color/transparent"
  />


================================================
FILE: demo/src/main/res/layout/fragment_demo.xml
================================================
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:gravity="center"
  >

  <TextView
    android:id="@+id/item_subtitle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Page:"
    android:textAppearance="?android:attr/textAppearanceLarge"
    />

  <TextView
    android:id="@+id/item_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="80sp"
    />

</LinearLayout>


================================================
FILE: demo/src/main/res/menu/menu_demo.xml
================================================
<menu
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  tools:context=".DemoActivity"
  >
  <item
    android:id="@+id/action_settings"
    android:orderInCategory="100"
    android:title="@string/action_settings"
    app:showAsAction="never"
    />
</menu>


================================================
FILE: demo/src/main/res/menu/menu_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<menu
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  >

  <item
    android:id="@+id/menu_github"
    android:icon="@null"
    android:title="@string/app_github"
    app:showAsAction="always"
    />

</menu>

================================================
FILE: demo/src/main/res/values/attrs.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="TintableImageView">
    <attr name="tint" format="reference|color"/>
  </declare-styleable>
</resources>

================================================
FILE: demo/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <color name="primary">#3C515C</color>
  <color name="primary_dark">#142E3C</color>
  <color name="accent">#40C4FF</color>
  <color name="white">#FFFFFFFF</color>
  <color name="black">#FF000000</color>
  <color name="black_20">#33000000</color>
  <color name="white_20">#33FFFFFF</color>
  <color name="transparent">#00000000</color>

  <color name="text_enabled">#FFFFFFFF</color>
  <color name="text_disabled">#4DFFFFFF</color>

  <color name="icon_enabled">#FFFFFFFF</color>
  <color name="icon_disabled">#FF63727B</color>

  <color name="medium_text_enabled">#FF000000</color>
  <color name="medium_text_disabled">#4D000000</color>

  <color name="light_blue_500">#03A9F4</color>
  <color name="cyan_500">#00BCD4</color>
  <color name="teal_500">#009688</color>
  <color name="green_500">#4CAF50</color>
  <color name="light_green_500">#8BC34A</color>

  <integer-array name="custom_tab_colors">
    <item>@color/light_blue_500</item>
    <item>@color/cyan_500</item>
    <item>@color/teal_500</item>
    <item>@color/green_500</item>
    <item>@color/light_green_500</item>
  </integer-array>

</resources>

================================================
FILE: demo/src/main/res/values/dimens.xml
================================================
<resources>
  <dimen name="tab_height">48dp</dimen>
  <dimen name="tab_height_large">72dp</dimen>
</resources>


================================================
FILE: demo/src/main/res/values/ids.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <item name="toolbar" type="id"/>
  <item name="tab" type="id"/>
  <item name="viewpager" type="id"/>
  <item name="viewpagertab" type="id"/>
</resources>

================================================
FILE: demo/src/main/res/values/strings.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>

  <string name="app_name">SmartTabLayout</string>
  <string name="app_github">GitHub</string>
  <string name="app_github_url"><![CDATA[https://github.com/ogaclejapan/SmartTabLayout]]></string>
  <string name="action_settings">Settings</string>

  <string name="demo_title_basic">Basic</string>
  <string name="demo_title_basic2">Basic(Title Offset Auto Center)</string>
  <string name="demo_title_smart_indicator">Smart Indicator</string>
  <string name="demo_title_distribute_evenly">Distribute Evenly</string>
  <string name="demo_title_always_in_center">Always In Center</string>
  <string name="demo_title_custom_tab_text">Custom Tab Text</string>
  <string name="demo_title_custom_tab_margin">Custom Tab Margin (since 1.2~)</string>
  <string name="demo_title_custom_tab_colors">Custom Tab Colors</string>
  <string name="demo_title_custom_tab_icons1">Custom Tab Icons 1</string>
  <string name="demo_title_custom_tab_icons2">Custom Tab Icons 2 (since 1.2~)</string>
  <string name="demo_title_custom_tab_icon_and_text">Custom Tab Icon and Text</string>
  <string name="demo_title_custom_tab_icon_and_notification_mark">Custom Tab Icon and Notification Mark</string>
  <string name="demo_title_indicator_trick1">Indicator Thickness Trick 1</string>
  <string name="demo_title_indicator_trick2">Indicator Thickness Trick 2</string>
  <string name="demo_title_right_to_left">RTL support</string>
  <string name="demo_title_advanced_medium">Advanced: Like a Medium Tag (since 1.2~)</string>

  <string name="demo_tab_1">Cupcake</string>
  <string name="demo_tab_2">Donut</string>
  <string name="demo_tab_3">Eclair</string>
  <string name="demo_tab_4">Froyo</string>
  <string name="demo_tab_5">Gingerbread</string>
  <string name="demo_tab_6">Honeycomb</string>
  <string name="demo_tab_7">Ice Cream Sandwich</string>
  <string name="demo_tab_8">Jelly Bean</string>
  <string name="demo_tab_9">KitKat</string>
  <string name="demo_tab_10">Lollipop</string>

  <string name="demo_tab_no_title">No Title</string>
  <string name="demo_tab_like_a_medium_top">Top</string>
  <string name="demo_tab_like_a_medium_latest">Latest</string>

</resources>


================================================
FILE: demo/src/main/res/values/styles.xml
================================================
<resources>

  <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimary">@color/primary</item>
    <item name="colorPrimaryDark">@color/primary_dark</item>
    <item name="colorAccent">@color/accent</item>
  </style>

  <style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/primary</item>
    <item name="colorPrimaryDark">@color/primary_dark</item>
    <item name="colorAccent">@color/accent</item>
  </style>

</resources>


================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Sun Nov 27 17:23:04 JST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip


================================================
FILE: gradle.properties
================================================
android.useAndroidX=true

VERSION_NAME=2.0.0
VERSION_CODE=18
COMPILE_SDK_VERSION=28
ANDROIDX_APPCOMPAT_VERSION=1.0.2
ANDROIDX_BASE_VERSION=1.0.0

GROUP=com.ogaclejapan.smarttablayout
ARTIFACT_NAME=SmartTabLayout
ARTIFACT_DESCRIPTION=A custom ViewPager title strip which gives continuous feedback to the user when scrolling
SITE_URL=https://github.com/ogaclejapan/SmartTabLayout
ISSUE_SYSTEM=github
ISSUE_URL=https://github.com/ogaclejapan/SmartTabLayout/issues
SCM_URL=https://github.com/ogaclejapan/SmartTabLayout
SCM_CONNECTION=scm:git@github.com:ogaclejapan/SmartTabLayout.git
SCM_DEV_CONNECTION=scm:git@github.com:ogaclejapan/SmartTabLayout.git
LICENCE_NAME=The Apache Software License, Version 2.0
LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
LICENCE_DIST=repo
DEVELOPER_ID=ogaclejapan
DEVELOPER_NAME=Masaki Ogata
DEVELOPER_EMAIL=ogaclejapan@gmail.com


================================================
FILE: gradlew
================================================
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"


================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windowz variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: library/.gitignore
================================================
/build


================================================
FILE: library/LICENSE
================================================
Copyright (C) 2015 ogaclejapan
Copyright (C) 2013 The Android Open Source Project

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.


================================================
FILE: library/build.gradle
================================================
apply plugin: 'com.android.library'
apply plugin: 'com.github.ben-manes.versions'
apply plugin: 'com.github.hierynomus.license'

android {
  compileSdkVersion COMPILE_SDK_VERSION as int
  resourcePrefix 'stl_'

  defaultConfig {
    minSdkVersion 14
    targetSdkVersion COMPILE_SDK_VERSION as int
    versionCode VERSION_CODE as int
    versionName VERSION_NAME

  }
  buildTypes {
    release {
      minifyEnabled false
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
  }
}

dependencies {
  implementation "androidx.viewpager:viewpager:${ANDROIDX_BASE_VERSION}"
  implementation "androidx.fragment:fragment:${ANDROIDX_BASE_VERSION}"
}

license {

  sourceSets {
    main.java.srcDirs = android.sourceSets.main.java.srcDirs
    main.resources.srcDirs = android.sourceSets.main.resources.srcDirs
  }

  excludes(["**/*.xml"])

}

pkginfo.name = ARTIFACT_NAME
apply from: "${project.rootDir}/publish.gradle"


================================================
FILE: library/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/msk/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: library/src/main/AndroidManifest.xml
================================================
<manifest package="com.ogaclejapan.smarttablayout">

</manifest>


================================================
FILE: library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabIndicationInterpolator.java
================================================
/**
 * Copyright (C) 2015 ogaclejapan
 * Copyright (C) 2013 The Android Open Source Project
 *
 * 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.
 */
package com.ogaclejapan.smarttablayout;

import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;

public abstract class SmartTabIndicationInterpolator {

  public static final SmartTabIndicationInterpolator SMART = new SmartIndicationInterpolator();
  public static final SmartTabIndicationInterpolator LINEAR = new LinearIndicationInterpolator();

  static final int ID_SMART = 0;
  static final int ID_LINEAR = 1;

  public static SmartTabIndicationInterpolator of(int id) {
    switch (id) {
      case ID_SMART:
        return SMART;
      case ID_LINEAR:
        return LINEAR;
      default:
        throw new IllegalArgumentException("Unknown id: " + id);
    }
  }

  public abstract float getLeftEdge(float offset);

  public abstract float getRightEdge(float offset);

  public float getThickness(float offset) {
    return 1f; //Always the same thickness by default
  }

  public static class SmartIndicationInterpolator extends SmartTabIndicationInterpolator {

    private static final float DEFAULT_INDICATOR_INTERPOLATION_FACTOR = 3.0f;

    private final Interpolator leftEdgeInterpolator;
    private final Interpolator rightEdgeInterpolator;

    public SmartIndicationInterpolator() {
      this(DEFAULT_INDICATOR_INTERPOLATION_FACTOR);
    }

    public SmartIndicationInterpolator(float factor) {
      leftEdgeInterpolator = new AccelerateInterpolator(factor);
      rightEdgeInterpolator = new DecelerateInterpolator(factor);
    }

    @Override
    public float getLeftEdge(float offset) {
      return leftEdgeInterpolator.getInterpolation(offset);
    }

    @Override
    public float getRightEdge(float offset) {
      return rightEdgeInterpolator.getInterpolation(offset);
    }

    @Override
    public float getThickness(float offset) {
      return 1f / (1.0f - getLeftEdge(offset) + getRightEdge(offset));
    }

  }

  public static class LinearIndicationInterpolator extends SmartTabIndicationInterpolator {

    @Override
    public float getLeftEdge(float offset) {
      return offset;
    }

    @Override
    public float getRightEdge(float offset) {
      return offset;
    }

  }
}


================================================
FILE: library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabLayout.java
================================================
/**
 * Copyright (C) 2015 ogaclejapan
 * Copyright (C) 2013 The Android Open Source Project
 *
 * 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.
 */
package com.ogaclejapan.smarttablayout;

import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.os.Build;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.core.view.ViewCompat;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

/**
 * To be used with ViewPager to provide a tab indicator component which give constant feedback as
 * to
 * the user's scroll progress.
 * <p>
 * To use the component, simply add it to your view hierarchy. Then in your
 * {@link android.app.Activity} or {@link androidx.fragment.app.Fragment} call
 * {@link #setViewPager(ViewPager)} providing it the ViewPager this
 * layout
 * is being used for.
 * <p>
 * The colors can be customized in two ways. The first and simplest is to provide an array of
 * colors
 * via {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)}. The
 * alternative is via the {@link TabColorizer} interface which provides you complete control over
 * which color is used for any individual position.
 * <p>
 * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},
 * providing the layout ID of your custom layout.
 * <p>
 * Forked from Google Samples &gt; SlidingTabsBasic &gt;
 * <a href="https://developer.android.com/samples/SlidingTabsBasic/src/com.example.android.common/view/SlidingTabLayout.html">SlidingTabLayout</a>
 */
public class SmartTabLayout extends HorizontalScrollView {

  private static final boolean DEFAULT_DISTRIBUTE_EVENLY = false;
  private static final int TITLE_OFFSET_DIPS = 24;
  private static final int TITLE_OFFSET_AUTO_CENTER = -1;
  private static final int TAB_VIEW_PADDING_DIPS = 16;
  private static final boolean TAB_VIEW_TEXT_ALL_CAPS = true;
  private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
  private static final int TAB_VIEW_TEXT_COLOR = 0xFC000000;
  private static final int TAB_VIEW_TEXT_MIN_WIDTH = 0;
  private static final boolean TAB_CLICKABLE = true;

  protected final SmartTabStrip tabStrip;
  private int titleOffset;
  private int tabViewBackgroundResId;
  private boolean tabViewTextAllCaps;
  private ColorStateList tabViewTextColors;
  private float tabViewTextSize;
  private int tabViewTextHorizontalPadding;
  private int tabViewTextMinWidth;
  private ViewPager viewPager;
  private ViewPager.OnPageChangeListener viewPagerPageChangeListener;
  private OnScrollChangeListener onScrollChangeListener;
  private TabProvider tabProvider;
  private InternalTabClickListener internalTabClickListener;
  private OnTabClickListener onTabClickListener;
  private boolean distributeEvenly;

  public SmartTabLayout(Context context) {
    this(context, null);
  }

  public SmartTabLayout(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public SmartTabLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    // Disable the Scroll Bar
    setHorizontalScrollBarEnabled(false);

    final DisplayMetrics dm = getResources().getDisplayMetrics();
    final float density = dm.density;

    int tabBackgroundResId = NO_ID;
    boolean textAllCaps = TAB_VIEW_TEXT_ALL_CAPS;
    ColorStateList textColors;
    float textSize = TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP, dm);
    int textHorizontalPadding = (int) (TAB_VIEW_PADDING_DIPS * density);
    int textMinWidth = (int) (TAB_VIEW_TEXT_MIN_WIDTH * density);
    boolean distributeEvenly = DEFAULT_DISTRIBUTE_EVENLY;
    int customTabLayoutId = NO_ID;
    int customTabTextViewId = NO_ID;
    boolean clickable = TAB_CLICKABLE;
    int titleOffset = (int) (TITLE_OFFSET_DIPS * density);

    TypedArray a = context.obtainStyledAttributes(
        attrs, R.styleable.stl_SmartTabLayout, defStyle, 0);
    tabBackgroundResId = a.getResourceId(
        R.styleable.stl_SmartTabLayout_stl_defaultTabBackground, tabBackgroundResId);
    textAllCaps = a.getBoolean(
        R.styleable.stl_SmartTabLayout_stl_defaultTabTextAllCaps, textAllCaps);
    textColors = a.getColorStateList(
        R.styleable.stl_SmartTabLayout_stl_defaultTabTextColor);
    textSize = a.getDimension(
        R.styleable.stl_SmartTabLayout_stl_defaultTabTextSize, textSize);
    textHorizontalPadding = a.getDimensionPixelSize(
        R.styleable.stl_SmartTabLayout_stl_defaultTabTextHorizontalPadding, textHorizontalPadding);
    textMinWidth = a.getDimensionPixelSize(
        R.styleable.stl_SmartTabLayout_stl_defaultTabTextMinWidth, textMinWidth);
    customTabLayoutId = a.getResourceId(
        R.styleable.stl_SmartTabLayout_stl_customTabTextLayoutId, customTabLayoutId);
    customTabTextViewId = a.getResourceId(
        R.styleable.stl_SmartTabLayout_stl_customTabTextViewId, customTabTextViewId);
    distributeEvenly = a.getBoolean(
        R.styleable.stl_SmartTabLayout_stl_distributeEvenly, distributeEvenly);
    clickable = a.getBoolean(
        R.styleable.stl_SmartTabLayout_stl_clickable, clickable);
    titleOffset = a.getLayoutDimension(
        R.styleable.stl_SmartTabLayout_stl_titleOffset, titleOffset);
    a.recycle();

    this.titleOffset = titleOffset;
    this.tabViewBackgroundResId = tabBackgroundResId;
    this.tabViewTextAllCaps = textAllCaps;
    this.tabViewTextColors = (textColors != null)
        ? textColors
        : ColorStateList.valueOf(TAB_VIEW_TEXT_COLOR);
    this.tabViewTextSize = textSize;
    this.tabViewTextHorizontalPadding = textHorizontalPadding;
    this.tabViewTextMinWidth = textMinWidth;
    this.internalTabClickListener = clickable ? new InternalTabClickListener() : null;
    this.distributeEvenly = distributeEvenly;

    if (customTabLayoutId != NO_ID) {
      setCustomTabView(customTabLayoutId, customTabTextViewId);
    }

    this.tabStrip = new SmartTabStrip(context, attrs);

    if (distributeEvenly && tabStrip.isIndicatorAlwaysInCenter()) {
      throw new UnsupportedOperationException(
          "'distributeEvenly' and 'indicatorAlwaysInCenter' both use does not support");
    }

    // Make sure that the Tab Strips fills this View
    setFillViewport(!tabStrip.isIndicatorAlwaysInCenter());

    addView(tabStrip, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);

  }

  @Override
  protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    super.onScrollChanged(l, t, oldl, oldt);
    if (onScrollChangeListener != null) {
      onScrollChangeListener.onScrollChanged(l, oldl);
    }
  }

  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    if (tabStrip.isIndicatorAlwaysInCenter() && tabStrip.getChildCount() > 0) {
      View firstTab = tabStrip.getChildAt(0);
      View lastTab = tabStrip.getChildAt(tabStrip.getChildCount() - 1);
      int start = (w - Utils.getMeasuredWidth(firstTab)) / 2 - Utils.getMarginStart(firstTab);
      int end = (w - Utils.getMeasuredWidth(lastTab)) / 2 - Utils.getMarginEnd(lastTab);
      tabStrip.setMinimumWidth(tabStrip.getMeasuredWidth());
      ViewCompat.setPaddingRelative(this, start, getPaddingTop(), end, getPaddingBottom());
      setClipToPadding(false);
    }
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);
    // Ensure first scroll
    if (changed && viewPager != null) {
      scrollToTab(viewPager.getCurrentItem(), 0);
    }
  }

  /**
   * Set the behavior of the Indicator scrolling feedback.
   *
   * @param interpolator {@link com.ogaclejapan.smarttablayout.SmartTabIndicationInterpolator}
   */
  public void setIndicationInterpolator(SmartTabIndicationInterpolator interpolator) {
    tabStrip.setIndicationInterpolator(interpolator);
  }

  /**
   * Set the custom {@link TabColorizer} to be used.
   *
   * If you only require simple customisation then you can use
   * {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)} to achieve
   * similar effects.
   */
  public void setCustomTabColorizer(TabColorizer tabColorizer) {
    tabStrip.setCustomTabColorizer(tabColorizer);
  }

  /**
   * Set the color used for styling the tab text. This will need to be called prior to calling
   * {@link #setViewPager(ViewPager)} otherwise it will not get set
   *
   * @param color to use for tab text
   */
  public void setDefaultTabTextColor(int color) {
    tabViewTextColors = ColorStateList.valueOf(color);
  }

  /**
   * Sets the colors used for styling the tab text. This will need to be called prior to calling
   * {@link #setViewPager(ViewPager)} otherwise it will not get set
   *
   * @param colors ColorStateList to use for tab text
   */
  public void setDefaultTabTextColor(ColorStateList colors) {
    tabViewTextColors = colors;
  }

  /**
   * Set the same weight for tab
   */
  public void setDistributeEvenly(boolean distributeEvenly) {
    this.distributeEvenly = distributeEvenly;
  }

  /**
   * Sets the colors to be used for indicating the selected tab. These colors are treated as a
   * circular array. Providing one color will mean that all tabs are indicated with the same color.
   */
  public void setSelectedIndicatorColors(int... colors) {
    tabStrip.setSelectedIndicatorColors(colors);
  }

  /**
   * Sets the colors to be used for tab dividers. These colors are treated as a circular array.
   * Providing one color will mean that all tabs are indicated with the same color.
   */
  public void setDividerColors(int... colors) {
    tabStrip.setDividerColors(colors);
  }

  /**
   * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SmartTabLayout} you are
   * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so
   * that the layout can update it's scroll position correctly.
   *
   * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
   */
  public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
    viewPagerPageChangeListener = listener;
  }

  /**
   * Set {@link OnScrollChangeListener} for obtaining values of scrolling.
   *
   * @param listener the {@link OnScrollChangeListener} to set
   */
  public void setOnScrollChangeListener(OnScrollChangeListener listener) {
    onScrollChangeListener = listener;
  }

  /**
   * Set {@link OnTabClickListener} for obtaining click event.
   *
   * @param listener the {@link OnTabClickListener} to set
   */
  public void setOnTabClickListener(OnTabClickListener listener) {
    onTabClickListener = listener;
  }

  /**
   * Set the custom layout to be inflated for the tab views.
   *
   * @param layoutResId Layout id to be inflated
   * @param textViewId id of the {@link android.widget.TextView} in the inflated view
   */
  public void setCustomTabView(int layoutResId, int textViewId) {
    tabProvider = new SimpleTabProvider(getContext(), layoutResId, textViewId);
  }

  /**
   * Set the custom layout to be inflated for the tab views.
   *
   * @param provider {@link TabProvider}
   */
  public void setCustomTabView(TabProvider provider) {
    tabProvider = provider;
  }

  /**
   * Sets the associated view pager. Note that the assumption here is that the pager content
   * (number of tabs and tab titles) does not change after this call has been made.
   */
  public void setViewPager(ViewPager viewPager) {
    tabStrip.removeAllViews();

    this.viewPager = viewPager;
    if (viewPager != null && viewPager.getAdapter() != null) {
      viewPager.addOnPageChangeListener(new InternalViewPagerListener());
      populateTabStrip();
    }
  }

  /**
   * Returns the view at the specified position in the tabs.
   *
   * @param position the position at which to get the view from
   * @return the view at the specified position or null if the position does not exist within the
   * tabs
   */
  public View getTabAt(int position) {
    return tabStrip.getChildAt(position);
  }

  /**
   * Create a default view to be used for tabs. This is called if a custom tab view is not set via
   * {@link #setCustomTabView(int, int)}.
   */
  protected TextView createDefaultTabView(CharSequence title) {
    TextView textView = new TextView(getContext());
    textView.setGravity(Gravity.CENTER);
    textView.setText(title);
    textView.setTextColor(tabViewTextColors);
    textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabViewTextSize);
    textView.setTypeface(Typeface.DEFAULT_BOLD);
    textView.setLayoutParams(new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));

    if (tabViewBackgroundResId != NO_ID) {
      textView.setBackgroundResource(tabViewBackgroundResId);
    } else {
      // If we're running on Honeycomb or newer, then we can use the Theme's
      // selectableItemBackground to ensure that the View has a pressed state
      TypedValue outValue = new TypedValue();
      getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
          outValue, true);
      textView.setBackgroundResource(outValue.resourceId);
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
      // If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
      textView.setAllCaps(tabViewTextAllCaps);
    }

    textView.setPadding(
        tabViewTextHorizontalPadding, 0,
        tabViewTextHorizontalPadding, 0);

    if (tabViewTextMinWidth > 0) {
      textView.setMinWidth(tabViewTextMinWidth);
    }

    return textView;
  }

  private void populateTabStrip() {
    final PagerAdapter adapter = viewPager.getAdapter();

    for (int i = 0; i < adapter.getCount(); i++) {

      final View tabView = (tabProvider == null)
          ? createDefaultTabView(adapter.getPageTitle(i))
          : tabProvider.createTabView(tabStrip, i, adapter);

      if (tabView == null) {
        throw new IllegalStateException("tabView is null.");
      }

      if (distributeEvenly) {
        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams();
        lp.width = 0;
        lp.weight = 1;
      }

      if (internalTabClickListener != null) {
        tabView.setOnClickListener(internalTabClickListener);
      }

      tabStrip.addView(tabView);

      if (i == viewPager.getCurrentItem()) {
        tabView.setSelected(true);
      }

    }
  }

  private void scrollToTab(int tabIndex, float positionOffset) {
    final int tabStripChildCount = tabStrip.getChildCount();
    if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
      return;
    }

    final boolean isLayoutRtl = Utils.isLayoutRtl(this);
    View selectedTab = tabStrip.getChildAt(tabIndex);
    int widthPlusMargin = Utils.getWidth(selectedTab) + Utils.getMarginHorizontally(selectedTab);
    int extraOffset = (int) (positionOffset * widthPlusMargin);

    if (tabStrip.isIndicatorAlwaysInCenter()) {

      if (0f < positionOffset && positionOffset < 1f) {
        View nextTab = tabStrip.getChildAt(tabIndex + 1);
        int selectHalfWidth = Utils.getWidth(selectedTab) / 2 + Utils.getMarginEnd(selectedTab);
        int nextHalfWidth = Utils.getWidth(nextTab) / 2 + Utils.getMarginStart(nextTab);
        extraOffset = Math.round(positionOffset * (selectHalfWidth + nextHalfWidth));
      }

      View firstTab = tabStrip.getChildAt(0);
      int x;
      if (isLayoutRtl) {
        int first = Utils.getWidth(firstTab) + Utils.getMarginEnd(firstTab);
        int selected = Utils.getWidth(selectedTab) + Utils.getMarginEnd(selectedTab);
        x = Utils.getEnd(selectedTab) - Utils.getMarginEnd(selectedTab) - extraOffset;
        x -= (first - selected) / 2;
      } else {
        int first = Utils.getWidth(firstTab) + Utils.getMarginStart(firstTab);
        int selected = Utils.getWidth(selectedTab) + Utils.getMarginStart(selectedTab);
        x = Utils.getStart(selectedTab) - Utils.getMarginStart(selectedTab) + extraOffset;
        x -= (first - selected) / 2;
      }

      scrollTo(x, 0);
      return;

    }

    int x;
    if (titleOffset == TITLE_OFFSET_AUTO_CENTER) {

      if (0f < positionOffset && positionOffset < 1f) {
        View nextTab = tabStrip.getChildAt(tabIndex + 1);
        int selectHalfWidth = Utils.getWidth(selectedTab) / 2 + Utils.getMarginEnd(selectedTab);
        int nextHalfWidth = Utils.getWidth(nextTab) / 2 + Utils.getMarginStart(nextTab);
        extraOffset = Math.round(positionOffset * (selectHalfWidth + nextHalfWidth));
      }

      if (isLayoutRtl) {
        x = -Utils.getWidthWithMargin(selectedTab) / 2 + getWidth() / 2;
        x -= Utils.getPaddingStart(this);
      } else {
        x = Utils.getWidthWithMargin(selectedTab) / 2 - getWidth() / 2;
        x += Utils.getPaddingStart(this);
      }

    } else {

      if (isLayoutRtl) {
        x = (tabIndex > 0 || positionOffset > 0) ? titleOffset : 0;
      } else {
        x = (tabIndex > 0 || positionOffset > 0) ? -titleOffset : 0;
      }

    }

    int start = Utils.getStart(selectedTab);
    int startMargin = Utils.getMarginStart(selectedTab);
    if (isLayoutRtl) {
      x += start + startMargin - extraOffset - getWidth() + Utils.getPaddingHorizontally(this);
    } else {
      x += start - startMargin + extraOffset;
    }

    scrollTo(x, 0);

  }

  /**
   * Allows complete control over the colors drawn in the tab layout. Set with
   * {@link #setCustomTabColorizer(TabColorizer)}.
   */
  public interface TabColorizer {

    /**
     * @return return the color of the indicator used when {@code position} is selected.
     */
    int getIndicatorColor(int position);

    /**
     * @return return the color of the divider drawn to the right of {@code position}.
     */
    int getDividerColor(int position);

  }

  /**
   * Interface definition for a callback to be invoked when the scroll position of a view changes.
   */
  public interface OnScrollChangeListener {

    /**
     * Called when the scroll position of a view changes.
     *
     * @param scrollX Current horizontal scroll origin.
     * @param oldScrollX Previous horizontal scroll origin.
     */
    void onScrollChanged(int scrollX, int oldScrollX);
  }

  /**
   * Interface definition for a callback to be invoked when a tab is clicked.
   */
  public interface OnTabClickListener {

    /**
     * Called when a tab is clicked.
     *
     * @param position tab's position
     */
    void onTabClicked(int position);
  }

  /**
   * Create the custom tabs in the tab layout. Set with
   * {@link #setCustomTabView(com.ogaclejapan.smarttablayout.SmartTabLayout.TabProvider)}
   */
  public interface TabProvider {

    /**
     * @return Return the View of {@code position} for the Tabs
     */
    View createTabView(ViewGroup container, int position, PagerAdapter adapter);

  }

  private static class SimpleTabProvider implements TabProvider {

    private final LayoutInflater inflater;
    private final int tabViewLayoutId;
    private final int tabViewTextViewId;

    private SimpleTabProvider(Context context, int layoutResId, int textViewId) {
      inflater = LayoutInflater.from(context);
      tabViewLayoutId = layoutResId;
      tabViewTextViewId = textViewId;
    }

    @Override
    public View createTabView(ViewGroup container, int position, PagerAdapter adapter) {
      View tabView = null;
      TextView tabTitleView = null;

      if (tabViewLayoutId != NO_ID) {
        tabView = inflater.inflate(tabViewLayoutId, container, false);
      }

      if (tabViewTextViewId != NO_ID && tabView != null) {
        tabTitleView = (TextView) tabView.findViewById(tabViewTextViewId);
      }

      if (tabTitleView == null && TextView.class.isInstance(tabView)) {
        tabTitleView = (TextView) tabView;
      }

      if (tabTitleView != null) {
        tabTitleView.setText(adapter.getPageTitle(position));
      }

      return tabView;
    }

  }

  private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {

    private int scrollState;

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
      int tabStripChildCount = tabStrip.getChildCount();
      if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
        return;
      }

      tabStrip.onViewPagerPageChanged(position, positionOffset);

      scrollToTab(position, positionOffset);

      if (viewPagerPageChangeListener != null) {
        viewPagerPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
      }
    }

    @Override
    public void onPageScrollStateChanged(int state) {
      scrollState = state;

      if (viewPagerPageChangeListener != null) {
        viewPagerPageChangeListener.onPageScrollStateChanged(state);
      }
    }

    @Override
    public void onPageSelected(int position) {
      if (scrollState == ViewPager.SCROLL_STATE_IDLE) {
        tabStrip.onViewPagerPageChanged(position, 0f);
        scrollToTab(position, 0);
      }

      for (int i = 0, size = tabStrip.getChildCount(); i < size; i++) {
        tabStrip.getChildAt(i).setSelected(position == i);
      }

      if (viewPagerPageChangeListener != null) {
        viewPagerPageChangeListener.onPageSelected(position);
      }
    }

  }

  private class InternalTabClickListener implements OnClickListener {
    @Override
    public void onClick(View v) {
      for (int i = 0; i < tabStrip.getChildCount(); i++) {
        if (v == tabStrip.getChildAt(i)) {
          if (onTabClickListener != null) {
            onTabClickListener.onTabClicked(i);
          }
          viewPager.setCurrentItem(i);
          return;
        }
      }
    }
  }

}


================================================
FILE: library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabStrip.java
================================================
/**
 * Copyright (C) 2015 ogaclejapan
 * Copyright (C) 2013 The Android Open Source Project
 *
 * 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.
 */
package com.ogaclejapan.smarttablayout;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.widget.LinearLayout;

/**
 * <p>
 * Forked from Google Samples &gt; SlidingTabsBasic &gt;
 * <a href="https://developer.android.com/samples/SlidingTabsBasic/src/com.example.android.common/view/SlidingTabLayout.html">SlidingTabStrip</a>
 */
class SmartTabStrip extends LinearLayout {

  private static final int GRAVITY_BOTTOM = 0;
  private static final int GRAVITY_TOP = 1;
  private static final int GRAVITY_CENTER = 2;

  private static final int AUTO_WIDTH = -1;

  private static final int DEFAULT_TOP_BORDER_THICKNESS_DIPS = 0;
  private static final byte DEFAULT_TOP_BORDER_COLOR_ALPHA = 0x26;
  private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 2;
  private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;
  private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 8;
  private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5;
  private static final float DEFAULT_INDICATOR_CORNER_RADIUS = 0f;
  private static final int DEFAULT_DIVIDER_THICKNESS_DIPS = 1;
  private static final byte DEFAULT_DIVIDER_COLOR_ALPHA = 0x20;
  private static final float DEFAULT_DIVIDER_HEIGHT = 0.5f;
  private static final boolean DEFAULT_INDICATOR_IN_CENTER = false;
  private static final boolean DEFAULT_INDICATOR_IN_FRONT = false;
  private static final boolean DEFAULT_INDICATOR_WITHOUT_PADDING = false;
  private static final int DEFAULT_INDICATOR_GRAVITY = GRAVITY_BOTTOM;
  private static final boolean DEFAULT_DRAW_DECORATION_AFTER_TAB = false;

  private final int topBorderThickness;
  private final int topBorderColor;
  private final int bottomBorderThickness;
  private final int bottomBorderColor;
  private final Paint borderPaint;
  private final RectF indicatorRectF = new RectF();
  private final boolean indicatorWithoutPadding;
  private final boolean indicatorAlwaysInCenter;
  private final boolean indicatorInFront;
  private final int indicatorThickness;
  private final int indicatorWidth;
  private final int indicatorGravity;
  private final float indicatorCornerRadius;
  private final Paint indicatorPaint;
  private final int dividerThickness;
  private final Paint dividerPaint;
  private final float dividerHeight;
  private final SimpleTabColorizer defaultTabColorizer;
  private final boolean drawDecorationAfterTab;

  private int lastPosition;
  private int selectedPosition;
  private float selectionOffset;
  private SmartTabIndicationInterpolator indicationInterpolator;
  private SmartTabLayout.TabColorizer customTabColorizer;

  SmartTabStrip(Context context, AttributeSet attrs) {
    super(context);
    setWillNotDraw(false);

    final float density = getResources().getDisplayMetrics().density;

    TypedValue outValue = new TypedValue();
    context.getTheme().resolveAttribute(android.R.attr.colorForeground, outValue, true);
    final int themeForegroundColor = outValue.data;

    boolean indicatorWithoutPadding = DEFAULT_INDICATOR_WITHOUT_PADDING;
    boolean indicatorInFront = DEFAULT_INDICATOR_IN_FRONT;
    boolean indicatorAlwaysInCenter = DEFAULT_INDICATOR_IN_CENTER;
    int indicationInterpolatorId = SmartTabIndicationInterpolator.ID_SMART;
    int indicatorGravity = DEFAULT_INDICATOR_GRAVITY;
    int indicatorColor = DEFAULT_SELECTED_INDICATOR_COLOR;
    int indicatorColorsId = NO_ID;
    int indicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);
    int indicatorWidth = AUTO_WIDTH;
    float indicatorCornerRadius = DEFAULT_INDICATOR_CORNER_RADIUS * density;
    int overlineColor = setColorAlpha(themeForegroundColor, DEFAULT_TOP_BORDER_COLOR_ALPHA);
    int overlineThickness = (int) (DEFAULT_TOP_BORDER_THICKNESS_DIPS * density);
    int underlineColor = setColorAlpha(themeForegroundColor, DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);
    int underlineThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
    int dividerColor = setColorAlpha(themeForegroundColor, DEFAULT_DIVIDER_COLOR_ALPHA);
    int dividerColorsId = NO_ID;
    int dividerThickness = (int) (DEFAULT_DIVIDER_THICKNESS_DIPS * density);
    boolean drawDecorationAfterTab = DEFAULT_DRAW_DECORATION_AFTER_TAB;

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.stl_SmartTabLayout);
    indicatorAlwaysInCenter = a.getBoolean(
        R.styleable.stl_SmartTabLayout_stl_indicatorAlwaysInCenter, indicatorAlwaysInCenter);
    indicatorWithoutPadding = a.getBoolean(
        R.styleable.stl_SmartTabLayout_stl_indicatorWithoutPadding, indicatorWithoutPadding);
    indicatorInFront = a.getBoolean(
        R.styleable.stl_SmartTabLayout_stl_indicatorInFront, indicatorInFront);
    indicationInterpolatorId = a.getInt(
        R.styleable.stl_SmartTabLayout_stl_indicatorInterpolation, indicationInterpolatorId);
    indicatorGravity = a.getInt(
        R.styleable.stl_SmartTabLayout_stl_indicatorGravity, indicatorGravity);
    indicatorColor = a.getColor(
        R.styleable.stl_SmartTabLayout_stl_indicatorColor, indicatorColor);
    indicatorColorsId = a.getResourceId(
        R.styleable.stl_SmartTabLayout_stl_indicatorColors, indicatorColorsId);
    indicatorThickness = a.getDimensionPixelSize(
        R.styleable.stl_SmartTabLayout_stl_indicatorThickness, indicatorThickness);
    indicatorWidth = a.getLayoutDimension(
        R.styleable.stl_SmartTabLayout_stl_indicatorWidth, indicatorWidth);
    indicatorCornerRadius = a.getDimension(
        R.styleable.stl_SmartTabLayout_stl_indicatorCornerRadius, indicatorCornerRadius);
    overlineColor = a.getColor(
        R.styleable.stl_SmartTabLayout_stl_overlineColor, overlineColor);
    overlineThickness = a.getDimensionPixelSize(
        R.styleable.stl_SmartTabLayout_stl_overlineThickness, overlineThickness);
    underlineColor = a.getColor(
        R.styleable.stl_SmartTabLayout_stl_underlineColor, underlineColor);
    underlineThickness = a.getDimensionPixelSize(
        R.styleable.stl_SmartTabLayout_stl_underlineThickness, underlineThickness);
    dividerColor = a.getColor(
        R.styleable.stl_SmartTabLayout_stl_dividerColor, dividerColor);
    dividerColorsId = a.getResourceId(
        R.styleable.stl_SmartTabLayout_stl_dividerColors, dividerColorsId);
    dividerThickness = a.getDimensionPixelSize(
        R.styleable.stl_SmartTabLayout_stl_dividerThickness, dividerThickness);
    drawDecorationAfterTab = a.getBoolean(
        R.styleable.stl_SmartTabLayout_stl_drawDecorationAfterTab, drawDecorationAfterTab);
    a.recycle();

    final int[] indicatorColors = (indicatorColorsId == NO_ID)
        ? new int[] { indicatorColor }
        : getResources().getIntArray(indicatorColorsId);

    final int[] dividerColors = (dividerColorsId == NO_ID)
        ? new int[] { dividerColor }
        : getResources().getIntArray(dividerColorsId);

    this.defaultTabColorizer = new SimpleTabColorizer();
    this.defaultTabColorizer.setIndicatorColors(indicatorColors);
    this.defaultTabColorizer.setDividerColors(dividerColors);

    this.topBorderThickness = overlineThickness;
    this.topBorderColor = overlineColor;
    this.bottomBorderThickness = underlineThickness;
    this.bottomBorderColor = underlineColor;
    this.borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    this.indicatorAlwaysInCenter = indicatorAlwaysInCenter;
    this.indicatorWithoutPadding = indicatorWithoutPadding;
    this.indicatorInFront = indicatorInFront;
    this.indicatorThickness = indicatorThickness;
    this.indicatorWidth = indicatorWidth;
    this.indicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    this.indicatorCornerRadius = indicatorCornerRadius;
    this.indicatorGravity = indicatorGravity;

    this.dividerHeight = DEFAULT_DIVIDER_HEIGHT;
    this.dividerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    this.dividerPaint.setStrokeWidth(dividerThickness);
    this.dividerThickness = dividerThickness;

    this.drawDecorationAfterTab = drawDecorationAfterTab;

    this.indicationInterpolator = SmartTabIndicationInterpolator.of(indicationInterpolatorId);
  }

  /**
   * Set the alpha value of the {@code color} to be the given {@code alpha} value.
   */
  private static int setColorAlpha(int color, byte alpha) {
    return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
  }

  /**
   * Blend {@code color1} and {@code color2} using the given ratio.
   *
   * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
   * 0.0 will return {@code color2}.
   */
  private static int blendColors(int color1, int color2, float ratio) {
    final float inverseRation = 1f - ratio;
    float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
    float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
    float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
    return Color.rgb((int) r, (int) g, (int) b);
  }

  void setIndicationInterpolator(SmartTabIndicationInterpolator interpolator) {
    indicationInterpolator = interpolator;
    invalidate();
  }

  void setCustomTabColorizer(SmartTabLayout.TabColorizer customTabColorizer) {
    this.customTabColorizer = customTabColorizer;
    invalidate();
  }

  void setSelectedIndicatorColors(int... colors) {
    // Make sure that the custom colorizer is removed
    customTabColorizer = null;
    defaultTabColorizer.setIndicatorColors(colors);
    invalidate();
  }

  void setDividerColors(int... colors) {
    // Make sure that the custom colorizer is removed
    customTabColorizer = null;
    defaultTabColorizer.setDividerColors(colors);
    invalidate();
  }

  void onViewPagerPageChanged(int position, float positionOffset) {
    selectedPosition = position;
    selectionOffset = positionOffset;
    if (positionOffset == 0f && lastPosition != selectedPosition) {
      lastPosition = selectedPosition;
    }
    invalidate();
  }

  boolean isIndicatorAlwaysInCenter() {
    return indicatorAlwaysInCenter;
  }

  SmartTabLayout.TabColorizer getTabColorizer() {
    return (customTabColorizer != null) ? customTabColorizer : defaultTabColorizer;
  }

  @Override
  protected void onDraw(Canvas canvas) {
    if (!drawDecorationAfterTab) {
      drawDecoration(canvas);
    }
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(canvas);
    if (drawDecorationAfterTab) {
      drawDecoration(canvas);
    }
  }

  private void drawDecoration(Canvas canvas) {
    final int height = getHeight();
    final int width = getWidth();
    final int tabCount = getChildCount();
    final SmartTabLayout.TabColorizer tabColorizer = getTabColorizer();
    final boolean isLayoutRtl = Utils.isLayoutRtl(this);

    if (indicatorInFront) {
      drawOverline(canvas, 0, width);
      drawUnderline(canvas, 0, width, height);
    }

    // Thick colored underline below the current selection
    if (tabCount > 0) {
      View selectedTab = getChildAt(selectedPosition);
      int selectedStart = Utils.getStart(selectedTab, indicatorWithoutPadding);
      int selectedEnd = Utils.getEnd(selectedTab, indicatorWithoutPadding);
      int left;
      int right;
      if (isLayoutRtl) {
        left = selectedEnd;
        right = selectedStart;
      } else {
        left = selectedStart;
        right = selectedEnd;
      }

      int color = tabColorizer.getIndicatorColor(selectedPosition);
      float thickness = indicatorThickness;

      if (selectionOffset > 0f && selectedPosition < (getChildCount() - 1)) {
        int nextColor = tabColorizer.getIndicatorColor(selectedPosition + 1);
        if (color != nextColor) {
          color = blendColors(nextColor, color, selectionOffset);
        }

        // Draw the selection partway between the tabs
        float startOffset = indicationInterpolator.getLeftEdge(selectionOffset);
        float endOffset = indicationInterpolator.getRightEdge(selectionOffset);
        float thicknessOffset = indicationInterpolator.getThickness(selectionOffset);

        View nextTab = getChildAt(selectedPosition + 1);
        int nextStart = Utils.getStart(nextTab, indicatorWithoutPadding);
        int nextEnd = Utils.getEnd(nextTab, indicatorWithoutPadding);
        if (isLayoutRtl) {
          left = (int) (endOffset * nextEnd + (1.0f - endOffset) * left);
          right = (int) (startOffset * nextStart + (1.0f - startOffset) * right);
        } else {
          left = (int) (startOffset * nextStart + (1.0f - startOffset) * left);
          right = (int) (endOffset * nextEnd + (1.0f - endOffset) * right);
        }
        thickness = thickness * thicknessOffset;
      }

      drawIndicator(canvas, left, right, height, thickness, color);

    }

    if (!indicatorInFront) {
      drawOverline(canvas, 0, width);
      drawUnderline(canvas, 0, getWidth(), height);
    }

    // Vertical separators between the titles
    drawSeparator(canvas, height, tabCount);

  }

  private void drawSeparator(Canvas canvas, int height, int tabCount) {
    if (dividerThickness <= 0) {
      return;
    }

    final int dividerHeightPx = (int) (Math.min(Math.max(0f, dividerHeight), 1f) * height);
    final SmartTabLayout.TabColorizer tabColorizer = getTabColorizer();

    // Vertical separators between the titles
    final int separatorTop = (height - dividerHeightPx) / 2;
    final int separatorBottom = separatorTop + dividerHeightPx;

    final boolean isLayoutRtl = Utils.isLayoutRtl(this);
    for (int i = 0; i < tabCount - 1; i++) {
      View child = getChildAt(i);
      int end = Utils.getEnd(child);
      int endMargin = Utils.getMarginEnd(child);
      int separatorX = isLayoutRtl ? end - endMargin : end + endMargin;
      dividerPaint.setColor(tabColorizer.getDividerColor(i));
      canvas.drawLine(separatorX, separatorTop, separatorX, separatorBottom, dividerPaint);
    }
  }

  private void drawIndicator(Canvas canvas, int left, int right, int height, float thickness,
      int color) {
    if (indicatorThickness <= 0 || indicatorWidth == 0) {
      return;
    }

    float center;
    float top;
    float bottom;

    switch (indicatorGravity) {
      case GRAVITY_TOP:
        center = indicatorThickness / 2f;
        top = center - (thickness / 2f);
        bottom = center + (thickness / 2f);
        break;
      case GRAVITY_CENTER:
        center = height / 2f;
        top = center - (thickness / 2f);
        bottom = center + (thickness / 2f);
        break;
      case GRAVITY_BOTTOM:
      default:
        center = height - (indicatorThickness / 2f);
        top = center - (thickness / 2f);
        bottom = center + (thickness / 2f);
    }

    indicatorPaint.setColor(color);
    if (indicatorWidth == AUTO_WIDTH) {
      indicatorRectF.set(left, top, right, bottom);
    } else {
      float padding = (Math.abs(left - right) - indicatorWidth) / 2f;
      indicatorRectF.set(left + padding, top, right - padding, bottom);
    }

    if (indicatorCornerRadius > 0f) {
      canvas.drawRoundRect(
          indicatorRectF, indicatorCornerRadius,
          indicatorCornerRadius, indicatorPaint);
    } else {
      canvas.drawRect(indicatorRectF, indicatorPaint);
    }
  }

  private void drawOverline(Canvas canvas, int left, int right) {
    if (topBorderThickness <= 0) {
      return;
    }
    // Thin overline along the entire top edge
    borderPaint.setColor(topBorderColor);
    canvas.drawRect(left, 0, right, topBorderThickness, borderPaint);
  }

  private void drawUnderline(Canvas canvas, int left, int right, int height) {
    if (bottomBorderThickness <= 0) {
      return;
    }
    // Thin underline along the entire bottom edge
    borderPaint.setColor(bottomBorderColor);
    canvas.drawRect(left, height - bottomBorderThickness, right, height, borderPaint);
  }

  private static class SimpleTabColorizer implements SmartTabLayout.TabColorizer {

    private int[] indicatorColors;
    private int[] dividerColors;

    @Override
    public final int getIndicatorColor(int position) {
      return indicatorColors[position % indicatorColors.length];
    }

    @Override
    public final int getDividerColor(int position) {
      return dividerColors[position % dividerColors.length];
    }

    void setIndicatorColors(int... colors) {
      indicatorColors = colors;
    }

    void setDividerColors(int... colors) {
      dividerColors = colors;
    }
  }
}


================================================
FILE: library/src/main/java/com/ogaclejapan/smarttablayout/Utils.java
================================================
/**
 * Copyright (C) 2015 ogaclejapan
 * Copyright (C) 2013 The Android Open Source Project
 *
 * 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.
 */
package com.ogaclejapan.smarttablayout;

import android.view.View;
import android.view.ViewGroup;

import androidx.core.view.MarginLayoutParamsCompat;
import androidx.core.view.ViewCompat;

final class Utils {

  static int getMeasuredWidth(View v) {
    return (v == null) ? 0 : v.getMeasuredWidth();
  }

  static int getWidth(View v) {
    return (v == null) ? 0 : v.getWidth();
  }

  static int getWidthWithMargin(View v) {
    return getWidth(v) + getMarginHorizontally(v);
  }

  static int getStart(View v) {
    return getStart(v, false);
  }

  static int getStart(View v, boolean withoutPadding) {
    if (v == null) {
      return 0;
    }
    if (isLayoutRtl(v)) {
      return (withoutPadding) ? v.getRight() - getPaddingStart(v) : v.getRight();
    } else {
      return (withoutPadding) ? v.getLeft() + getPaddingStart(v) : v.getLeft();
    }
  }

  static int getEnd(View v) {
    return getEnd(v, false);
  }

  static int getEnd(View v, boolean withoutPadding) {
    if (v == null) {
      return 0;
    }
    if (isLayoutRtl(v)) {
      return (withoutPadding) ? v.getLeft() + getPaddingEnd(v) : v.getLeft();
    } else {
      return (withoutPadding) ? v.getRight() - getPaddingEnd(v) : v.getRight();
    }
  }

  static int getPaddingStart(View v) {
    if (v == null) {
      return 0;
    }
    return ViewCompat.getPaddingStart(v);
  }

  static int getPaddingEnd(View v) {
    if (v == null) {
      return 0;
    }
    return ViewCompat.getPaddingEnd(v);
  }

  static int getPaddingHorizontally(View v) {
    if (v == null) {
      return 0;
    }
    return v.getPaddingLeft() + v.getPaddingRight();
  }

  static int getMarginStart(View v) {
    if (v == null) {
      return 0;
    }
    ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
    return MarginLayoutParamsCompat.getMarginStart(lp);
  }

  static int getMarginEnd(View v) {
    if (v == null) {
      return 0;
    }
    ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
    return MarginLayoutParamsCompat.getMarginEnd(lp);
  }

  static int getMarginHorizontally(View v) {
    if (v == null) {
      return 0;
    }
    ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
    return MarginLayoutParamsCompat.getMarginStart(lp) + MarginLayoutParamsCompat.getMarginEnd(lp);
  }

  static boolean isLayoutRtl(View v) {
    return ViewCompat.getLayoutDirection(v) == ViewCompat.LAYOUT_DIRECTION_RTL;
  }

  private Utils() { }

}


================================================
FILE: library/src/main/res/values/attrs.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="stl_SmartTabLayout">
    <attr name="stl_indicatorAlwaysInCenter" format="boolean"/>
    <attr name="stl_indicatorWithoutPadding" format="boolean"/>
    <attr name="stl_indicatorInFront" format="boolean"/>
    <attr name="stl_indicatorInterpolation" format="enum">
      <enum name="smart" value="0"/>
      <enum name="linear" value="1"/>
    </attr>
    <attr name="stl_indicatorGravity" format="enum">
      <enum name="bottom" value="0"/>
      <enum name="top" value="1"/>
      <enum name="center" value="2"/>
    </attr>
    <attr name="stl_indicatorColor" format="color"/>
    <attr name="stl_indicatorColors" format="reference"/>
    <attr name="stl_indicatorThickness" format="dimension"/>
    <attr name="stl_indicatorWidth" format="dimension">
      <enum name="auto" value="-1"/>
    </attr>
    <attr name="stl_indicatorCornerRadius" format="dimension"/>
    <attr name="stl_overlineColor" format="color"/>
    <attr name="stl_overlineThickness" format="dimension"/>
    <attr name="stl_underlineColor" format="color"/>
    <attr name="stl_underlineThickness" format="dimension"/>
    <attr name="stl_dividerColor" format="color"/>
    <attr name="stl_dividerColors" format="reference"/>
    <attr name="stl_dividerThickness" format="dimension"/>
    <attr name="stl_defaultTabBackground" format="reference"/>
    <attr name="stl_defaultTabTextAllCaps" format="boolean"/>
    <attr name="stl_defaultTabTextColor" format="color|reference"/>
    <attr name="stl_defaultTabTextSize" format="dimension"/>
    <attr name="stl_defaultTabTextHorizontalPadding" format="dimension"/>
    <attr name="stl_defaultTabTextMinWidth" format="dimension"/>
    <attr name="stl_customTabTextLayoutId" format="reference"/>
    <attr name="stl_customTabTextViewId" format="reference"/>
    <attr name="stl_distributeEvenly" format="boolean"/>
    <attr name="stl_clickable" format="boolean"/>
    <attr name="stl_titleOffset" format="dimension">
      <enum name="auto_center" value="-1"/>
    </attr>
    <attr name="stl_drawDecorationAfterTab" format="boolean"/>
  </declare-styleable>
</resources>


================================================
FILE: publish.gradle
================================================
apply plugin: 'com.jfrog.bintray'
apply plugin: 'com.github.dcendents.android-maven'


// build a jar with source files
task sourcesJar(type: Jar) {
  from android.sourceSets.main.java.srcDirs
  classifier = 'sources'
}

task javadoc(type: Javadoc) {
  failOnError false
  source = android.sourceSets.main.java.sourceFiles
  classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
  classpath += configurations.compile
}

// build a jar with javadoc
task javadocJar(type: Jar, dependsOn: javadoc) {
  classifier = 'javadoc'
  from javadoc.destinationDir
}

artifacts {
  archives sourcesJar
  archives javadocJar
}

install {
  repositories.mavenInstaller {
    // This generates POM.xml with proper parameters
    pom {
      project {
        packaging 'aar'

        name ARTIFACT_NAME
        description ARTIFACT_DESCRIPTION
        url SITE_URL

        licenses {
          license {
            name LICENCE_NAME
            url LICENCE_URL
            distribution LICENCE_DIST
          }
        }

        developers {
          developer {
            id DEVELOPER_ID
            name DEVELOPER_NAME
            email DEVELOPER_EMAIL
          }
        }
        issueManagement {
          system ISSUE_SYSTEM
          url ISSUE_URL
        }

        scm {
          connection SCM_CONNECTION
          developerConnection SCM_DEV_CONNECTION
          url SCM_URL

        }
      }
    }
  }
}

bintray {

  user = findProperty('BINTRAY_USER')
  key = findProperty('BINTRAY_APIKEY')

  configurations = ['archives']

  dryRun = false
  publish = true

  pkg {
    repo = "maven"
    name = pkginfo.name
    desc = pkginfo.description
    websiteUrl = pkginfo.site
    issueTrackerUrl = pkginfo.issue
    vcsUrl = pkginfo.vcs
    licenses = ["Apache-2.0"]
    labels = ['android']
    publicDownloadNumbers = true

    version {
      gpg {
        sign = true
        passphrase = findProperty('BINTRAY_GPG_PASSPHRASE')
      }

      mavenCentralSync {
        sync = true
        user = findProperty('NEXUS_USER')
        password = findProperty('NEXUS_PASSWORD')
        close = '1'
      }
    }
  }
}


================================================
FILE: settings.gradle
================================================
include ':demo', ':library', ':utils-v4'


================================================
FILE: utils-v4/.gitignore
================================================
/build


================================================
FILE: utils-v4/LICENSE
================================================
Copyright (C) 2015 ogaclejapan

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.


================================================
FILE: utils-v4/build.gradle
================================================
apply plugin: 'com.android.library'
apply plugin: 'com.github.ben-manes.versions'
apply plugin: 'com.github.hierynomus.license'

android {
  compileSdkVersion COMPILE_SDK_VERSION as int

  defaultConfig {
    minSdkVersion 14
    targetSdkVersion COMPILE_SDK_VERSION as int
    versionCode VERSION_CODE as int
    versionName VERSION_NAME

  }
  buildTypes {
    release {
      minifyEnabled false
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
  }
}

dependencies {
  implementation "androidx.fragment:fragment:${ANDROIDX_BASE_VERSION}"
}

license {

  sourceSets {
    main.java.srcDirs = android.sourceSets.main.java.srcDirs
    main.resources.srcDirs = android.sourceSets.main.resources.srcDirs
  }

  ext.year = Calendar.getInstance().get(Calendar.YEAR)
  ext.name = DEVELOPER_ID

}

pkginfo.name = ARTIFACT_NAME + '-V4Utils'
apply from: "${project.rootDir}/publish.gradle"


================================================
FILE: utils-v4/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/msk/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: utils-v4/src/main/AndroidManifest.xml
================================================
<manifest package="com.ogaclejapan.smarttablayout.utils">

</manifest>


================================================
FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/PagerItem.java
================================================
/**
 * Copyright (C) 2015 ogaclejapan
 *
 * 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.
 */
package com.ogaclejapan.smarttablayout.utils;

public abstract class PagerItem {

  protected static final float DEFAULT_WIDTH = 1.f;

  private final CharSequence title;
  private final float width;

  protected PagerItem(CharSequence title, float width) {
    this.title = title;
    this.width = width;
  }

  public CharSequence getTitle() {
    return title;
  }

  public float getWidth() {
    return width;
  }

}


================================================
FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/PagerItems.java
================================================
/**
 * Copyright (C) 2015 ogaclejapan
 *
 * 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.
 */
package com.ogaclejapan.smarttablayout.utils;

import android.content.Context;

import java.util.ArrayList;

public abstract class PagerItems<T extends PagerItem> extends ArrayList<T> {

  private final Context context;

  protected PagerItems(Context context) {
    this.context = context;
  }

  public Context getContext() {
    return context;
  }

}


================================================
FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/ViewPagerItem.java
================================================
/**
 * Copyright (C) 2015 ogaclejapan
 *
 * 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.
 */
package com.ogaclejapan.smarttablayout.utils;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.LayoutRes;

public class ViewPagerItem extends PagerItem {

  private final int resource;

  protected ViewPagerItem(CharSequence title, float width, @LayoutRes int resource) {
    super(title, width);
    this.resource = resource;
  }

  public static ViewPagerItem of(CharSequence title, @LayoutRes int resource) {
    return of(title, DEFAULT_WIDTH, resource);
  }

  public static ViewPagerItem of(CharSequence title, float width, @LayoutRes int resource) {
    return new ViewPagerItem(title, width, resource);
  }

  public View initiate(LayoutInflater inflater, ViewGroup container) {
    return inflater.inflate(resource, container, false);
  }

}


================================================
FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/ViewPagerItemAdapter.java
================================================
/**
 * Copyright (C) 2015 ogaclejapan
 *
 * 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.
 */
package com.ogaclejapan.smarttablayout.utils;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.lang.ref.WeakReference;

import androidx.annotation.NonNull;
import androidx.collection.SparseArrayCompat;
import androidx.viewpager.widget.PagerAdapter;

public class ViewPagerItemAdapter extends PagerAdapter {

  private final ViewPagerItems pages;
  private final SparseArrayCompat<WeakReference<View>> holder;
  private final LayoutInflater inflater;

  public ViewPagerItemAdapter(ViewPagerItems pages) {
    this.pages = pages;
    this.holder = new SparseArrayCompat<>(pages.size());
    this.inflater = LayoutInflater.from(pages.getContext());
  }

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

  @NonNull
  @Override
  public Object instantiateItem(@NonNull ViewGroup container, int position) {
    View view = getPagerItem(position).initiate(inflater, container);
    container.addView(view);
    holder.put(position, new WeakReference<View>(view));
    return view;
  }

  @Override
  public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
    holder.remove(position);
    container.removeView((View) object);
  }

  @Override
  public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
    return object == view;
  }

  @Override
  public CharSequence getPageTitle(int position) {
    return getPagerItem(position).getTitle();
  }

  @Override
  public float getPageWidth(int position) {
    return getPagerItem(position).getWidth();
  }

  public View getPage(int position) {
    final WeakReference<View> weakRefItem = holder.get(position);
    return (weakRefItem != null) ? weakRefItem.get() : null;
  }

  protected ViewPagerItem getPagerItem(int position) {
    return pages.get(position);
  }
}


================================================
FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/ViewPagerItems.java
================================================
/**
 * Copyright (C) 2015 ogaclejapan
 *
 * 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.
 */
package com.ogaclejapan.smarttablayout.utils;

import android.content.Context;

import androidx.annotation.LayoutRes;
import androidx.annotation.StringRes;

public class ViewPagerItems extends PagerItems<ViewPagerItem> {

  public ViewPagerItems(Context context) {
    super(context);
  }

  public static Creator with(Context context) {
    return new Creator(context);
  }

  public static class Creator {

    private final ViewPagerItems items;

    public Creator(Context context) {
      items = new ViewPagerItems(context);
    }

    public Creator add(@StringRes int title, @LayoutRes int resource) {
      return add(ViewPagerItem.of(items.getContext().getString(title), resource));
    }

    public Creator add(@StringRes int title, float width, @LayoutRes int resource) {
      return add(ViewPagerItem.of(items.getContext().getString(title), width, resource));
    }

    public Creator add(CharSequence title, @LayoutRes int resource) {
      return add(ViewPagerItem.of(title, resource));
    }

    public Creator add(ViewPagerItem item) {
      items.add(item);
      return this;
    }

    public ViewPagerItems create() {
      return items;
    }

  }

}


================================================
FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/Bundler.java
================================================
/**
 * Copyright (C) 2015 ogaclejapan
 *
 * 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.
 */
package com.ogaclejapan.smarttablayout.utils.v4;

import android.annotation.TargetApi;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcelable;
import android.util.Size;
import android.util.SizeF;
import android.util.SparseArray;

import java.io.Serializable;
import java.util.ArrayList;

import androidx.fragment.app.Fragment;

public class Bundler {

  private final Bundle bundle;

  /**
   * Constructs a new, empty Bundle.
   */
  public Bundler() {
    this(null);
  }

  private Bundler(Bundle b) {
    bundle = (b == null) ? new Bundle() : new Bundle(b);
  }

  /**
   * Constructs a Bundle containing a copy of the mappings from the given
   * Bundle.
   *
   * @param b a Bundle to be copied.
   */
  public static Bundler of(Bundle b) {
    return new Bundler(b);
  }

  /**
   * Inserts all mappings from the given Bundle into this Bundle.
   *
   * @param bundle a Bundle
   * @return this
   */
  public Bundler putAll(Bundle bundle) {
    this.bundle.putAll(bundle);
    return this;
  }

  /**
   * Inserts a byte value into the mapping of this Bundle, replacing
   * any existing value for the given key.
   *
   * @param key a String, or null
   * @param value a byte
   * @return this
   */
  public Bundler putByte(String key, byte value) {
    bundle.putByte(key, value);
    return this;
  }

  /**
   * Inserts a char value into the mapping of this Bundle, replacing
   * any existing value for the given key.
   *
   * @param key a String, or null
   * @param value a char, or null
   * @return this
   */
  public Bundler putChar(String key, char value) {
    bundle.putChar(key, value);
    return this;
  }

  /**
   * Inserts a short value into the mapping of this Bundle, replacing
   * any existing value for the given key.
   *
   * @param key a String, or null
   * @param value a short
   * @return this
   */
  public Bundler putShort(String key, short value) {
    bundle.putShort(key, value);
    return this;
  }

  /**
   * Inserts a float value into the mapping of this Bundle, replacing
   * any existing value for the given key.
   *
   * @param key a String, or null
   * @param value a float
   * @return this
   */
  public Bundler putFloat(String key, float value) {
    bundle.putFloat(key, value);
    return this;
  }

  /**
   * Inserts a CharSequence value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a CharSequence, or null
   * @return this
   */
  public Bundler putCharSequence(String key, CharSequence value) {
    bundle.putCharSequence(key, value);
    return this;
  }

  /**
   * Inserts a Parcelable value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a Parcelable object, or null
   * @return this
   */
  public Bundler putParcelable(String key, Parcelable value) {
    bundle.putParcelable(key, value);
    return this;
  }

  /**
   * Inserts a Size value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a Size object, or null
   * @return this
   */
  @TargetApi(21)
  public Bundler putSize(String key, Size value) {
    bundle.putSize(key, value);
    return this;
  }

  /**
   * Inserts a SizeF value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a SizeF object, or null
   * @return this
   */
  @TargetApi(21)
  public Bundler putSizeF(String key, SizeF value) {
    bundle.putSizeF(key, value);
    return this;
  }

  /**
   * Inserts an array of Parcelable values into the mapping of this Bundle,
   * replacing any existing value for the given key.  Either key or value may
   * be null.
   *
   * @param key a String, or null
   * @param value an array of Parcelable objects, or null
   * @return this
   */
  public Bundler putParcelableArray(String key, Parcelable[] value) {
    bundle.putParcelableArray(key, value);
    return this;
  }

  /**
   * Inserts a List of Parcelable values into the mapping of this Bundle,
   * replacing any existing value for the given key.  Either key or value may
   * be null.
   *
   * @param key a String, or null
   * @param value an ArrayList of Parcelable objects, or null
   * @return this
   */
  public Bundler putParcelableArrayList(String key,
      ArrayList<? extends Parcelable> value) {
    bundle.putParcelableArrayList(key, value);
    return this;
  }

  /**
   * Inserts a SparceArray of Parcelable values into the mapping of this
   * Bundle, replacing any existing value for the given key.  Either key
   * or value may be null.
   *
   * @param key a String, or null
   * @param value a SparseArray of Parcelable objects, or null
   * @return this
   */
  public Bundler putSparseParcelableArray(String key,
      SparseArray<? extends Parcelable> value) {
    bundle.putSparseParcelableArray(key, value);
    return this;
  }

  /**
   * Inserts an ArrayList<Integer> value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value an ArrayList<Integer> object, or null
   * @return this
   */
  public Bundler putIntegerArrayList(String key, ArrayList<Integer> value) {
    bundle.putIntegerArrayList(key, value);
    return this;
  }

  /**
   * Inserts an ArrayList<String> value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value an ArrayList<String> object, or null
   * @return this
   */
  public Bundler putStringArrayList(String key, ArrayList<String> value) {
    bundle.putStringArrayList(key, value);
    return this;
  }

  /**
   * Inserts an ArrayList<CharSequence> value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value an ArrayList<CharSequence> object, or null
   * @return this
   */
  @TargetApi(8)
  public Bundler putCharSequenceArrayList(String key, ArrayList<CharSequence> value) {
    bundle.putCharSequenceArrayList(key, value);
    return this;
  }

  /**
   * Inserts a Serializable value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a Serializable object, or null
   * @return this
   */
  public Bundler putSerializable(String key, Serializable value) {
    bundle.putSerializable(key, value);
    return this;
  }

  /**
   * Inserts a byte array value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a byte array object, or null
   * @return this
   */
  public Bundler putByteArray(String key, byte[] value) {
    bundle.putByteArray(key, value);
    return this;
  }

  /**
   * Inserts a short array value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a short array object, or null
   * @return this
   */
  public Bundler putShortArray(String key, short[] value) {
    bundle.putShortArray(key, value);
    return this;
  }

  /**
   * Inserts a char array value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a char array object, or null
   * @return this
   */
  public Bundler putCharArray(String key, char[] value) {
    bundle.putCharArray(key, value);
    return this;
  }

  /**
   * Inserts a float array value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a float array object, or null
   * @return this
   */
  public Bundler putFloatArray(String key, float[] value) {
    bundle.putFloatArray(key, value);
    return this;
  }

  /**
   * Inserts a CharSequence array value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a CharSequence array object, or null
   * @return this
   */
  @TargetApi(8)
  public Bundler putCharSequenceArray(String key, CharSequence[] value) {
    bundle.putCharSequenceArray(key, value);
    return this;
  }

  /**
   * Inserts a Bundle value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a Bundle object, or null
   * @return this
   */
  public Bundler putBundle(String key, Bundle value) {
    bundle.putBundle(key, value);
    return this;
  }

  /**
   * Inserts an {@link android.os.IBinder} value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * <p class="note">You should be very careful when using this function.  In many
   * places where Bundles are used (such as inside of Intent objects), the Bundle
   * can live longer inside of another process than the process that had originally
   * created it.  In that case, the IBinder you supply here will become invalid
   * when your process goes away, and no longer usable, even if a new process is
   * created for you later on.</p>
   *
   * @param key a String, or null
   * @param value an IBinder object, or null
   * @return this
   */
  @TargetApi(18)
  public Bundler putBinder(String key, IBinder value) {
    bundle.putBinder(key, value);
    return this;
  }

  /**
   * Inserts a Boolean value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a Boolean, or null
   * @return this
   */
  public Bundler putBoolean(String key, boolean value) {
    bundle.putBoolean(key, value);
    return this;
  }

  /**
   * Inserts an int value into the mapping of this Bundle, replacing
   * any existing value for the given key.
   *
   * @param key a String, or null
   * @param value an int, or null
   * @return this
   */
  public Bundler putInt(String key, int value) {
    bundle.putInt(key, value);
    return this;
  }

  /**
   * Inserts a long value into the mapping of this Bundle, replacing
   * any existing value for the given key.
   *
   * @param key a String, or null
   * @param value a long
   * @return this
   */
  public Bundler putLong(String key, long value) {
    bundle.putLong(key, value);
    return this;
  }

  /**
   * Inserts a double value into the mapping of this Bundle, replacing
   * any existing value for the given key.
   *
   * @param key a String, or null
   * @param value a double
   * @return this
   */
  public Bundler putDouble(String key, double value) {
    bundle.putDouble(key, value);
    return this;
  }

  /**
   * Inserts a String value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a String, or null
   * @return this
   */
  public Bundler putString(String key, String value) {
    bundle.putString(key, value);
    return this;
  }

  /**
   * Inserts a boolean array value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a boolean array object, or null
   * @return this
   */
  public Bundler putBooleanArray(String key, boolean[] value) {
    bundle.putBooleanArray(key, value);
    return this;
  }

  /**
   * Inserts an int array value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value an int array object, or null
   * @return this
   */
  public Bundler putIntArray(String key, int[] value) {
    bundle.putIntArray(key, value);
    return this;
  }

  /**
   * Inserts a long array value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a long array object, or null
   * @return this
   */
  public Bundler putLongArray(String key, long[] value) {
    bundle.putLongArray(key, value);
    return this;
  }

  /**
   * Inserts a double array value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a double array object, or null
   * @return this
   */
  public Bundler putDoubleArray(String key, double[] value) {
    bundle.putDoubleArray(key, value);
    return this;
  }

  /**
   * Inserts a String array value into the mapping of this Bundle, replacing
   * any existing value for the given key.  Either key or value may be null.
   *
   * @param key a String, or null
   * @param value a String array object, or null
   * @return this
   */
  public Bundler putStringArray(String key, String[] value) {
    bundle.putStringArray(key, value);
    return this;
  }

  /**
   * Get the bundle.
   *
   * @return a bundle
   */
  public Bundle get() {
    return bundle;
  }

  /**
   * Set the argument of Fragment.
   *
   * @param fragment a fragment
   * @return a fragment
   */
  public <T extends Fragment> T into(T fragment) {
    fragment.setArguments(get());
    return fragment;
  }

}


================================================
FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentPagerItem.java
================================================
/**
 * Copyright (C) 2015 ogaclejapan
 *
 * 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.
 */
package com.ogaclejapan.smarttablayout.utils.v4;

import android.content.Context;
import android.os.Bundle;

import com.ogaclejapan.smarttablayout.utils.PagerItem;

import androidx.fragment.app.Fragment;

public class FragmentPagerItem extends PagerItem {

  private static final String TAG = "FragmentPagerItem";
  private static final String KEY_POSITION = TAG + ":Position";

  private final String className;
  private final Bundle args;

  protected FragmentPagerItem(CharSequence title, float width, String className, Bundle args) {
    super(title, width);
    this.className = className;
    this.args = args;
  }

  public static FragmentPagerItem of(CharSequence title, Class<? extends Fragment> clazz) {
    return of(title, DEFAULT_WIDTH, clazz);
  }

  public static FragmentPagerItem of(CharSequence title, Class<? extends Fragment> clazz,
      Bundle args) {
    return of(title, DEFAULT_WIDTH, clazz, args);
  }

  public static FragmentPagerItem of(CharSequence title, float width,
      Class<? extends Fragment> clazz) {
    return of(title, width, clazz, new Bundle());
  }

  public static FragmentPagerItem of(CharSequence title, float width,
      Class<? extends Fragment> clazz, Bundle args) {
    return new FragmentPagerItem(title, width, clazz.getName(), args);
  }

  public static boolean hasPosition(Bundle args) {
    return args != null && args.containsKey(KEY_POSITION);
  }

  public static int getPosition(Bundle args) {
    return (hasPosition(args)) ? args.getInt(KEY_POSITION) : 0;
  }

  static void setPosition(Bundle args, int position) {
    args.putInt(KEY_POSITION, position);
  }

  public Fragment instantiate(Context context, int position) {
    setPosition(args, position);
    return Fragment.instantiate(context, className, args);
  }

}


================================================
FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentPagerItemAdapter.java
================================================
/**
 * Copyright (C) 2015 ogaclejapan
 *
 * 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.
 */
package com.ogaclejapan.smarttablayout.utils.v4;

import android.view.ViewGroup;

import java.lang.ref.WeakReference;

import androidx.annotation.NonNull;
import androidx.collection.SparseArrayCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;

public class FragmentPagerItemAdapter extends FragmentPagerAdapter {

  private final FragmentPagerItems pages;
  private final SparseArrayCompat<WeakReference<Fragment>> holder;

  public FragmentPagerItemAdapter(FragmentManager fm, FragmentPagerItems pages) {
    super(fm);
    this.pages = pages;
    this.holder = new SparseArrayCompat<>(pages.size());
  }

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

  @Override
  public Fragment getItem(int position) {
    return getPagerItem(position).instantiate(pages.getContext(), position);
  }

  @NonNull
  @Override
  public Object instantiateItem(@NonNull ViewGroup container, int position) {
    Object item = super.instantiateItem(container, position);
    if (item instanceof Fragment) {
      holder.put(position, new WeakReference<Fragment>((Fragment) item));
    }
    return item;
  }

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

  @Override
  public CharSequence getPageTitle(int position) {
    return getPagerItem(position).getTitle();
  }

  @Override
  public float getPageWidth(int position) {
    return super.getPageWidth(position);
  }

  public Fragment getPage(int position) {
    final WeakReference<Fragment> weakRefItem = holder.get(position);
    return (weakRefItem != null) ? weakRefItem.get() : null;
  }

  protected FragmentPagerItem getPagerItem(int position) {
    return pages.get(position);
  }

}


================================================
FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentPagerItems.java
================================================
/**
 * Copyright (C) 2015 ogaclejapan
 *
 * 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.
 */
package com.ogaclejapan.smarttablayout.utils.v4;

import android.content.Context;
import android.os.Bundle;

import com.ogaclejapan.smarttablayout.utils.PagerItems;

import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;

public class FragmentPagerItems extends PagerItems<FragmentPagerItem> {

  public FragmentPagerItems(Context context) {
    super(context);
  }

  public static Creator with(Context context) {
    return new Creator(context);
  }

  public static class Creator {

    private final FragmentPagerItems items;

    public Creator(Context context) {
      items = new FragmentPagerItems(context);
    }

    public Creator add(@StringRes int title, Class<? extends Fragment> clazz) {
      return add(FragmentPagerItem.of(items.getContext().getString(title), clazz));
    }

    public Creator add(@StringRes int title, Class<? extends Fragment> clazz, Bundle args) {
      return add(FragmentPagerItem.of(items.getContext().getString(title), clazz, args));
    }

    public Creator add(@StringRes int title, float width, Class<? extends Fragment> clazz) {
      return add(FragmentPagerItem.of(items.getContext().getString(title), width, clazz));
    }

    public Creator add(@StringRes int title, float width, Class<? extends Fragment> clazz,
        Bundle args) {
      return add(FragmentPagerItem.of(items.getContext().getString(title), width, clazz, args));
    }

    public Creator add(CharSequence title, Class<? extends Fragment> clazz) {
      return add(FragmentPagerItem.of(title, clazz));
    }

    public Creator add(CharSequence title, Class<? extends Fragment> clazz, Bundle args) {
      return add(FragmentPagerItem.of(title, clazz, args));
    }

    public Creator add(FragmentPagerItem item) {
      items.add(item);
      return this;
    }

    public FragmentPagerItems create() {
      return items;
    }

  }

}


================================================
FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentStatePagerItemAdapter.java
================================================
/**
 * Copyright (C) 2015 ogaclejapan
 *
 * 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.
 */
package com.ogaclejapan.smarttablayout.utils.v4;

import android.view.ViewGroup;

import java.lang.ref.WeakReference;

import androidx.annotation.NonNull;
import androidx.collection.SparseArrayCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;

public class FragmentStatePagerItemAdapter extends FragmentStatePagerAdapter {

  private final FragmentPagerItems pages;
  private final SparseArrayCompat<WeakReference<Fragment>> holder;

  public FragmentStatePagerItemAdapter(FragmentManager fm, FragmentPagerItems pages) {
    super(fm);
    this.pages = pages;
    this.holder = new SparseArrayCompat<>(pages.size());
  }

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

  @Override
  public Fragment getItem(int position) {
    return getPagerItem(position).instantiate(pages.getContext(), position);
  }

  @NonNull
  @Override
  public Object instantiateItem(@NonNull ViewGroup container, int position) {
    Object item = super.instantiateItem(container, position);
    if (item instanceof Fragment) {
      holder.put(position, new WeakReference<Fragment>((Fragment) item));
    }
    return item;
  }

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

  @Override
  public CharSequence getPageTitle(int position) {
    return getPagerItem(position).getTitle();
  }

  @Override
  public float getPageWidth(int position) {
    return getPagerItem(position).getWidth();
  }

  public Fragment getPage(int position) {
    final WeakReference<Fragment> weakRefItem = holder.get(position);
    return (weakRefItem != null) ? weakRefItem.get() : null;
  }

  protected FragmentPagerItem getPagerItem(int position) {
    return pages.get(position);
  }

}
Download .txt
gitextract_8nyfmi02/

├── .gitignore
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── README.md
├── build.gradle
├── demo/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── ogaclejapan/
│           │           └── smarttablayout/
│           │               └── demo/
│           │                   ├── Demo.java
│           │                   ├── DemoActivity.java
│           │                   ├── DemoFragment.java
│           │                   ├── DemoLikeMediumActivity.java
│           │                   ├── DemoRtlActivity.java
│           │                   ├── DemoTabWithNotificationMarkActivity.java
│           │                   ├── MainActivity.java
│           │                   └── TintableImageView.java
│           └── res/
│               ├── color/
│               │   ├── custom_tab.xml
│               │   ├── custom_tab_icon.xml
│               │   └── custom_tab_like_a_medium.xml
│               ├── drawable/
│               │   ├── custom_circle.xml
│               │   ├── custom_icon.xml
│               │   ├── custom_tab.xml
│               │   └── shape_notification_mark.xml
│               ├── layout/
│               │   ├── activity_demo.xml
│               │   ├── activity_demo_tab_with_notification_mark.xml
│               │   ├── activity_like_a_medium.xml
│               │   ├── activity_main.xml
│               │   ├── activity_rtl.xml
│               │   ├── custom_tab.xml
│               │   ├── custom_tab_circle.xml
│               │   ├── custom_tab_icon1.xml
│               │   ├── custom_tab_icon2.xml
│               │   ├── custom_tab_icon_and_notification_mark.xml
│               │   ├── custom_tab_icon_and_text.xml
│               │   ├── custom_tab_like_a_medium.xml
│               │   ├── custom_tab_margin.xml
│               │   ├── demo_always_in_center.xml
│               │   ├── demo_basic.xml
│               │   ├── demo_basic_title_offset_auto_center.xml
│               │   ├── demo_custom_tab_colors.xml
│               │   ├── demo_custom_tab_icon_and_notification_mark.xml
│               │   ├── demo_custom_tab_icon_and_text.xml
│               │   ├── demo_custom_tab_icons1.xml
│               │   ├── demo_custom_tab_icons2.xml
│               │   ├── demo_custom_tab_margin.xml
│               │   ├── demo_custom_tab_text.xml
│               │   ├── demo_distribute_evenly.xml
│               │   ├── demo_indicator_trick1.xml
│               │   ├── demo_indicator_trick2.xml
│               │   ├── demo_like_a_medium_tag.xml
│               │   ├── demo_rtl.xml
│               │   ├── demo_smart_indicator.xml
│               │   └── fragment_demo.xml
│               ├── menu/
│               │   ├── menu_demo.xml
│               │   └── menu_main.xml
│               └── values/
│                   ├── attrs.xml
│                   ├── colors.xml
│                   ├── dimens.xml
│                   ├── ids.xml
│                   ├── strings.xml
│                   └── styles.xml
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── library/
│   ├── .gitignore
│   ├── LICENSE
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── ogaclejapan/
│           │           └── smarttablayout/
│           │               ├── SmartTabIndicationInterpolator.java
│           │               ├── SmartTabLayout.java
│           │               ├── SmartTabStrip.java
│           │               └── Utils.java
│           └── res/
│               └── values/
│                   └── attrs.xml
├── publish.gradle
├── settings.gradle
└── utils-v4/
    ├── .gitignore
    ├── LICENSE
    ├── build.gradle
    ├── proguard-rules.pro
    └── src/
        └── main/
            ├── AndroidManifest.xml
            └── java/
                └── com/
                    └── ogaclejapan/
                        └── smarttablayout/
                            └── utils/
                                ├── PagerItem.java
                                ├── PagerItems.java
                                ├── ViewPagerItem.java
                                ├── ViewPagerItemAdapter.java
                                ├── ViewPagerItems.java
                                └── v4/
                                    ├── Bundler.java
                                    ├── FragmentPagerItem.java
                                    ├── FragmentPagerItemAdapter.java
                                    ├── FragmentPagerItems.java
                                    └── FragmentStatePagerItemAdapter.java
Download .txt
SYMBOL INDEX (261 symbols across 22 files)

FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/Demo.java
  type Demo (line 14) | public enum Demo {
    method tabs (line 23) | @Override
    method tabs (line 36) | @Override
    method setup (line 46) | @Override
    method tabs (line 81) | @Override
    method setup (line 91) | @Override
    method tabs (line 127) | @Override
    method tabs (line 135) | @Override
    method startActivity (line 140) | @Override
    method startActivity (line 153) | @Override
    method tabs (line 160) | @Override
    method startActivity (line 168) | @Override
    method Demo (line 177) | Demo(int titleResId, int layoutResId) {
    method tab10 (line 182) | public static int[] tab10() {
    method tab3 (line 197) | public static int[] tab3() {
    method startActivity (line 205) | public void startActivity(Context context) {
    method setup (line 209) | public void setup(final SmartTabLayout layout) {
    method tabs (line 213) | public int[] tabs() {

FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoActivity.java
  class DemoActivity (line 18) | public class DemoActivity extends AppCompatActivity {
    method startActivity (line 22) | public static void startActivity(Context context, Demo demo) {
    method onCreate (line 28) | @Override
    method getDemo (line 60) | private Demo getDemo() {

FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoFragment.java
  class DemoFragment (line 14) | public class DemoFragment extends Fragment {
    method onCreateView (line 16) | @Override
    method onViewCreated (line 22) | @Override

FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoLikeMediumActivity.java
  class DemoLikeMediumActivity (line 18) | public class DemoLikeMediumActivity extends AppCompatActivity {
    method startActivity (line 22) | public static void startActivity(Context context, Demo demo) {
    method onCreate (line 28) | @Override
    method getDemo (line 60) | private Demo getDemo() {

FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoRtlActivity.java
  class DemoRtlActivity (line 18) | public class DemoRtlActivity extends AppCompatActivity {
    method startActivity (line 22) | public static void startActivity(Context context, Demo demo) {
    method onCreate (line 28) | @Override
    method getDemo (line 60) | private Demo getDemo() {

FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoTabWithNotificationMarkActivity.java
  class DemoTabWithNotificationMarkActivity (line 24) | public class DemoTabWithNotificationMarkActivity extends AppCompatActivi...
    method startActivity (line 29) | public static void startActivity(Context context, Demo demo) {
    method onCreate (line 37) | @Override
    method createTabView (line 89) | @Override
    method getDemo (line 113) | private Demo getDemo() {

FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/MainActivity.java
  class MainActivity (line 16) | public class MainActivity extends AppCompatActivity implements AbsListVi...
    method onCreate (line 18) | @Override
    method onCreateOptionsMenu (line 35) | @Override
    method onOptionsItemSelected (line 41) | @Override
    method onItemClick (line 52) | @Override
    method openGitHub (line 58) | private void openGitHub() {

FILE: demo/src/main/java/com/ogaclejapan/smarttablayout/demo/TintableImageView.java
  class TintableImageView (line 13) | public class TintableImageView extends AppCompatImageView {
    method TintableImageView (line 17) | public TintableImageView(Context context) {
    method TintableImageView (line 21) | public TintableImageView(Context context, AttributeSet attrs) {
    method TintableImageView (line 26) | public TintableImageView(Context context, AttributeSet attrs, int defS...
    method init (line 31) | private void init(Context context, AttributeSet attrs, int defStyle) {
    method drawableStateChanged (line 39) | @Override
    method setColorFilter (line 47) | public void setColorFilter(ColorStateList tint) {
    method updateTintColor (line 52) | private void updateTintColor() {

FILE: library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabIndicationInterpolator.java
  class SmartTabIndicationInterpolator (line 23) | public abstract class SmartTabIndicationInterpolator {
    method of (line 31) | public static SmartTabIndicationInterpolator of(int id) {
    method getLeftEdge (line 42) | public abstract float getLeftEdge(float offset);
    method getRightEdge (line 44) | public abstract float getRightEdge(float offset);
    method getThickness (line 46) | public float getThickness(float offset) {
    class SmartIndicationInterpolator (line 50) | public static class SmartIndicationInterpolator extends SmartTabIndica...
      method SmartIndicationInterpolator (line 57) | public SmartIndicationInterpolator() {
      method SmartIndicationInterpolator (line 61) | public SmartIndicationInterpolator(float factor) {
      method getLeftEdge (line 66) | @Override
      method getRightEdge (line 71) | @Override
      method getThickness (line 76) | @Override
    class LinearIndicationInterpolator (line 83) | public static class LinearIndicationInterpolator extends SmartTabIndic...
      method getLeftEdge (line 85) | @Override
      method getRightEdge (line 90) | @Override

FILE: library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabLayout.java
  class SmartTabLayout (line 62) | public class SmartTabLayout extends HorizontalScrollView {
    method SmartTabLayout (line 90) | public SmartTabLayout(Context context) {
    method SmartTabLayout (line 94) | public SmartTabLayout(Context context, AttributeSet attrs) {
    method SmartTabLayout (line 98) | public SmartTabLayout(Context context, AttributeSet attrs, int defStyl...
    method onScrollChanged (line 176) | @Override
    method onSizeChanged (line 184) | @Override
    method onLayout (line 198) | @Override
    method setIndicationInterpolator (line 212) | public void setIndicationInterpolator(SmartTabIndicationInterpolator i...
    method setCustomTabColorizer (line 223) | public void setCustomTabColorizer(TabColorizer tabColorizer) {
    method setDefaultTabTextColor (line 233) | public void setDefaultTabTextColor(int color) {
    method setDefaultTabTextColor (line 243) | public void setDefaultTabTextColor(ColorStateList colors) {
    method setDistributeEvenly (line 250) | public void setDistributeEvenly(boolean distributeEvenly) {
    method setSelectedIndicatorColors (line 258) | public void setSelectedIndicatorColors(int... colors) {
    method setDividerColors (line 266) | public void setDividerColors(int... colors) {
    method setOnPageChangeListener (line 277) | public void setOnPageChangeListener(ViewPager.OnPageChangeListener lis...
    method setOnScrollChangeListener (line 286) | public void setOnScrollChangeListener(OnScrollChangeListener listener) {
    method setOnTabClickListener (line 295) | public void setOnTabClickListener(OnTabClickListener listener) {
    method setCustomTabView (line 305) | public void setCustomTabView(int layoutResId, int textViewId) {
    method setCustomTabView (line 314) | public void setCustomTabView(TabProvider provider) {
    method setViewPager (line 322) | public void setViewPager(ViewPager viewPager) {
    method getTabAt (line 339) | public View getTabAt(int position) {
    method createDefaultTabView (line 347) | protected TextView createDefaultTabView(CharSequence title) {
    method populateTabStrip (line 384) | private void populateTabStrip() {
    method scrollToTab (line 416) | private void scrollToTab(int tabIndex, float positionOffset) {
    type TabColorizer (line 499) | public interface TabColorizer {
      method getIndicatorColor (line 504) | int getIndicatorColor(int position);
      method getDividerColor (line 509) | int getDividerColor(int position);
    type OnScrollChangeListener (line 516) | public interface OnScrollChangeListener {
      method onScrollChanged (line 524) | void onScrollChanged(int scrollX, int oldScrollX);
    type OnTabClickListener (line 530) | public interface OnTabClickListener {
      method onTabClicked (line 537) | void onTabClicked(int position);
    type TabProvider (line 544) | public interface TabProvider {
      method createTabView (line 549) | View createTabView(ViewGroup container, int position, PagerAdapter a...
    class SimpleTabProvider (line 553) | private static class SimpleTabProvider implements TabProvider {
      method SimpleTabProvider (line 559) | private SimpleTabProvider(Context context, int layoutResId, int text...
      method createTabView (line 565) | @Override
    class InternalViewPagerListener (line 591) | private class InternalViewPagerListener implements ViewPager.OnPageCha...
      method onPageScrolled (line 595) | @Override
      method onPageScrollStateChanged (line 611) | @Override
      method onPageSelected (line 620) | @Override
    class InternalTabClickListener (line 638) | private class InternalTabClickListener implements OnClickListener {
      method onClick (line 639) | @Override

FILE: library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabStrip.java
  class SmartTabStrip (line 35) | class SmartTabStrip extends LinearLayout {
    method SmartTabStrip (line 85) | SmartTabStrip(Context context, AttributeSet attrs) {
    method setColorAlpha (line 193) | private static int setColorAlpha(int color, byte alpha) {
    method blendColors (line 203) | private static int blendColors(int color1, int color2, float ratio) {
    method setIndicationInterpolator (line 211) | void setIndicationInterpolator(SmartTabIndicationInterpolator interpol...
    method setCustomTabColorizer (line 216) | void setCustomTabColorizer(SmartTabLayout.TabColorizer customTabColori...
    method setSelectedIndicatorColors (line 221) | void setSelectedIndicatorColors(int... colors) {
    method setDividerColors (line 228) | void setDividerColors(int... colors) {
    method onViewPagerPageChanged (line 235) | void onViewPagerPageChanged(int position, float positionOffset) {
    method isIndicatorAlwaysInCenter (line 244) | boolean isIndicatorAlwaysInCenter() {
    method getTabColorizer (line 248) | SmartTabLayout.TabColorizer getTabColorizer() {
    method onDraw (line 252) | @Override
    method dispatchDraw (line 259) | @Override
    method drawDecoration (line 267) | private void drawDecoration(Canvas canvas) {
    method drawSeparator (line 335) | private void drawSeparator(Canvas canvas, int height, int tabCount) {
    method drawIndicator (line 358) | private void drawIndicator(Canvas canvas, int left, int right, int hei...
    method drawOverline (line 403) | private void drawOverline(Canvas canvas, int left, int right) {
    method drawUnderline (line 412) | private void drawUnderline(Canvas canvas, int left, int right, int hei...
    class SimpleTabColorizer (line 421) | private static class SimpleTabColorizer implements SmartTabLayout.TabC...
      method getIndicatorColor (line 426) | @Override
      method getDividerColor (line 431) | @Override
      method setIndicatorColors (line 436) | void setIndicatorColors(int... colors) {
      method setDividerColors (line 440) | void setDividerColors(int... colors) {

FILE: library/src/main/java/com/ogaclejapan/smarttablayout/Utils.java
  class Utils (line 25) | final class Utils {
    method getMeasuredWidth (line 27) | static int getMeasuredWidth(View v) {
    method getWidth (line 31) | static int getWidth(View v) {
    method getWidthWithMargin (line 35) | static int getWidthWithMargin(View v) {
    method getStart (line 39) | static int getStart(View v) {
    method getStart (line 43) | static int getStart(View v, boolean withoutPadding) {
    method getEnd (line 54) | static int getEnd(View v) {
    method getEnd (line 58) | static int getEnd(View v, boolean withoutPadding) {
    method getPaddingStart (line 69) | static int getPaddingStart(View v) {
    method getPaddingEnd (line 76) | static int getPaddingEnd(View v) {
    method getPaddingHorizontally (line 83) | static int getPaddingHorizontally(View v) {
    method getMarginStart (line 90) | static int getMarginStart(View v) {
    method getMarginEnd (line 98) | static int getMarginEnd(View v) {
    method getMarginHorizontally (line 106) | static int getMarginHorizontally(View v) {
    method isLayoutRtl (line 114) | static boolean isLayoutRtl(View v) {
    method Utils (line 118) | private Utils() { }

FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/PagerItem.java
  class PagerItem (line 18) | public abstract class PagerItem {
    method PagerItem (line 25) | protected PagerItem(CharSequence title, float width) {
    method getTitle (line 30) | public CharSequence getTitle() {
    method getWidth (line 34) | public float getWidth() {

FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/PagerItems.java
  class PagerItems (line 22) | public abstract class PagerItems<T extends PagerItem> extends ArrayList<...
    method PagerItems (line 26) | protected PagerItems(Context context) {
    method getContext (line 30) | public Context getContext() {

FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/ViewPagerItem.java
  class ViewPagerItem (line 24) | public class ViewPagerItem extends PagerItem {
    method ViewPagerItem (line 28) | protected ViewPagerItem(CharSequence title, float width, @LayoutRes in...
    method of (line 33) | public static ViewPagerItem of(CharSequence title, @LayoutRes int reso...
    method of (line 37) | public static ViewPagerItem of(CharSequence title, float width, @Layou...
    method initiate (line 41) | public View initiate(LayoutInflater inflater, ViewGroup container) {

FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/ViewPagerItemAdapter.java
  class ViewPagerItemAdapter (line 28) | public class ViewPagerItemAdapter extends PagerAdapter {
    method ViewPagerItemAdapter (line 34) | public ViewPagerItemAdapter(ViewPagerItems pages) {
    method getCount (line 40) | @Override
    method instantiateItem (line 45) | @NonNull
    method destroyItem (line 54) | @Override
    method isViewFromObject (line 60) | @Override
    method getPageTitle (line 65) | @Override
    method getPageWidth (line 70) | @Override
    method getPage (line 75) | public View getPage(int position) {
    method getPagerItem (line 80) | protected ViewPagerItem getPagerItem(int position) {

FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/ViewPagerItems.java
  class ViewPagerItems (line 23) | public class ViewPagerItems extends PagerItems<ViewPagerItem> {
    method ViewPagerItems (line 25) | public ViewPagerItems(Context context) {
    method with (line 29) | public static Creator with(Context context) {
    class Creator (line 33) | public static class Creator {
      method Creator (line 37) | public Creator(Context context) {
      method add (line 41) | public Creator add(@StringRes int title, @LayoutRes int resource) {
      method add (line 45) | public Creator add(@StringRes int title, float width, @LayoutRes int...
      method add (line 49) | public Creator add(CharSequence title, @LayoutRes int resource) {
      method add (line 53) | public Creator add(ViewPagerItem item) {
      method create (line 58) | public ViewPagerItems create() {

FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/Bundler.java
  class Bundler (line 31) | public class Bundler {
    method Bundler (line 38) | public Bundler() {
    method Bundler (line 42) | private Bundler(Bundle b) {
    method of (line 52) | public static Bundler of(Bundle b) {
    method putAll (line 62) | public Bundler putAll(Bundle bundle) {
    method putByte (line 75) | public Bundler putByte(String key, byte value) {
    method putChar (line 88) | public Bundler putChar(String key, char value) {
    method putShort (line 101) | public Bundler putShort(String key, short value) {
    method putFloat (line 114) | public Bundler putFloat(String key, float value) {
    method putCharSequence (line 127) | public Bundler putCharSequence(String key, CharSequence value) {
    method putParcelable (line 140) | public Bundler putParcelable(String key, Parcelable value) {
    method putSize (line 153) | @TargetApi(21)
    method putSizeF (line 167) | @TargetApi(21)
    method putParcelableArray (line 182) | public Bundler putParcelableArray(String key, Parcelable[] value) {
    method putParcelableArrayList (line 196) | public Bundler putParcelableArrayList(String key,
    method putSparseParcelableArray (line 211) | public Bundler putSparseParcelableArray(String key,
    method putIntegerArrayList (line 225) | public Bundler putIntegerArrayList(String key, ArrayList<Integer> valu...
    method putStringArrayList (line 238) | public Bundler putStringArrayList(String key, ArrayList<String> value) {
    method putCharSequenceArrayList (line 251) | @TargetApi(8)
    method putSerializable (line 265) | public Bundler putSerializable(String key, Serializable value) {
    method putByteArray (line 278) | public Bundler putByteArray(String key, byte[] value) {
    method putShortArray (line 291) | public Bundler putShortArray(String key, short[] value) {
    method putCharArray (line 304) | public Bundler putCharArray(String key, char[] value) {
    method putFloatArray (line 317) | public Bundler putFloatArray(String key, float[] value) {
    method putCharSequenceArray (line 330) | @TargetApi(8)
    method putBundle (line 344) | public Bundler putBundle(String key, Bundle value) {
    method putBinder (line 364) | @TargetApi(18)
    method putBoolean (line 378) | public Bundler putBoolean(String key, boolean value) {
    method putInt (line 391) | public Bundler putInt(String key, int value) {
    method putLong (line 404) | public Bundler putLong(String key, long value) {
    method putDouble (line 417) | public Bundler putDouble(String key, double value) {
    method putString (line 430) | public Bundler putString(String key, String value) {
    method putBooleanArray (line 443) | public Bundler putBooleanArray(String key, boolean[] value) {
    method putIntArray (line 456) | public Bundler putIntArray(String key, int[] value) {
    method putLongArray (line 469) | public Bundler putLongArray(String key, long[] value) {
    method putDoubleArray (line 482) | public Bundler putDoubleArray(String key, double[] value) {
    method putStringArray (line 495) | public Bundler putStringArray(String key, String[] value) {
    method get (line 505) | public Bundle get() {
    method into (line 515) | public <T extends Fragment> T into(T fragment) {

FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentPagerItem.java
  class FragmentPagerItem (line 25) | public class FragmentPagerItem extends PagerItem {
    method FragmentPagerItem (line 33) | protected FragmentPagerItem(CharSequence title, float width, String cl...
    method of (line 39) | public static FragmentPagerItem of(CharSequence title, Class<? extends...
    method of (line 43) | public static FragmentPagerItem of(CharSequence title, Class<? extends...
    method of (line 48) | public static FragmentPagerItem of(CharSequence title, float width,
    method of (line 53) | public static FragmentPagerItem of(CharSequence title, float width,
    method hasPosition (line 58) | public static boolean hasPosition(Bundle args) {
    method getPosition (line 62) | public static int getPosition(Bundle args) {
    method setPosition (line 66) | static void setPosition(Bundle args, int position) {
    method instantiate (line 70) | public Fragment instantiate(Context context, int position) {

FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentPagerItemAdapter.java
  class FragmentPagerItemAdapter (line 28) | public class FragmentPagerItemAdapter extends FragmentPagerAdapter {
    method FragmentPagerItemAdapter (line 33) | public FragmentPagerItemAdapter(FragmentManager fm, FragmentPagerItems...
    method getCount (line 39) | @Override
    method getItem (line 44) | @Override
    method instantiateItem (line 49) | @NonNull
    method destroyItem (line 59) | @Override
    method getPageTitle (line 65) | @Override
    method getPageWidth (line 70) | @Override
    method getPage (line 75) | public Fragment getPage(int position) {
    method getPagerItem (line 80) | protected FragmentPagerItem getPagerItem(int position) {

FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentPagerItems.java
  class FragmentPagerItems (line 26) | public class FragmentPagerItems extends PagerItems<FragmentPagerItem> {
    method FragmentPagerItems (line 28) | public FragmentPagerItems(Context context) {
    method with (line 32) | public static Creator with(Context context) {
    class Creator (line 36) | public static class Creator {
      method Creator (line 40) | public Creator(Context context) {
      method add (line 44) | public Creator add(@StringRes int title, Class<? extends Fragment> c...
      method add (line 48) | public Creator add(@StringRes int title, Class<? extends Fragment> c...
      method add (line 52) | public Creator add(@StringRes int title, float width, Class<? extend...
      method add (line 56) | public Creator add(@StringRes int title, float width, Class<? extend...
      method add (line 61) | public Creator add(CharSequence title, Class<? extends Fragment> cla...
      method add (line 65) | public Creator add(CharSequence title, Class<? extends Fragment> cla...
      method add (line 69) | public Creator add(FragmentPagerItem item) {
      method create (line 74) | public FragmentPagerItems create() {

FILE: utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentStatePagerItemAdapter.java
  class FragmentStatePagerItemAdapter (line 28) | public class FragmentStatePagerItemAdapter extends FragmentStatePagerAda...
    method FragmentStatePagerItemAdapter (line 33) | public FragmentStatePagerItemAdapter(FragmentManager fm, FragmentPager...
    method getCount (line 39) | @Override
    method getItem (line 44) | @Override
    method instantiateItem (line 49) | @NonNull
    method destroyItem (line 59) | @Override
    method getPageTitle (line 65) | @Override
    method getPageWidth (line 70) | @Override
    method getPage (line 75) | public Fragment getPage(int position) {
    method getPagerItem (line 80) | protected FragmentPagerItem getPagerItem(int position) {
Condensed preview — 95 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (190K chars).
[
  {
    "path": ".gitignore",
    "chars": 1264,
    "preview": "# https://github.com/github/gitignore\n# https://github.com/hsz/idea-gitignore\n\n\n### JetBrains template\n# Covers JetBrain"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 1744,
    "preview": "# Version 2.0.0\n\n* Migrate to androidx 1.0.0\n* Remove util-v13 library\n\n# Version 1.7.0\n\n* Update support library versio"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 429,
    "preview": "# Contributing\n\nIf you would like to contribute code to SmartTabLayout you can do so through GitHub by\nforking the repos"
  },
  {
    "path": "LICENSE.txt",
    "chars": 11400,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "README.md",
    "chars": 12131,
    "preview": "# SmartTabLayout\n[![Maven Central][maven_central_badge_svg]][maven_central_badge_app] [![Android Arsenal][android_arsena"
  },
  {
    "path": "build.gradle",
    "chars": 1168,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\next {\n  // Package i"
  },
  {
    "path": "demo/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "demo/build.gradle",
    "chars": 1016,
    "preview": "apply plugin: 'com.android.application'\n\nandroid {\n  compileSdkVersion COMPILE_SDK_VERSION as int\n\n  defaultConfig {\n   "
  },
  {
    "path": "demo/proguard-rules.pro",
    "chars": 661,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "demo/src/main/AndroidManifest.xml",
    "chars": 1501,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  package="
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/Demo.java",
    "chars": 6516,
    "preview": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.content.Context;\nimport android.content.res.Resources;\nimpo"
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoActivity.java",
    "chars": 2095,
    "preview": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport andr"
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoFragment.java",
    "chars": 931,
    "preview": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.os.Bundle;\nimport android.view.LayoutInflater;\nimport andro"
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoLikeMediumActivity.java",
    "chars": 2124,
    "preview": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport andr"
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoRtlActivity.java",
    "chars": 2106,
    "preview": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport andr"
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoTabWithNotificationMarkActivity.java",
    "chars": 4203,
    "preview": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport andr"
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/MainActivity.java",
    "chars": 1776,
    "preview": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.content.Intent;\nimport android.net.Uri;\nimport android.os.B"
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/TintableImageView.java",
    "chars": 1501,
    "preview": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.content.Context;\nimport android.content.res.ColorStateList;"
  },
  {
    "path": "demo/src/main/res/color/custom_tab.xml",
    "chars": 275,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <item and"
  },
  {
    "path": "demo/src/main/res/color/custom_tab_icon.xml",
    "chars": 274,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <item and"
  },
  {
    "path": "demo/src/main/res/color/custom_tab_like_a_medium.xml",
    "chars": 288,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <item and"
  },
  {
    "path": "demo/src/main/res/drawable/custom_circle.xml",
    "chars": 280,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:sha"
  },
  {
    "path": "demo/src/main/res/drawable/custom_icon.xml",
    "chars": 271,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <item and"
  },
  {
    "path": "demo/src/main/res/drawable/custom_tab.xml",
    "chars": 314,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <item and"
  },
  {
    "path": "demo/src/main/res/drawable/shape_notification_mark.xml",
    "chars": 184,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:sha"
  },
  {
    "path": "demo/src/main/res/layout/activity_demo.xml",
    "chars": 1168,
    "preview": "<RelativeLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk"
  },
  {
    "path": "demo/src/main/res/layout/activity_demo_tab_with_notification_mark.xml",
    "chars": 1396,
    "preview": "<RelativeLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk"
  },
  {
    "path": "demo/src/main/res/layout/activity_like_a_medium.xml",
    "chars": 1174,
    "preview": "<RelativeLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk"
  },
  {
    "path": "demo/src/main/res/layout/activity_main.xml",
    "chars": 337,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  andro"
  },
  {
    "path": "demo/src/main/res/layout/activity_rtl.xml",
    "chars": 1164,
    "preview": "<RelativeLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab.xml",
    "chars": 441,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TextView\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab_circle.xml",
    "chars": 330,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<View\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:layo"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab_icon1.xml",
    "chars": 411,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.ogaclejapan.smarttablayout.demo.TintableImageView\n  xmlns:android=\"http://sc"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab_icon2.xml",
    "chars": 419,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.ogaclejapan.smarttablayout.demo.TintableImageView\n  xmlns:android=\"http://sc"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab_icon_and_notification_mark.xml",
    "chars": 919,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xm"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab_icon_and_text.xml",
    "chars": 1203,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xm"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab_like_a_medium.xml",
    "chars": 511,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TextView\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab_margin.xml",
    "chars": 510,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TextView\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:"
  },
  {
    "path": "demo/src/main/res/layout/demo_always_in_center.xml",
    "chars": 643,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/demo_basic.xml",
    "chars": 568,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/demo_basic_title_offset_auto_center.xml",
    "chars": 565,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/demo_custom_tab_colors.xml",
    "chars": 593,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/demo_custom_tab_icon_and_notification_mark.xml",
    "chars": 468,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/demo_custom_tab_icon_and_text.xml",
    "chars": 593,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/demo_custom_tab_icons1.xml",
    "chars": 556,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/demo_custom_tab_icons2.xml",
    "chars": 723,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/demo_custom_tab_margin.xml",
    "chars": 544,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/demo_custom_tab_text.xml",
    "chars": 537,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/demo_distribute_evenly.xml",
    "chars": 595,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/demo_indicator_trick1.xml",
    "chars": 819,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/demo_indicator_trick2.xml",
    "chars": 760,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/demo_like_a_medium_tag.xml",
    "chars": 893,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/demo_rtl.xml",
    "chars": 530,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/demo_smart_indicator.xml",
    "chars": 608,
    "preview": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app="
  },
  {
    "path": "demo/src/main/res/layout/fragment_demo.xml",
    "chars": 620,
    "preview": "<LinearLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:orientation=\"vertical\"\n  android:la"
  },
  {
    "path": "demo/src/main/res/menu/menu_demo.xml",
    "chars": 374,
    "preview": "<menu\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\""
  },
  {
    "path": "demo/src/main/res/menu/menu_main.xml",
    "chars": 316,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"h"
  },
  {
    "path": "demo/src/main/res/values/attrs.xml",
    "chars": 182,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n  <declare-styleable name=\"TintableImageView\">\n    <attr name=\"tint\" "
  },
  {
    "path": "demo/src/main/res/values/colors.xml",
    "chars": 1164,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n  <color name=\"primary\">#3C515C</color>\n  <color name=\"primary_dark\">"
  },
  {
    "path": "demo/src/main/res/values/dimens.xml",
    "chars": 111,
    "preview": "<resources>\n  <dimen name=\"tab_height\">48dp</dimen>\n  <dimen name=\"tab_height_large\">72dp</dimen>\n</resources>\n"
  },
  {
    "path": "demo/src/main/res/values/ids.xml",
    "chars": 206,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n  <item name=\"toolbar\" type=\"id\"/>\n  <item name=\"tab\" type=\"id\"/>\n  <"
  },
  {
    "path": "demo/src/main/res/values/strings.xml",
    "chars": 2200,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n  <string name=\"app_name\">SmartTabLayout</string>\n  <string name=\"ap"
  },
  {
    "path": "demo/src/main/res/values/styles.xml",
    "chars": 528,
    "preview": "<resources>\n\n  <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n    <item name=\"colorPrimary\">@color"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 233,
    "preview": "#Sun Nov 27 17:23:04 JST 2016\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "gradle.properties",
    "chars": 871,
    "preview": "android.useAndroidX=true\n\nVERSION_NAME=2.0.0\nVERSION_CODE=18\nCOMPILE_SDK_VERSION=28\nANDROIDX_APPCOMPAT_VERSION=1.0.2\nAND"
  },
  {
    "path": "gradlew",
    "chars": 5080,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "gradlew.bat",
    "chars": 2314,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
  },
  {
    "path": "library/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "library/LICENSE",
    "chars": 603,
    "preview": "Copyright (C) 2015 ogaclejapan\nCopyright (C) 2013 The Android Open Source Project\n\nLicensed under the Apache License, Ve"
  },
  {
    "path": "library/build.gradle",
    "chars": 956,
    "preview": "apply plugin: 'com.android.library'\napply plugin: 'com.github.ben-manes.versions'\napply plugin: 'com.github.hierynomus.l"
  },
  {
    "path": "library/proguard-rules.pro",
    "chars": 661,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "library/src/main/AndroidManifest.xml",
    "chars": 65,
    "preview": "<manifest package=\"com.ogaclejapan.smarttablayout\">\n\n</manifest>\n"
  },
  {
    "path": "library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabIndicationInterpolator.java",
    "chars": 2873,
    "preview": "/**\n * Copyright (C) 2015 ogaclejapan\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apa"
  },
  {
    "path": "library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabLayout.java",
    "chars": 22759,
    "preview": "/**\n * Copyright (C) 2015 ogaclejapan\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apa"
  },
  {
    "path": "library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabStrip.java",
    "chars": 17310,
    "preview": "/**\n * Copyright (C) 2015 ogaclejapan\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apa"
  },
  {
    "path": "library/src/main/java/com/ogaclejapan/smarttablayout/Utils.java",
    "chars": 3176,
    "preview": "/**\n * Copyright (C) 2015 ogaclejapan\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apa"
  },
  {
    "path": "library/src/main/res/values/attrs.xml",
    "chars": 2173,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n  <declare-styleable name=\"stl_SmartTabLayout\">\n    <attr name=\"stl_i"
  },
  {
    "path": "publish.gradle",
    "chars": 2148,
    "preview": "apply plugin: 'com.jfrog.bintray'\napply plugin: 'com.github.dcendents.android-maven'\n\n\n// build a jar with source files\n"
  },
  {
    "path": "settings.gradle",
    "chars": 41,
    "preview": "include ':demo', ':library', ':utils-v4'\n"
  },
  {
    "path": "utils-v4/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "utils-v4/LICENSE",
    "chars": 552,
    "preview": "Copyright (C) 2015 ogaclejapan\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this fil"
  },
  {
    "path": "utils-v4/build.gradle",
    "chars": 928,
    "preview": "apply plugin: 'com.android.library'\napply plugin: 'com.github.ben-manes.versions'\napply plugin: 'com.github.hierynomus.l"
  },
  {
    "path": "utils-v4/proguard-rules.pro",
    "chars": 661,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "utils-v4/src/main/AndroidManifest.xml",
    "chars": 71,
    "preview": "<manifest package=\"com.ogaclejapan.smarttablayout.utils\">\n\n</manifest>\n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/PagerItem.java",
    "chars": 1018,
    "preview": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/PagerItems.java",
    "chars": 951,
    "preview": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/ViewPagerItem.java",
    "chars": 1420,
    "preview": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/ViewPagerItemAdapter.java",
    "chars": 2444,
    "preview": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/ViewPagerItems.java",
    "chars": 1773,
    "preview": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/Bundler.java",
    "chars": 14725,
    "preview": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentPagerItem.java",
    "chars": 2386,
    "preview": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentPagerItemAdapter.java",
    "chars": 2488,
    "preview": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentPagerItems.java",
    "chars": 2481,
    "preview": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentStatePagerItemAdapter.java",
    "chars": 2513,
    "preview": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the ogaclejapan/SmartTabLayout GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 95 files (171.7 KB), approximately 45.8k tokens, and a symbol index with 261 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!