[
  {
    "path": ".gitignore",
    "content": "# https://github.com/github/gitignore\n# https://github.com/hsz/idea-gitignore\n\n\n### JetBrains template\n# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm\n\n*.iml\n\n## Directory-based project format:\n.idea/\n# if you remove the above rule, at least ignore the following:\n\n# User-specific stuff:\n# .idea/workspace.xml\n# .idea/tasks.xml\n# .idea/dictionaries\n\n# Sensitive or high-churn files:\n# .idea/dataSources.ids\n# .idea/dataSources.xml\n# .idea/sqlDataSources.xml\n# .idea/dynamic.xml\n# .idea/uiDesigner.xml\n\n# Gradle:\n# .idea/gradle.xml\n# .idea/libraries\n\n# Mongo Explorer plugin:\n# .idea/mongoSettings.xml\n\n## File-based project format:\n*.ipr\n*.iws\n\n## Plugin-specific files:\n\n# IntelliJ\n/out/\n\n# mpeltonen/sbt-idea plugin\n.idea_modules/\n\n# JIRA plugin\natlassian-ide-plugin.xml\n\n# Crashlytics plugin (for Android Studio and IntelliJ)\ncom_crashlytics_export_strings.xml\ncrashlytics.properties\ncrashlytics-build.properties\n\n\n### Android template\n# Built application files\n*.apk\n*.ap_\n\n# Files for the Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\n\n# Gradle files\n.gradle/\nbuild/\n/*/build/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# 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 version to 28.0.0\n* Change target sdk version to 28\n* Change min sdk version to 14\n* Deprecated util-v13 library\n\n# Version 1.6.1\n\n* Fixed issue with center last item in always in center tablayout #160\n\n# Version 1.6.0\n\n* Add `stl_indicatorWidth` to custom indicator's width #106\n\n# Version 1.5.1\n\n* Fixed indicator position of auto_center #100\n\n# Version 1.5.0\n\n* Add `stl_drawDecorationAfterTab` attribute for change the drawing order #58\n* Add `stl_titleOffset` attribute for adjust the slide position #89\n* Fixed a condition code of onSizeChanged for always in center\n\n# Version 1.4.2\n\n* Change the call order of OnTabClickListener when press the tab #74\n\n# Version 1.4.1\n\n* Update android support library version to 22.2.1\n\n# Version 1.4.0\n\n* Add TabClickListener interface #68\n\n# Version 1.3.0\n\n* RTL support #48\n* Add `stl_clickable` attribute.\n\n# Version 1.2.3\n\n* Modify to ensure the first scroll #54\n\n# Version 1.2.2\n\n* Fix bug when indicatorAlwaysInCenter is true and tabHost has only two tabs #50\n\n# Version 1.2.1\n\n* Add custom ScrollListener interface #46\n\n# Version 1.2.0\n\n* Support the margin of each tab.\n* Add `stl_indicatorWithoutPadding` and `stl_indicatorGravity` attributes.\n* Add `stl_overlineColor` and `stl_overlineThickness` attributes.\n\n# Version 1.1.3\n\n* Allow to set the background on default tab #13\n\n# Version 1.1.2\n\n* Added setter for tab text colors #10\n* Allow to set a String title dynamically on PagerItems. #7\n\n# Version 1.1.1\n\n* Enable the format of ‘reference’ for defaultTextColor to support ColorStateList #3\n\n# Version 1.1.0\n\n* Supported Icon Tab. #1\n\n\n# Version 1.0.0\n\n* Initial release.\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nIf you would like to contribute code to SmartTabLayout you can do so through GitHub by\nforking the repository and sending a pull request.\n\nWhen submitting code, please make every effort to follow existing conventions\nand style in order to keep the code as readable as possible.\n\n## Coding Style\n\n* Use the AndroidModernStyle of [Android Code Styles](https://github.com/ogaclejapan/android-code-styles) repository\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright (C) 2015 ogaclejapan\n   Copyright (C) 2013 The Android Open Source Project\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "# SmartTabLayout\n[![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]\n\n![icon][demo_icon]\n\nA custom ViewPager title strip which gives continuous feedback to the user when scrolling.\n\nThis library has been added some features and utilities based on [android-SlidingTabBasic][google_slidingtabbasic] project of Google Samples.\n\n\n![SmartTabLayout Demo1][demo1_gif] ![SmartTabLayout Demo2][demo2_gif]\n![SmartTabLayout Demo3][demo3_gif] ![SmartTabLayout Demo4][demo4_gif]\n![SmartTabLayout Demo5][demo5_gif] ![SmartTabLayout Demo6][demo6_gif]\n![SmartTabLayout Demo7][demo7_gif]\n\n\nTry out the sample application on the Play Store.\n\n[![Get it on Google Play][googleplay_store_badge]][demo_app]\n\n\n# Usage\n\n_(For a working implementation of this project see the demo/ folder.)_\n\nAdd the dependency to your build.gradle.\n\n```\n// For androidx (1.0.0)\ndependencies {\n    compile 'com.ogaclejapan.smarttablayout:library:2.0.0@aar'\n\n    //Optional: see how to use the utility.\n    compile 'com.ogaclejapan.smarttablayout:utils-v4:2.0.0@aar'\n}\n\n// For legacy android support library (28.0.0)\ndependencies {\n    compile 'com.ogaclejapan.smarttablayout:library:1.7.0@aar'\n\n    //Optional: see how to use the utility.\n    compile 'com.ogaclejapan.smarttablayout:utils-v4:1.7.0@aar'\n\n    //Deprecated since 1.7.0\n    compile 'com.ogaclejapan.smarttablayout:utils-v13:1.7.0@aar'\n}\n```\n\nInclude the SmartTabLayout widget in your layout.\nThis should usually be placed above the ViewPager it represents.\n\n```xml\n\n<com.ogaclejapan.smarttablayout.SmartTabLayout\n    android:id=\"@+id/viewpagertab\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"48dp\"\n    app:stl_indicatorAlwaysInCenter=\"false\"\n    app:stl_indicatorWithoutPadding=\"false\"\n    app:stl_indicatorInFront=\"false\"\n    app:stl_indicatorInterpolation=\"smart\"\n    app:stl_indicatorGravity=\"bottom\"\n    app:stl_indicatorColor=\"#40C4FF\"\n    app:stl_indicatorThickness=\"4dp\"\n    app:stl_indicatorWidth=\"auto\"\n    app:stl_indicatorCornerRadius=\"2dp\"\n    app:stl_overlineColor=\"#4D000000\"\n    app:stl_overlineThickness=\"0dp\"\n    app:stl_underlineColor=\"#4D000000\"\n    app:stl_underlineThickness=\"1dp\"\n    app:stl_dividerColor=\"#4D000000\"\n    app:stl_dividerThickness=\"1dp\"\n    app:stl_defaultTabBackground=\"?attr/selectableItemBackground\"\n    app:stl_defaultTabTextAllCaps=\"true\"\n    app:stl_defaultTabTextColor=\"#FC000000\"\n    app:stl_defaultTabTextSize=\"12sp\"\n    app:stl_defaultTabTextHorizontalPadding=\"16dp\"\n    app:stl_defaultTabTextMinWidth=\"0dp\"\n    app:stl_distributeEvenly=\"false\"\n    app:stl_clickable=\"true\"\n    app:stl_titleOffset=\"24dp\"\n    app:stl_drawDecorationAfterTab=\"false\"\n    />\n\n<androidx.viewpager.widget.ViewPager\n    android:id=\"@+id/viewpager\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:layout_below=\"@id/viewpagertab\"\n    />\n\n```\n\nIn your onCreate method (or onCreateView for a fragment), bind the widget to the ViewPager.\n(If you use a utility together, you can easily add items to PagerAdapter)\n\ne.g. ViewPager of v4.Fragment\n\n```java\n\nFragmentPagerItemAdapter adapter = new FragmentPagerItemAdapter(\n        getSupportFragmentManager(), FragmentPagerItems.with(this)\n        .add(R.string.titleA, PageFragment.class)\n        .add(R.string.titleB, PageFragment.class)\n        .create());\n\nViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);\nviewPager.setAdapter(adapter);\n\nSmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpagertab);\nviewPagerTab.setViewPager(viewPager);\n\n```\n\n(Optional) If you use an OnPageChangeListener with your view pager you should set it in the widget rather than on the pager directly.\n\n\n```java\n\nviewPagerTab.setOnPageChangeListener(mPageChangeListener);\n\n```\n\n(Optional) Using the FragmentPagerItemAdapter of utility, you will be able to get a position in the Fragment side.\n\n```java\n\nint position = FragmentPagerItem.getPosition(getArguments());\n\n```\n\nThis position will help to implement the parallax scrolling header that contains the ViewPager :P\n\n# Attributes\n\nThere are several attributes you can set:\n\n| attr | description |\n|:---|:---|\n| stl_indicatorAlwaysInCenter | If set to true, active tab is always displayed in center (Like Newsstand google app), default false |\n| stl_indicatorWithoutPadding | If set to true, draw the indicator without padding of tab, default false |\n| stl_indicatorInFront | Draw the indicator in front of the underline, default false |\n| stl_indicatorInterpolation | Behavior of the indicator: 'linear' or 'smart' |\n| stl_indicatorGravity | Drawing position of the indicator: 'bottom' or 'top' or 'center', default 'bottom' |\n| stl_indicatorColor | Color of the indicator |\n| stl_indicatorColors | Multiple colors of the indicator, can set the color for each tab |\n| stl_indicatorThickness | Thickness of the indicator |\n| stl_indicatorWidth | Width of the indicator, default 'auto' |\n| stl_indicatorCornerRadius | Radius of rounded corner the indicator |\n| stl_overlineColor | Color of the top line |\n| stl_overlineThickness | Thickness of the top line |\n| stl_underlineColor | Color of the bottom line |\n| stl_underlineThickness | Thickness of the bottom line |\n| stl_dividerColor | Color of the dividers between tabs |\n| stl_dividerColors | Multiple colors of the dividers between tabs, can set the color for each tab |\n| stl_dividerThickness | Thickness of the divider |\n| stl_defaultTabBackground | Background drawable of each tab. In general it set the StateListDrawable |\n| stl_defaultTabTextAllCaps | If set to true, all tab titles will be upper case, default true |\n| stl_defaultTabTextColor | Text color of the tab that was included by default |\n| stl_defaultTabTextSize | Text size of the tab that was included by default |\n| stl_defaultTabTextHorizontalPadding | Text layout padding of the tab that was included by default |\n| stl_defaultTabTextMinWidth | Minimum width of tab |\n| stl_customTabTextLayoutId | Layout ID defined custom tab. If you do not specify a layout, use the default tab |\n| stl_customTabTextViewId | Text view ID in a custom tab layout. If you do not define with customTabTextLayoutId, does not work |\n| stl_distributeEvenly | If set to true, each tab is given the same weight, default false |\n| stl_clickable | If set to false, disable the selection of a tab click, default true |\n| 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 |\n| stl_drawDecorationAfterTab | Draw the decoration(indicator and lines) after drawing of tab, default false |\n\n*__Notes:__ Both 'stl_indicatorAlwaysInCenter' and 'stl_distributeEvenly' if it is set to true, it will throw UnsupportedOperationException.*\n\n# How to customize the tab\n\nThe customization of tab There are three ways.\n\n* Customize the attribute\n* SmartTabLayout#setCustomTabView(int layoutResId, int textViewId)\n* SmartTabLayout#setCustomTabView(TabProvider provider)\n\nIf set the TabProvider, can build a view for each tab.\n\n```java\n\npublic class SmartTabLayout extends HorizontalScrollView {\n\n    //...\n\n    /**\n     * Create the custom tabs in the tab layout. Set with\n     * {@link #setCustomTabView(com.ogaclejapan.smarttablayout.SmartTabLayout.TabProvider)}\n     */\n    public interface TabProvider {\n\n        /**\n         * @return Return the View of {@code position} for the Tabs\n         */\n        View createTabView(ViewGroup container, int position, PagerAdapter adapter);\n\n    }\n\n    //...\n}\n\n```\n\n# How to use the utility\n\nUtility has two types available to suit the Android support library.\n\n* utils-v4 library contains the PagerAdapter implementation class for _androidx.fragment.app.Fragment_\n* (Deprecated) utils-v13 library contains the PagerAdapter implementation class for _android.app.Fragment_\n\nThe two libraries have different Android support libraries that depend,\nbut implemented functionality is the same.\n\n## PagerAdapter for View-based Page\n\n```java\n\nViewPagerItemAdapter adapter = new ViewPagerItemAdapter(ViewPagerItems.with(this)\n        .add(R.string.title, R.layout.page)\n        .add(\"title\", R.layout.page)\n        .create());\n\nviewPager.setAdapter(adapter);\n\n//...\n\npublic void onPageSelected(int position) {\n\n  //.instantiateItem() from until .destroyItem() is called it will be able to get the View of page.\n  View page = adapter.getPage(position);\n\n}\n\n\n```\n\n## PagerAdapter for Fragment-based Page\n\nFragment-based PagerAdapter There are two implementations.\nPlease differences refer to the library documentation for Android.\n\n* FragmentPagerItemAdapter extends FragmentPagerAdapter\n* FragmentStatePagerItemAdapter extends FragmentStatePagerAdapter\n\n```java\n\nFragmentPagerItemAdapter adapter = new FragmentPagerItemAdapter(\n        getSupportFragmentManager(), FragmentPagerItems.with(this)\n        .add(R.string.title, PageFragment.class),\n        .add(R.string.title, WithArgumentsPageFragment.class, new Bundler().putString(\"key\", \"value\").get()),\n        .add(\"title\", PageFragment.class)\n        .create());\n\nviewPager.setAdapter(adapter);\n\n//...\n\npublic void onPageSelected(int position) {\n\n  //.instantiateItem() from until .destoryItem() is called it will be able to get the Fragment of page.\n  Fragment page = adapter.getPage(position);\n\n}\n\n```\n\n*__Notes:__ If using fragment inside a ViewPager, Must be use [Fragment#getChildFragmentManager()](https://developer.android.com/reference/androidx/fragment/app/Fragment.html#getChildFragmentManager).*\n\n\n# Looking for iOS ?\n Check [WormTabStrip](https://github.com/EzimetYusup/WormTabStrip) out.\n \n# LICENSE\n\n```\nCopyright (C) 2015 ogaclejapan\nCopyright (C) 2013 The Android Open Source Project\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n\n[demo1_gif]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/demo1.gif\n[demo2_gif]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/demo2.gif\n[demo3_gif]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/demo3.gif\n[demo4_gif]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/demo4.gif\n[demo5_gif]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/demo5.gif\n[demo6_gif]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/demo6.gif\n[demo7_gif]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/demo7.gif\n[demo_app]: https://play.google.com/store/apps/details?id=com.ogaclejapan.smarttablayout.demo&referrer=utm_source%3Dgithub\n[demo_icon]: https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/icon.png\n[googleplay_store_badge]: http://www.android.com/images/brand/get_it_on_play_logo_large.png\n[maven_central_badge_svg]: https://maven-badges.herokuapp.com/maven-central/com.ogaclejapan.smarttablayout/library/badge.svg?style=flat\n[maven_central_badge_app]: https://maven-badges.herokuapp.com/maven-central/com.ogaclejapan.smarttablayout/library\n[android_arsenal_badge_svg]: https://img.shields.io/badge/Android%20Arsenal-SmartTabLayout-brightgreen.svg?style=flat\n[android_arsenal_badge_link]: http://android-arsenal.com/details/1/1683\n[android_weekly_badge_svg]: https://img.shields.io/badge/AndroidWeekly-%23148-blue.svg\n[android_weekly_badge_link]: http://androidweekly.net/issues/issue-148\n[qiitanium]: https://github.com/ogaclejapan/Qiitanium\n[google_slidingtabbasic]: https://github.com/googlesamples/android-SlidingTabsBasic\n"
  },
  {
    "path": "build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\next {\n  // Package information for bintray\n  pkginfo = [name       : ARTIFACT_NAME,\n             description: ARTIFACT_DESCRIPTION,\n             site       : SITE_URL,\n             issue      : ISSUE_URL,\n             vcs        : SCM_URL]\n}\n\nbuildscript {\n  repositories {\n    google()\n    mavenCentral()\n    maven {\n      url \"https://plugins.gradle.org/m2/\"\n    }\n    jcenter()\n  }\n  dependencies {\n    classpath 'com.android.tools.build:gradle:3.3.1'\n    classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'\n    classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'\n    classpath 'com.github.ben-manes:gradle-versions-plugin:0.21.0'\n    classpath 'gradle.plugin.com.hierynomus.gradle.plugins:license-gradle-plugin:0.15.0'\n\n    // NOTE: Do not place your application dependencies here; they belong\n    // in the individual module build.gradle files\n  }\n}\n\nallprojects {\n\n  version = VERSION_NAME\n  group = GROUP\n\n  repositories {\n    google()\n    mavenCentral()\n    jcenter()\n  }\n}\n\ntask clean(type: Delete) {\n  delete rootProject.buildDir\n}\n"
  },
  {
    "path": "demo/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "demo/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n  compileSdkVersion COMPILE_SDK_VERSION as int\n\n  defaultConfig {\n    minSdkVersion 14\n    targetSdkVersion COMPILE_SDK_VERSION as int\n    versionCode VERSION_CODE as int\n    versionName VERSION_NAME\n  }\n\n  def secretFile = file(\"${rootDir}/secret.gradle\")\n  if (secretFile.exists()) {\n    apply from: secretFile.absolutePath\n    signingConfigs {\n      release {\n        storeFile project.ext.storeFile\n        storePassword project.ext.storePassword\n        keyAlias project.ext.keyAlias\n        keyPassword project.ext.keyPassword\n      }\n    }\n  }\n\n  buildTypes {\n    release {\n      if (secretFile.exists()) {\n        signingConfig signingConfigs.release\n      }\n      minifyEnabled false\n      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n    }\n  }\n}\n\ndependencies {\n  implementation project(':library')\n  implementation project(':utils-v4')\n  implementation \"androidx.appcompat:appcompat:${ANDROIDX_APPCOMPAT_VERSION}\"\n}\n"
  },
  {
    "path": "demo/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/msk/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n"
  },
  {
    "path": "demo/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  package=\"com.ogaclejapan.smarttablayout.demo\"\n  >\n\n  <application\n    android:allowBackup=\"true\"\n    android:icon=\"@drawable/ic_launcher\"\n    android:label=\"@string/app_name\"\n    android:supportsRtl=\"true\"\n    android:theme=\"@style/AppTheme\"\n    >\n\n    <activity\n      android:name=\".MainActivity\"\n      android:label=\"@string/app_name\"\n      >\n      <intent-filter>\n        <action android:name=\"android.intent.action.MAIN\"/>\n        <category android:name=\"android.intent.category.LAUNCHER\"/>\n      </intent-filter>\n    </activity>\n\n    <activity\n      android:name=\".DemoActivity\"\n      android:label=\"@string/app_name\"\n      android:parentActivityName=\".MainActivity\"\n      android:theme=\"@style/AppTheme.NoActionBar\"\n      />\n\n    <activity\n      android:name=\".DemoRtlActivity\"\n      android:label=\"@string/app_name\"\n      android:parentActivityName=\".MainActivity\"\n      android:theme=\"@style/AppTheme.NoActionBar\"\n      />\n\n    <activity\n      android:name=\".DemoLikeMediumActivity\"\n      android:label=\"@string/app_name\"\n      android:parentActivityName=\".MainActivity\"\n      android:theme=\"@style/AppTheme.NoActionBar\"\n      />\n\n    <activity\n      android:name=\".DemoTabWithNotificationMarkActivity\"\n      android:label=\"@string/app_name\"\n      android:parentActivityName=\".MainActivity\"\n      android:theme=\"@style/AppTheme.NoActionBar\"\n      />\n\n  </application>\n\n</manifest>\n"
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/Demo.java",
    "content": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.content.Context;\nimport android.content.res.Resources;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.ImageView;\n\nimport com.ogaclejapan.smarttablayout.SmartTabLayout;\n\nimport androidx.viewpager.widget.PagerAdapter;\n\npublic enum Demo {\n\n  BASIC(R.string.demo_title_basic, R.layout.demo_basic),\n\n  BASIC2(R.string.demo_title_basic2, R.layout.demo_basic_title_offset_auto_center),\n\n  SMART_INDICATOR(R.string.demo_title_smart_indicator, R.layout.demo_smart_indicator),\n\n  DISTRIBUTE_EVENLY(R.string.demo_title_distribute_evenly, R.layout.demo_distribute_evenly) {\n    @Override\n    public int[] tabs() {\n      return tab3();\n    }\n  },\n\n  ALWAYS_IN_CENTER(R.string.demo_title_always_in_center, R.layout.demo_always_in_center),\n\n  CUSTOM_TAB(R.string.demo_title_custom_tab_text, R.layout.demo_custom_tab_text),\n\n  CUSTOM_TAB_COLORS(R.string.demo_title_custom_tab_colors, R.layout.demo_custom_tab_colors),\n\n  CUSTOM_TAB_ICONS1(R.string.demo_title_custom_tab_icons1, R.layout.demo_custom_tab_icons1) {\n    @Override\n    public int[] tabs() {\n      return new int[] {\n          R.string.demo_tab_no_title,\n          R.string.demo_tab_no_title,\n          R.string.demo_tab_no_title,\n          R.string.demo_tab_no_title\n      };\n    }\n\n    @Override\n    public void setup(SmartTabLayout layout) {\n      super.setup(layout);\n\n      final LayoutInflater inflater = LayoutInflater.from(layout.getContext());\n      final Resources res = layout.getContext().getResources();\n\n      layout.setCustomTabView(new SmartTabLayout.TabProvider() {\n        @Override\n        public View createTabView(ViewGroup container, int position, PagerAdapter adapter) {\n          ImageView icon = (ImageView) inflater.inflate(R.layout.custom_tab_icon1, container,\n              false);\n          switch (position) {\n            case 0:\n              icon.setImageDrawable(res.getDrawable(R.drawable.ic_home_white_24dp));\n              break;\n            case 1:\n              icon.setImageDrawable(res.getDrawable(R.drawable.ic_search_white_24dp));\n              break;\n            case 2:\n              icon.setImageDrawable(res.getDrawable(R.drawable.ic_person_white_24dp));\n              break;\n            case 3:\n              icon.setImageDrawable(res.getDrawable(R.drawable.ic_flash_on_white_24dp));\n              break;\n            default:\n              throw new IllegalStateException(\"Invalid position: \" + position);\n          }\n          return icon;\n        }\n      });\n    }\n  },\n\n  CUSTOM_TAB_ICONS2(R.string.demo_title_custom_tab_icons2, R.layout.demo_custom_tab_icons2) {\n    @Override\n    public int[] tabs() {\n      return new int[] {\n          R.string.demo_tab_no_title,\n          R.string.demo_tab_no_title,\n          R.string.demo_tab_no_title,\n          R.string.demo_tab_no_title\n      };\n    }\n\n    @Override\n    public void setup(SmartTabLayout layout) {\n      super.setup(layout);\n\n      final LayoutInflater inflater = LayoutInflater.from(layout.getContext());\n      final Resources res = layout.getContext().getResources();\n\n      layout.setCustomTabView(new SmartTabLayout.TabProvider() {\n        @Override\n        public View createTabView(ViewGroup container, int position, PagerAdapter adapter) {\n          ImageView icon = (ImageView) inflater.inflate(R.layout.custom_tab_icon2, container,\n              false);\n          switch (position) {\n            case 0:\n              icon.setImageDrawable(res.getDrawable(R.drawable.ic_home_white_24dp));\n              break;\n            case 1:\n              icon.setImageDrawable(res.getDrawable(R.drawable.ic_search_white_24dp));\n              break;\n            case 2:\n              icon.setImageDrawable(res.getDrawable(R.drawable.ic_person_white_24dp));\n              break;\n            case 3:\n              icon.setImageDrawable(res.getDrawable(R.drawable.ic_flash_on_white_24dp));\n              break;\n            default:\n              throw new IllegalStateException(\"Invalid position: \" + position);\n          }\n          return icon;\n        }\n      });\n    }\n  },\n\n  CUSTOM_TAB_ICON_AND_TEXT(R.string.demo_title_custom_tab_icon_and_text,\n      R.layout.demo_custom_tab_icon_and_text) {\n    @Override\n    public int[] tabs() {\n      return tab3();\n    }\n  },\n\n  CUSTOM_TAB_ICON_AND_NOTIFICATION_MARK(R.string.demo_title_custom_tab_icon_and_notification_mark,\n      R.layout.demo_custom_tab_icon_and_notification_mark) {\n    @Override\n    public int[] tabs() {\n      return tab3();\n    }\n\n    @Override\n    public void startActivity(Context context) {\n      DemoTabWithNotificationMarkActivity.startActivity(context, this);\n    }\n  },\n\n  CUSTOM_TAB_MARGIN(R.string.demo_title_custom_tab_margin, R.layout.demo_custom_tab_margin),\n\n  INDICATOR_TRICK1(R.string.demo_title_indicator_trick1, R.layout.demo_indicator_trick1),\n\n  INDICATOR_TRICK2(R.string.demo_title_indicator_trick2, R.layout.demo_indicator_trick2),\n\n  RIGHT_TO_LEFT(R.string.demo_title_right_to_left, R.layout.demo_rtl) {\n    @Override\n    public void startActivity(Context context) {\n      DemoRtlActivity.startActivity(context, this);\n    }\n  },\n\n  LIKE_MEDIUM_TAG(R.string.demo_title_advanced_medium, R.layout.demo_like_a_medium_tag) {\n    @Override\n    public int[] tabs() {\n      return new int[] {\n          R.string.demo_tab_like_a_medium_top,\n          R.string.demo_tab_like_a_medium_latest\n      };\n    }\n\n    @Override\n    public void startActivity(Context context) {\n      DemoLikeMediumActivity.startActivity(context, this);\n    }\n  };\n\n  public final int titleResId;\n  public final int layoutResId;\n\n  Demo(int titleResId, int layoutResId) {\n    this.titleResId = titleResId;\n    this.layoutResId = layoutResId;\n  }\n\n  public static int[] tab10() {\n    return new int[] {\n        R.string.demo_tab_1,\n        R.string.demo_tab_2,\n        R.string.demo_tab_3,\n        R.string.demo_tab_4,\n        R.string.demo_tab_5,\n        R.string.demo_tab_6,\n        R.string.demo_tab_7,\n        R.string.demo_tab_8,\n        R.string.demo_tab_9,\n        R.string.demo_tab_10\n    };\n  }\n\n  public static int[] tab3() {\n    return new int[] {\n        R.string.demo_tab_8,\n        R.string.demo_tab_9,\n        R.string.demo_tab_10\n    };\n  }\n\n  public void startActivity(Context context) {\n    DemoActivity.startActivity(context, this);\n  }\n\n  public void setup(final SmartTabLayout layout) {\n    //Do nothing.\n  }\n\n  public int[] tabs() {\n    return tab10();\n  }\n\n}\n"
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoActivity.java",
    "content": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.view.LayoutInflater;\nimport android.view.ViewGroup;\n\nimport com.ogaclejapan.smarttablayout.SmartTabLayout;\nimport com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem;\nimport com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItemAdapter;\nimport com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems;\n\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.appcompat.widget.Toolbar;\nimport androidx.viewpager.widget.ViewPager;\n\npublic class DemoActivity extends AppCompatActivity {\n\n  private static final String KEY_DEMO = \"demo\";\n\n  public static void startActivity(Context context, Demo demo) {\n    Intent intent = new Intent(context, DemoActivity.class);\n    intent.putExtra(KEY_DEMO, demo.name());\n    context.startActivity(intent);\n  }\n\n  @Override\n  protected void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.activity_demo);\n\n    Demo demo = getDemo();\n\n    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);\n    toolbar.setTitle(demo.titleResId);\n    setSupportActionBar(toolbar);\n    getSupportActionBar().setDisplayHomeAsUpEnabled(true);\n\n    ViewGroup tab = (ViewGroup) findViewById(R.id.tab);\n    tab.addView(LayoutInflater.from(this).inflate(demo.layoutResId, tab, false));\n\n    ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);\n    SmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpagertab);\n    demo.setup(viewPagerTab);\n\n    FragmentPagerItems pages = new FragmentPagerItems(this);\n    for (int titleResId : demo.tabs()) {\n      pages.add(FragmentPagerItem.of(getString(titleResId), DemoFragment.class));\n    }\n\n    FragmentPagerItemAdapter adapter = new FragmentPagerItemAdapter(\n        getSupportFragmentManager(), pages);\n\n    viewPager.setAdapter(adapter);\n    viewPagerTab.setViewPager(viewPager);\n\n  }\n\n  private Demo getDemo() {\n    return Demo.valueOf(getIntent().getStringExtra(KEY_DEMO));\n  }\n}\n"
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoFragment.java",
    "content": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.os.Bundle;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.TextView;\n\nimport com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem;\n\nimport androidx.annotation.Nullable;\nimport androidx.fragment.app.Fragment;\n\npublic class DemoFragment extends Fragment {\n\n  @Override\n  public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,\n      @Nullable Bundle savedInstanceState) {\n    return inflater.inflate(R.layout.fragment_demo, container, false);\n  }\n\n  @Override\n  public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {\n    super.onViewCreated(view, savedInstanceState);\n    int position = FragmentPagerItem.getPosition(getArguments());\n    TextView title = (TextView) view.findViewById(R.id.item_title);\n    title.setText(String.valueOf(position));\n  }\n\n}\n"
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoLikeMediumActivity.java",
    "content": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.view.LayoutInflater;\nimport android.view.ViewGroup;\n\nimport com.ogaclejapan.smarttablayout.SmartTabLayout;\nimport com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem;\nimport com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItemAdapter;\nimport com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems;\n\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.appcompat.widget.Toolbar;\nimport androidx.viewpager.widget.ViewPager;\n\npublic class DemoLikeMediumActivity extends AppCompatActivity {\n\n  private static final String KEY_DEMO = \"demo\";\n\n  public static void startActivity(Context context, Demo demo) {\n    Intent intent = new Intent(context, DemoLikeMediumActivity.class);\n    intent.putExtra(KEY_DEMO, demo.name());\n    context.startActivity(intent);\n  }\n\n  @Override\n  protected void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.activity_like_a_medium);\n\n    Demo demo = getDemo();\n\n    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);\n    toolbar.setTitle(demo.titleResId);\n    setSupportActionBar(toolbar);\n    getSupportActionBar().setDisplayHomeAsUpEnabled(true);\n\n    ViewGroup tab = (ViewGroup) findViewById(R.id.tab);\n    tab.addView(LayoutInflater.from(this).inflate(demo.layoutResId, tab, false));\n\n    ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);\n    SmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpagertab);\n    demo.setup(viewPagerTab);\n\n    FragmentPagerItems pages = new FragmentPagerItems(this);\n    for (int titleResId : demo.tabs()) {\n      pages.add(FragmentPagerItem.of(getString(titleResId), DemoFragment.class));\n    }\n\n    FragmentPagerItemAdapter adapter = new FragmentPagerItemAdapter(\n        getSupportFragmentManager(), pages);\n\n    viewPager.setAdapter(adapter);\n    viewPagerTab.setViewPager(viewPager);\n\n  }\n\n  private Demo getDemo() {\n    return Demo.valueOf(getIntent().getStringExtra(KEY_DEMO));\n  }\n}\n"
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoRtlActivity.java",
    "content": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.view.LayoutInflater;\nimport android.view.ViewGroup;\n\nimport com.ogaclejapan.smarttablayout.SmartTabLayout;\nimport com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem;\nimport com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItemAdapter;\nimport com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems;\n\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.appcompat.widget.Toolbar;\nimport androidx.viewpager.widget.ViewPager;\n\npublic class DemoRtlActivity extends AppCompatActivity {\n\n  private static final String KEY_DEMO = \"demo\";\n\n  public static void startActivity(Context context, Demo demo) {\n    Intent intent = new Intent(context, DemoRtlActivity.class);\n    intent.putExtra(KEY_DEMO, demo.name());\n    context.startActivity(intent);\n  }\n\n  @Override\n  protected void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.activity_rtl);\n\n    Demo demo = getDemo();\n\n    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);\n    toolbar.setTitle(demo.titleResId);\n    setSupportActionBar(toolbar);\n    getSupportActionBar().setDisplayHomeAsUpEnabled(true);\n\n    ViewGroup tab = (ViewGroup) findViewById(R.id.tab);\n    tab.addView(LayoutInflater.from(this).inflate(demo.layoutResId, tab, false));\n\n    ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);\n    final SmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpagertab);\n    demo.setup(viewPagerTab);\n\n    FragmentPagerItems pages = new FragmentPagerItems(this);\n    for (int titleResId : demo.tabs()) {\n      pages.add(FragmentPagerItem.of(getString(titleResId), DemoFragment.class));\n    }\n\n    FragmentPagerItemAdapter adapter = new FragmentPagerItemAdapter(\n        getSupportFragmentManager(), pages);\n\n    viewPager.setAdapter(adapter);\n    viewPagerTab.setViewPager(viewPager);\n\n  }\n\n  private Demo getDemo() {\n    return Demo.valueOf(getIntent().getStringExtra(KEY_DEMO));\n  }\n}\n"
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/DemoTabWithNotificationMarkActivity.java",
    "content": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.res.Resources;\nimport android.os.Bundle;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.ImageView;\n\nimport com.ogaclejapan.smarttablayout.SmartTabLayout;\nimport com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem;\nimport com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItemAdapter;\nimport com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems;\n\nimport java.util.Random;\n\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.appcompat.widget.Toolbar;\nimport androidx.viewpager.widget.PagerAdapter;\nimport androidx.viewpager.widget.ViewPager;\n\npublic class DemoTabWithNotificationMarkActivity extends AppCompatActivity implements\n    SmartTabLayout.TabProvider {\n\n  private static final String KEY_DEMO = \"demo\";\n\n  public static void startActivity(Context context, Demo demo) {\n    Intent intent = new Intent(context, DemoTabWithNotificationMarkActivity.class);\n    intent.putExtra(KEY_DEMO, demo.name());\n    context.startActivity(intent);\n  }\n\n  private Random random = new Random(System.currentTimeMillis());\n\n  @Override\n  protected void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.activity_demo_tab_with_notification_mark);\n\n    final Demo demo = getDemo();\n\n    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);\n    toolbar.setTitle(demo.titleResId);\n    setSupportActionBar(toolbar);\n    getSupportActionBar().setDisplayHomeAsUpEnabled(true);\n\n    ViewGroup tab = (ViewGroup) findViewById(R.id.tab);\n    tab.addView(LayoutInflater.from(this).inflate(demo.layoutResId, tab, false));\n\n    ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);\n    final SmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpagertab);\n    viewPagerTab.setCustomTabView(this);\n\n    FragmentPagerItems pages = new FragmentPagerItems(this);\n    for (int titleResId : demo.tabs()) {\n      pages.add(FragmentPagerItem.of(getString(titleResId), DemoFragment.class));\n    }\n\n    FragmentPagerItemAdapter adapter = new FragmentPagerItemAdapter(\n        getSupportFragmentManager(), pages);\n\n    viewPager.setAdapter(adapter);\n    viewPagerTab.setViewPager(viewPager);\n\n    viewPagerTab.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {\n      @Override\n      public void onPageSelected(int position) {\n        super.onPageSelected(position);\n        View tab = viewPagerTab.getTabAt(position);\n        View mark = tab.findViewById(R.id.custom_tab_notification_mark);\n        mark.setVisibility(View.GONE);\n      }\n    });\n\n    findViewById(R.id.test).setOnClickListener(new View.OnClickListener() {\n      @Override\n      public void onClick(View v) {\n        int position = Math.abs(random.nextInt()) % demo.tabs().length;\n        View tab = viewPagerTab.getTabAt(position);\n        View mark = tab.findViewById(R.id.custom_tab_notification_mark);\n        mark.setVisibility(View.VISIBLE);\n      }\n    });\n\n  }\n\n  @Override\n  public View createTabView(ViewGroup container, int position, PagerAdapter adapter) {\n    LayoutInflater inflater = LayoutInflater.from(container.getContext());\n    Resources res = container.getContext().getResources();\n    View tab = inflater.inflate(R.layout.custom_tab_icon_and_notification_mark, container, false);\n    View mark = tab.findViewById(R.id.custom_tab_notification_mark);\n    mark.setVisibility(View.GONE);\n    ImageView icon = (ImageView) tab.findViewById(R.id.custom_tab_icon);\n    switch (position) {\n      case 0:\n        icon.setImageDrawable(res.getDrawable(R.drawable.ic_home_white_24dp));\n        break;\n      case 1:\n        icon.setImageDrawable(res.getDrawable(R.drawable.ic_search_white_24dp));\n        break;\n      case 2:\n        icon.setImageDrawable(res.getDrawable(R.drawable.ic_person_white_24dp));\n        break;\n      default:\n        throw new IllegalStateException(\"Invalid position: \" + position);\n    }\n    return tab;\n  }\n\n  private Demo getDemo() {\n    return Demo.valueOf(getIntent().getStringExtra(KEY_DEMO));\n  }\n}\n"
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/MainActivity.java",
    "content": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.content.Intent;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.view.Menu;\nimport android.view.MenuItem;\nimport android.view.View;\nimport android.widget.AbsListView;\nimport android.widget.AdapterView;\nimport android.widget.ArrayAdapter;\nimport android.widget.ListView;\n\nimport androidx.appcompat.app.AppCompatActivity;\n\npublic class MainActivity extends AppCompatActivity implements AbsListView.OnItemClickListener {\n\n  @Override\n  protected void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.activity_main);\n    ListView listView = (ListView) findViewById(R.id.list);\n    listView.setOnItemClickListener(this);\n\n    ArrayAdapter<String> demoAdapter = new ArrayAdapter<String>(this,\n        android.R.layout.simple_list_item_1);\n\n    for (Demo demo : Demo.values()) {\n      demoAdapter.add(getString(demo.titleResId));\n    }\n\n    listView.setAdapter(demoAdapter);\n  }\n\n  @Override\n  public boolean onCreateOptionsMenu(Menu menu) {\n    getMenuInflater().inflate(R.menu.menu_main, menu);\n    return super.onCreateOptionsMenu(menu);\n  }\n\n  @Override\n  public boolean onOptionsItemSelected(MenuItem item) {\n    switch (item.getItemId()) {\n      case R.id.menu_github:\n        openGitHub();\n        return true;\n      default:\n        return super.onOptionsItemSelected(item);\n    }\n  }\n\n  @Override\n  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {\n    Demo demo = Demo.values()[position];\n    demo.startActivity(this);\n  }\n\n  private void openGitHub() {\n    Uri uri = Uri.parse(getString(R.string.app_github_url));\n    Intent intent = new Intent(Intent.ACTION_VIEW, uri);\n    startActivity(intent);\n  }\n\n}\n"
  },
  {
    "path": "demo/src/main/java/com/ogaclejapan/smarttablayout/demo/TintableImageView.java",
    "content": "package com.ogaclejapan.smarttablayout.demo;\n\nimport android.content.Context;\nimport android.content.res.ColorStateList;\nimport android.content.res.TypedArray;\nimport android.util.AttributeSet;\n\nimport androidx.appcompat.widget.AppCompatImageView;\n\n/**\n * https://gist.github.com/tylerchesley/5d15d859be4f3ce31213\n */\npublic class TintableImageView extends AppCompatImageView {\n\n  private ColorStateList tint;\n\n  public TintableImageView(Context context) {\n    super(context);\n  }\n\n  public TintableImageView(Context context, AttributeSet attrs) {\n    super(context, attrs);\n    init(context, attrs, 0);\n  }\n\n  public TintableImageView(Context context, AttributeSet attrs, int defStyle) {\n    super(context, attrs, defStyle);\n    init(context, attrs, defStyle);\n  }\n\n  private void init(Context context, AttributeSet attrs, int defStyle) {\n    TypedArray a = context.obtainStyledAttributes(\n        attrs, R.styleable.TintableImageView, defStyle, 0);\n    tint = a.getColorStateList(\n        R.styleable.TintableImageView_tint);\n    a.recycle();\n  }\n\n  @Override\n  protected void drawableStateChanged() {\n    super.drawableStateChanged();\n    if (tint != null && tint.isStateful()) {\n      updateTintColor();\n    }\n  }\n\n  public void setColorFilter(ColorStateList tint) {\n    this.tint = tint;\n    super.setColorFilter(tint.getColorForState(getDrawableState(), 0));\n  }\n\n  private void updateTintColor() {\n    int color = tint.getColorForState(getDrawableState(), 0);\n    setColorFilter(color);\n  }\n\n}\n"
  },
  {
    "path": "demo/src/main/res/color/custom_tab.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <item android:color=\"@color/text_enabled\" android:state_selected=\"true\"/>\n  <item android:color=\"@color/text_disabled\" android:state_selected=\"false\"/>\n</selector>\n"
  },
  {
    "path": "demo/src/main/res/color/custom_tab_icon.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <item android:color=\"@color/icon_enabled\" android:state_selected=\"true\"/>\n  <item android:color=\"@color/icon_disabled\" android:state_selected=\"false\"/>\n</selector>"
  },
  {
    "path": "demo/src/main/res/color/custom_tab_like_a_medium.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <item android:color=\"@color/medium_text_enabled\" android:state_selected=\"true\"/>\n  <item android:color=\"@color/medium_text_disabled\" android:state_selected=\"false\"/>\n</selector>"
  },
  {
    "path": "demo/src/main/res/drawable/custom_circle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:shape=\"oval\"\n  >\n\n  <solid android:color=\"@android:color/transparent\"/>\n\n  <stroke\n    android:width=\"1dp\"\n    android:color=\"@color/icon_disabled\"\n    />\n</shape>"
  },
  {
    "path": "demo/src/main/res/drawable/custom_icon.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <item android:drawable=\"@drawable/ic_flash_on_white_24dp\" android:state_selected=\"true\"/>\n  <item android:drawable=\"@drawable/ic_home_white_24dp\"/>\n</selector>\n"
  },
  {
    "path": "demo/src/main/res/drawable/custom_tab.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <item android:state_pressed=\"true\">\n    <shape android:shape=\"rectangle\">\n      <solid android:color=\"@color/black_20\"/>\n    </shape>\n  </item>\n  <item android:drawable=\"@color/transparent\"/>\n</selector>"
  },
  {
    "path": "demo/src/main/res/drawable/shape_notification_mark.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:shape=\"oval\"\n  >\n  <solid android:color=\"@color/accent\"/>\n</shape>\n"
  },
  {
    "path": "demo/src/main/res/layout/activity_demo.xml",
    "content": "<RelativeLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"match_parent\"\n  >\n\n  <LinearLayout\n    android:id=\"@+id/header\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:background=\"@color/primary\"\n    >\n\n    <androidx.appcompat.widget.Toolbar\n      android:id=\"@id/toolbar\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"wrap_content\"\n      android:minHeight=\"?attr/actionBarSize\"\n      app:popupTheme=\"@style/ThemeOverlay.AppCompat.Light\"\n      app:theme=\"@style/ThemeOverlay.AppCompat.Dark.ActionBar\"\n      >\n\n    </androidx.appcompat.widget.Toolbar>\n\n    <FrameLayout\n      android:id=\"@id/tab\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"wrap_content\"\n      />\n\n  </LinearLayout>\n\n  <androidx.viewpager.widget.ViewPager\n    android:id=\"@id/viewpager\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:layout_below=\"@id/header\"\n    />\n\n</RelativeLayout>\n"
  },
  {
    "path": "demo/src/main/res/layout/activity_demo_tab_with_notification_mark.xml",
    "content": "<RelativeLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"match_parent\"\n  >\n\n  <LinearLayout\n    android:id=\"@+id/header\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:background=\"@color/primary\"\n    >\n\n    <androidx.appcompat.widget.Toolbar\n      android:id=\"@id/toolbar\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"wrap_content\"\n      android:minHeight=\"?attr/actionBarSize\"\n      app:popupTheme=\"@style/ThemeOverlay.AppCompat.Light\"\n      app:theme=\"@style/ThemeOverlay.AppCompat.Dark.ActionBar\"\n      />\n\n    <FrameLayout\n      android:id=\"@id/tab\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"wrap_content\"\n      />\n\n  </LinearLayout>\n\n  <androidx.viewpager.widget.ViewPager\n    android:id=\"@id/viewpager\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:layout_below=\"@id/header\"\n    />\n\n  <Button\n    android:id=\"@+id/test\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:layout_alignParentBottom=\"true\"\n    android:layout_margin=\"8dp\"\n    android:padding=\"8dp\"\n    android:text=\"Try notification mark\"\n    />\n\n</RelativeLayout>\n"
  },
  {
    "path": "demo/src/main/res/layout/activity_like_a_medium.xml",
    "content": "<RelativeLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"match_parent\"\n  android:background=\"@color/white\"\n  >\n\n  <LinearLayout\n    android:id=\"@+id/header\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    >\n\n    <androidx.appcompat.widget.Toolbar\n      android:id=\"@id/toolbar\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"wrap_content\"\n      android:background=\"@color/transparent\"\n      android:minHeight=\"?attr/actionBarSize\"\n      app:popupTheme=\"@style/ThemeOverlay.AppCompat.Dark.ActionBar\"\n      app:theme=\"@style/ThemeOverlay.AppCompat.Light\"\n      />\n\n    <FrameLayout\n      android:id=\"@id/tab\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"@dimen/tab_height\"\n      />\n\n  </LinearLayout>\n\n  <androidx.viewpager.widget.ViewPager\n    android:id=\"@id/viewpager\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:layout_below=\"@id/header\"\n    />\n\n</RelativeLayout>\n"
  },
  {
    "path": "demo/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"match_parent\"\n  >\n\n  <ListView\n    android:id=\"@+id/list\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    />\n\n</FrameLayout>"
  },
  {
    "path": "demo/src/main/res/layout/activity_rtl.xml",
    "content": "<RelativeLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"match_parent\"\n  android:layoutDirection=\"rtl\"\n  >\n\n  <LinearLayout\n    android:id=\"@+id/header\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:background=\"@color/primary\"\n    >\n\n    <androidx.appcompat.widget.Toolbar\n      android:id=\"@id/toolbar\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"wrap_content\"\n      android:minHeight=\"?attr/actionBarSize\"\n      app:popupTheme=\"@style/ThemeOverlay.AppCompat.Light\"\n      app:theme=\"@style/ThemeOverlay.AppCompat.Dark.ActionBar\"\n      />\n\n    <FrameLayout\n      android:id=\"@id/tab\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"@dimen/tab_height\"\n      />\n\n  </LinearLayout>\n\n  <androidx.viewpager.widget.ViewPager\n    android:id=\"@id/viewpager\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:layout_below=\"@id/header\"\n    />\n\n</RelativeLayout>\n"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TextView\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:id=\"@+id/custom_text\"\n  android:layout_width=\"wrap_content\"\n  android:layout_height=\"match_parent\"\n  android:background=\"?attr/selectableItemBackground\"\n  android:gravity=\"center\"\n  android:paddingLeft=\"24dp\"\n  android:paddingRight=\"24dp\"\n  android:textColor=\"@color/custom_tab\"\n  android:textSize=\"14sp\"\n  >\n\n</TextView>"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab_circle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<View\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:layout_width=\"8dp\"\n  android:layout_height=\"8dp\"\n  android:layout_gravity=\"center_vertical\"\n  android:layout_marginLeft=\"1dp\"\n  android:layout_marginRight=\"1dp\"\n  android:background=\"@drawable/custom_circle\"\n  />\n\n"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab_icon1.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.ogaclejapan.smarttablayout.demo.TintableImageView\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:layout_width=\"wrap_content\"\n  android:layout_height=\"match_parent\"\n  android:background=\"?attr/selectableItemBackground\"\n  android:scaleType=\"center\"\n  app:tint=\"@color/custom_tab_icon\"\n  />\n\n"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab_icon2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.ogaclejapan.smarttablayout.demo.TintableImageView\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:layout_width=\"48dp\"\n  android:layout_height=\"48dp\"\n  android:background=\"?attr/selectableItemBackground\"\n  android:padding=\"6dp\"\n  android:scaleType=\"center\"\n  app:tint=\"@color/custom_tab_icon\"\n  />\n\n"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab_icon_and_notification_mark.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"match_parent\"\n  android:background=\"?attr/selectableItemBackground\"\n  >\n\n  <com.ogaclejapan.smarttablayout.demo.TintableImageView\n    android:id=\"@+id/custom_tab_icon\"\n    android:layout_width=\"24dp\"\n    android:layout_height=\"24dp\"\n    android:layout_centerInParent=\"true\"\n    android:scaleType=\"center\"\n    app:tint=\"@color/custom_tab_icon\"\n    />\n\n  <View\n    android:id=\"@+id/custom_tab_notification_mark\"\n    android:layout_width=\"4dp\"\n    android:layout_height=\"4dp\"\n    android:layout_above=\"@id/custom_tab_icon\"\n    android:layout_toRightOf=\"@id/custom_tab_icon\"\n    android:background=\"@drawable/shape_notification_mark\"\n    android:visibility=\"gone\"\n    />\n\n</RelativeLayout>\n"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab_icon_and_text.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"match_parent\"\n  android:background=\"?attr/selectableItemBackground\"\n  >\n\n  <Space\n    android:id=\"@+id/center_anchor\"\n    android:layout_width=\"0dp\"\n    android:layout_height=\"0dp\"\n    android:layout_centerInParent=\"true\"\n    />\n\n  <com.ogaclejapan.smarttablayout.demo.TintableImageView\n    android:id=\"@+id/custom_tab_icon\"\n    android:layout_width=\"24dp\"\n    android:layout_height=\"24dp\"\n    android:layout_above=\"@id/center_anchor\"\n    android:layout_centerHorizontal=\"true\"\n    android:scaleType=\"center\"\n    android:src=\"@drawable/custom_icon\"\n    app:tint=\"@color/custom_tab_icon\"\n    />\n\n  <TextView\n    android:id=\"@+id/custom_tab_text\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:layout_below=\"@id/center_anchor\"\n    android:layout_centerHorizontal=\"true\"\n    android:layout_marginTop=\"2dp\"\n    android:maxLines=\"1\"\n    android:textColor=\"@color/custom_tab\"\n    android:textSize=\"14sp\"\n    />\n\n</RelativeLayout>\n"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab_like_a_medium.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TextView\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:id=\"@+id/custom_text\"\n  android:layout_width=\"wrap_content\"\n  android:layout_height=\"match_parent\"\n  android:background=\"?attr/selectableItemBackground\"\n  android:gravity=\"center\"\n  android:paddingLeft=\"24dp\"\n  android:paddingRight=\"24dp\"\n  android:textAllCaps=\"true\"\n  android:textColor=\"@color/custom_tab_like_a_medium\"\n  android:textSize=\"14sp\"\n  android:textStyle=\"bold\"\n  >\n\n</TextView>"
  },
  {
    "path": "demo/src/main/res/layout/custom_tab_margin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TextView\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:id=\"@+id/custom_text\"\n  android:layout_width=\"wrap_content\"\n  android:layout_height=\"match_parent\"\n  android:layout_marginLeft=\"8dp\"\n  android:layout_marginRight=\"8dp\"\n  android:background=\"?attr/selectableItemBackground\"\n  android:gravity=\"center\"\n  android:paddingLeft=\"24dp\"\n  android:paddingRight=\"24dp\"\n  android:textColor=\"@color/custom_tab\"\n  android:textSize=\"14sp\"\n  >\n\n</TextView>"
  },
  {
    "path": "demo/src/main/res/layout/demo_always_in_center.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"@dimen/tab_height\"\n  android:paddingBottom=\"4dp\"\n  app:stl_defaultTabTextColor=\"@color/white\"\n  app:stl_defaultTabTextMinWidth=\"120dp\"\n  app:stl_indicatorAlwaysInCenter=\"true\"\n  app:stl_indicatorColor=\"@color/accent\"\n  app:stl_indicatorCornerRadius=\"1.5dp\"\n  app:stl_indicatorInterpolation=\"smart\"\n  app:stl_indicatorThickness=\"3dp\"\n  app:stl_underlineColor=\"@color/transparent\"\n  />\n\n\n"
  },
  {
    "path": "demo/src/main/res/layout/demo_basic.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"@dimen/tab_height\"\n  android:background=\"@color/primary\"\n  app:stl_defaultTabTextColor=\"@color/white\"\n  app:stl_defaultTabTextHorizontalPadding=\"24dp\"\n  app:stl_indicatorColor=\"@color/accent\"\n  app:stl_indicatorInterpolation=\"linear\"\n  app:stl_indicatorThickness=\"3dp\"\n  app:stl_underlineThickness=\"1dp\"\n  />\n\n\n"
  },
  {
    "path": "demo/src/main/res/layout/demo_basic_title_offset_auto_center.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"@dimen/tab_height\"\n  app:stl_defaultTabTextColor=\"@color/white\"\n  app:stl_defaultTabTextHorizontalPadding=\"24dp\"\n  app:stl_indicatorColor=\"@color/accent\"\n  app:stl_indicatorInterpolation=\"linear\"\n  app:stl_indicatorThickness=\"3dp\"\n  app:stl_titleOffset=\"auto_center\"\n  app:stl_underlineThickness=\"1dp\"\n  />\n\n"
  },
  {
    "path": "demo/src/main/res/layout/demo_custom_tab_colors.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"@dimen/tab_height\"\n  app:stl_defaultTabTextColor=\"@color/white\"\n  app:stl_defaultTabTextHorizontalPadding=\"24dp\"\n  app:stl_dividerColors=\"@array/custom_tab_colors\"\n  app:stl_indicatorColors=\"@array/custom_tab_colors\"\n  app:stl_indicatorInterpolation=\"linear\"\n  app:stl_indicatorThickness=\"3dp\"\n  app:stl_underlineThickness=\"1dp\"\n  />\n\n\n"
  },
  {
    "path": "demo/src/main/res/layout/demo_custom_tab_icon_and_notification_mark.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"@dimen/tab_height\"\n  app:stl_distributeEvenly=\"true\"\n  app:stl_indicatorColor=\"@color/accent\"\n  app:stl_indicatorInterpolation=\"linear\"\n  app:stl_indicatorThickness=\"3dp\"\n  app:stl_underlineThickness=\"1dp\"\n  />\n"
  },
  {
    "path": "demo/src/main/res/layout/demo_custom_tab_icon_and_text.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"@dimen/tab_height_large\"\n  app:stl_customTabTextLayoutId=\"@layout/custom_tab_icon_and_text\"\n  app:stl_customTabTextViewId=\"@id/custom_tab_text\"\n  app:stl_distributeEvenly=\"true\"\n  app:stl_indicatorColor=\"@color/accent\"\n  app:stl_indicatorInterpolation=\"linear\"\n  app:stl_indicatorThickness=\"3dp\"\n  app:stl_underlineThickness=\"1dp\"\n  />\n"
  },
  {
    "path": "demo/src/main/res/layout/demo_custom_tab_icons1.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"@dimen/tab_height\"\n  app:stl_distributeEvenly=\"true\"\n  app:stl_dividerColor=\"@color/transparent\"\n  app:stl_dividerThickness=\"0dp\"\n  app:stl_indicatorColor=\"@color/transparent\"\n  app:stl_indicatorThickness=\"0dp\"\n  app:stl_underlineColor=\"@color/transparent\"\n  app:stl_underlineThickness=\"0dp\"\n  />\n\n\n"
  },
  {
    "path": "demo/src/main/res/layout/demo_custom_tab_icons2.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"wrap_content\"\n  android:layout_height=\"@dimen/tab_height\"\n  android:layout_gravity=\"center_horizontal\"\n  app:stl_dividerColor=\"@color/transparent\"\n  app:stl_dividerThickness=\"0dp\"\n  app:stl_indicatorColor=\"@color/white_20\"\n  app:stl_indicatorCornerRadius=\"18dp\"\n  app:stl_indicatorGravity=\"center\"\n  app:stl_indicatorInterpolation=\"linear\"\n  app:stl_indicatorThickness=\"36dp\"\n  app:stl_indicatorWithoutPadding=\"true\"\n  app:stl_underlineColor=\"@color/transparent\"\n  app:stl_underlineThickness=\"0dp\"\n  />\n\n\n"
  },
  {
    "path": "demo/src/main/res/layout/demo_custom_tab_margin.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"@dimen/tab_height\"\n  app:stl_customTabTextLayoutId=\"@layout/custom_tab_margin\"\n  app:stl_customTabTextViewId=\"@id/custom_text\"\n  app:stl_indicatorColor=\"@color/accent\"\n  app:stl_indicatorInterpolation=\"linear\"\n  app:stl_indicatorThickness=\"3dp\"\n  app:stl_underlineThickness=\"1dp\"\n  />\n\n\n"
  },
  {
    "path": "demo/src/main/res/layout/demo_custom_tab_text.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"@dimen/tab_height\"\n  app:stl_customTabTextLayoutId=\"@layout/custom_tab\"\n  app:stl_customTabTextViewId=\"@id/custom_text\"\n  app:stl_indicatorColor=\"@color/accent\"\n  app:stl_indicatorInterpolation=\"linear\"\n  app:stl_indicatorThickness=\"3dp\"\n  app:stl_underlineThickness=\"1dp\"\n  />\n\n\n"
  },
  {
    "path": "demo/src/main/res/layout/demo_distribute_evenly.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"@dimen/tab_height\"\n  android:paddingBottom=\"4dp\"\n  app:stl_defaultTabTextColor=\"@color/white\"\n  app:stl_distributeEvenly=\"true\"\n  app:stl_indicatorColor=\"@color/accent\"\n  app:stl_indicatorCornerRadius=\"1.5dp\"\n  app:stl_indicatorInterpolation=\"smart\"\n  app:stl_indicatorThickness=\"3dp\"\n  app:stl_underlineColor=\"@color/transparent\"\n  />\n\n\n"
  },
  {
    "path": "demo/src/main/res/layout/demo_indicator_trick1.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"@dimen/tab_height\"\n  android:clipToPadding=\"false\"\n  android:paddingLeft=\"4dp\"\n  android:paddingRight=\"4dp\"\n  app:stl_defaultTabTextColor=\"@color/white\"\n  app:stl_defaultTabTextHorizontalPadding=\"18dp\"\n  app:stl_dividerColor=\"@color/transparent\"\n  app:stl_dividerThickness=\"0dp\"\n  app:stl_indicatorColor=\"@color/black_20\"\n  app:stl_indicatorCornerRadius=\"18dp\"\n  app:stl_indicatorGravity=\"center\"\n  app:stl_indicatorInterpolation=\"smart\"\n  app:stl_indicatorThickness=\"36dp\"\n  app:stl_underlineColor=\"@color/transparent\"\n  app:stl_underlineThickness=\"0dp\"\n  />\n\n\n"
  },
  {
    "path": "demo/src/main/res/layout/demo_indicator_trick2.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"wrap_content\"\n  android:layout_height=\"16dp\"\n  android:layout_gravity=\"bottom|center_horizontal\"\n  app:stl_clickable=\"false\"\n  app:stl_customTabTextLayoutId=\"@layout/custom_tab_circle\"\n  app:stl_dividerColor=\"@color/transparent\"\n  app:stl_dividerThickness=\"0dp\"\n  app:stl_indicatorColor=\"@color/accent\"\n  app:stl_indicatorCornerRadius=\"4dp\"\n  app:stl_indicatorGravity=\"center\"\n  app:stl_indicatorInterpolation=\"linear\"\n  app:stl_indicatorThickness=\"8dp\"\n  app:stl_underlineColor=\"@color/transparent\"\n  app:stl_underlineThickness=\"0dp\"\n  />\n\n\n"
  },
  {
    "path": "demo/src/main/res/layout/demo_like_a_medium_tag.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"@dimen/tab_height\"\n  app:stl_customTabTextLayoutId=\"@layout/custom_tab_like_a_medium\"\n  app:stl_customTabTextViewId=\"@id/custom_text\"\n  app:stl_dividerColor=\"@color/transparent\"\n  app:stl_dividerThickness=\"0dp\"\n  app:stl_indicatorColor=\"@color/black\"\n  app:stl_indicatorCornerRadius=\"1dp\"\n  app:stl_indicatorGravity=\"top\"\n  app:stl_indicatorInterpolation=\"linear\"\n  app:stl_indicatorThickness=\"1dp\"\n  app:stl_indicatorWidth=\"48dp\"\n  app:stl_indicatorWithoutPadding=\"true\"\n  app:stl_overlineColor=\"@color/black_20\"\n  app:stl_overlineThickness=\"1dp\"\n  app:stl_underlineColor=\"@color/transparent\"\n  app:stl_underlineThickness=\"0dp\"\n  />\n\n\n"
  },
  {
    "path": "demo/src/main/res/layout/demo_rtl.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"@dimen/tab_height\"\n  app:stl_defaultTabTextColor=\"@color/white\"\n  app:stl_defaultTabTextHorizontalPadding=\"24dp\"\n  app:stl_indicatorColor=\"@color/accent\"\n  app:stl_indicatorInterpolation=\"linear\"\n  app:stl_indicatorThickness=\"3dp\"\n  app:stl_underlineThickness=\"1dp\"\n  />\n\n\n"
  },
  {
    "path": "demo/src/main/res/layout/demo_smart_indicator.xml",
    "content": "<com.ogaclejapan.smarttablayout.SmartTabLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  android:id=\"@id/viewpagertab\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"@dimen/tab_height\"\n  android:paddingBottom=\"4dp\"\n  app:stl_defaultTabTextColor=\"@color/white\"\n  app:stl_defaultTabTextHorizontalPadding=\"24dp\"\n  app:stl_indicatorColor=\"@color/accent\"\n  app:stl_indicatorCornerRadius=\"1.5dp\"\n  app:stl_indicatorInterpolation=\"smart\"\n  app:stl_indicatorThickness=\"3dp\"\n  app:stl_underlineColor=\"@color/transparent\"\n  />\n"
  },
  {
    "path": "demo/src/main/res/layout/fragment_demo.xml",
    "content": "<LinearLayout\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:orientation=\"vertical\"\n  android:layout_width=\"match_parent\"\n  android:layout_height=\"match_parent\"\n  android:gravity=\"center\"\n  >\n\n  <TextView\n    android:id=\"@+id/item_subtitle\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:text=\"Page:\"\n    android:textAppearance=\"?android:attr/textAppearanceLarge\"\n    />\n\n  <TextView\n    android:id=\"@+id/item_title\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:textSize=\"80sp\"\n    />\n\n</LinearLayout>\n"
  },
  {
    "path": "demo/src/main/res/menu/menu_demo.xml",
    "content": "<menu\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  xmlns:tools=\"http://schemas.android.com/tools\"\n  tools:context=\".DemoActivity\"\n  >\n  <item\n    android:id=\"@+id/action_settings\"\n    android:orderInCategory=\"100\"\n    android:title=\"@string/action_settings\"\n    app:showAsAction=\"never\"\n    />\n</menu>\n"
  },
  {
    "path": "demo/src/main/res/menu/menu_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu\n  xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n  >\n\n  <item\n    android:id=\"@+id/menu_github\"\n    android:icon=\"@null\"\n    android:title=\"@string/app_github\"\n    app:showAsAction=\"always\"\n    />\n\n</menu>"
  },
  {
    "path": "demo/src/main/res/values/attrs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n  <declare-styleable name=\"TintableImageView\">\n    <attr name=\"tint\" format=\"reference|color\"/>\n  </declare-styleable>\n</resources>"
  },
  {
    "path": "demo/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n  <color name=\"primary\">#3C515C</color>\n  <color name=\"primary_dark\">#142E3C</color>\n  <color name=\"accent\">#40C4FF</color>\n  <color name=\"white\">#FFFFFFFF</color>\n  <color name=\"black\">#FF000000</color>\n  <color name=\"black_20\">#33000000</color>\n  <color name=\"white_20\">#33FFFFFF</color>\n  <color name=\"transparent\">#00000000</color>\n\n  <color name=\"text_enabled\">#FFFFFFFF</color>\n  <color name=\"text_disabled\">#4DFFFFFF</color>\n\n  <color name=\"icon_enabled\">#FFFFFFFF</color>\n  <color name=\"icon_disabled\">#FF63727B</color>\n\n  <color name=\"medium_text_enabled\">#FF000000</color>\n  <color name=\"medium_text_disabled\">#4D000000</color>\n\n  <color name=\"light_blue_500\">#03A9F4</color>\n  <color name=\"cyan_500\">#00BCD4</color>\n  <color name=\"teal_500\">#009688</color>\n  <color name=\"green_500\">#4CAF50</color>\n  <color name=\"light_green_500\">#8BC34A</color>\n\n  <integer-array name=\"custom_tab_colors\">\n    <item>@color/light_blue_500</item>\n    <item>@color/cyan_500</item>\n    <item>@color/teal_500</item>\n    <item>@color/green_500</item>\n    <item>@color/light_green_500</item>\n  </integer-array>\n\n</resources>"
  },
  {
    "path": "demo/src/main/res/values/dimens.xml",
    "content": "<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",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n  <item name=\"toolbar\" type=\"id\"/>\n  <item name=\"tab\" type=\"id\"/>\n  <item name=\"viewpager\" type=\"id\"/>\n  <item name=\"viewpagertab\" type=\"id\"/>\n</resources>"
  },
  {
    "path": "demo/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n  <string name=\"app_name\">SmartTabLayout</string>\n  <string name=\"app_github\">GitHub</string>\n  <string name=\"app_github_url\"><![CDATA[https://github.com/ogaclejapan/SmartTabLayout]]></string>\n  <string name=\"action_settings\">Settings</string>\n\n  <string name=\"demo_title_basic\">Basic</string>\n  <string name=\"demo_title_basic2\">Basic(Title Offset Auto Center)</string>\n  <string name=\"demo_title_smart_indicator\">Smart Indicator</string>\n  <string name=\"demo_title_distribute_evenly\">Distribute Evenly</string>\n  <string name=\"demo_title_always_in_center\">Always In Center</string>\n  <string name=\"demo_title_custom_tab_text\">Custom Tab Text</string>\n  <string name=\"demo_title_custom_tab_margin\">Custom Tab Margin (since 1.2~)</string>\n  <string name=\"demo_title_custom_tab_colors\">Custom Tab Colors</string>\n  <string name=\"demo_title_custom_tab_icons1\">Custom Tab Icons 1</string>\n  <string name=\"demo_title_custom_tab_icons2\">Custom Tab Icons 2 (since 1.2~)</string>\n  <string name=\"demo_title_custom_tab_icon_and_text\">Custom Tab Icon and Text</string>\n  <string name=\"demo_title_custom_tab_icon_and_notification_mark\">Custom Tab Icon and Notification Mark</string>\n  <string name=\"demo_title_indicator_trick1\">Indicator Thickness Trick 1</string>\n  <string name=\"demo_title_indicator_trick2\">Indicator Thickness Trick 2</string>\n  <string name=\"demo_title_right_to_left\">RTL support</string>\n  <string name=\"demo_title_advanced_medium\">Advanced: Like a Medium Tag (since 1.2~)</string>\n\n  <string name=\"demo_tab_1\">Cupcake</string>\n  <string name=\"demo_tab_2\">Donut</string>\n  <string name=\"demo_tab_3\">Eclair</string>\n  <string name=\"demo_tab_4\">Froyo</string>\n  <string name=\"demo_tab_5\">Gingerbread</string>\n  <string name=\"demo_tab_6\">Honeycomb</string>\n  <string name=\"demo_tab_7\">Ice Cream Sandwich</string>\n  <string name=\"demo_tab_8\">Jelly Bean</string>\n  <string name=\"demo_tab_9\">KitKat</string>\n  <string name=\"demo_tab_10\">Lollipop</string>\n\n  <string name=\"demo_tab_no_title\">No Title</string>\n  <string name=\"demo_tab_like_a_medium_top\">Top</string>\n  <string name=\"demo_tab_like_a_medium_latest\">Latest</string>\n\n</resources>\n"
  },
  {
    "path": "demo/src/main/res/values/styles.xml",
    "content": "<resources>\n\n  <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n    <item name=\"colorPrimary\">@color/primary</item>\n    <item name=\"colorPrimaryDark\">@color/primary_dark</item>\n    <item name=\"colorAccent\">@color/accent</item>\n  </style>\n\n  <style name=\"AppTheme.NoActionBar\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n    <item name=\"colorPrimary\">@color/primary</item>\n    <item name=\"colorPrimaryDark\">@color/primary_dark</item>\n    <item name=\"colorAccent\">@color/accent</item>\n  </style>\n\n</resources>\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Sun Nov 27 17:23:04 JST 2016\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.10.1-all.zip\n"
  },
  {
    "path": "gradle.properties",
    "content": "android.useAndroidX=true\n\nVERSION_NAME=2.0.0\nVERSION_CODE=18\nCOMPILE_SDK_VERSION=28\nANDROIDX_APPCOMPAT_VERSION=1.0.2\nANDROIDX_BASE_VERSION=1.0.0\n\nGROUP=com.ogaclejapan.smarttablayout\nARTIFACT_NAME=SmartTabLayout\nARTIFACT_DESCRIPTION=A custom ViewPager title strip which gives continuous feedback to the user when scrolling\nSITE_URL=https://github.com/ogaclejapan/SmartTabLayout\nISSUE_SYSTEM=github\nISSUE_URL=https://github.com/ogaclejapan/SmartTabLayout/issues\nSCM_URL=https://github.com/ogaclejapan/SmartTabLayout\nSCM_CONNECTION=scm:git@github.com:ogaclejapan/SmartTabLayout.git\nSCM_DEV_CONNECTION=scm:git@github.com:ogaclejapan/SmartTabLayout.git\nLICENCE_NAME=The Apache Software License, Version 2.0\nLICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt\nLICENCE_DIST=repo\nDEVELOPER_ID=ogaclejapan\nDEVELOPER_NAME=Masaki Ogata\nDEVELOPER_EMAIL=ogaclejapan@gmail.com\n"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# For Cygwin, ensure paths are in UNIX format before anything is touched.\nif $cygwin ; then\n    [ -n \"$JAVA_HOME\" ] && JAVA_HOME=`cygpath --unix \"$JAVA_HOME\"`\nfi\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >&-\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >&-\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windowz variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\ngoto execute\n\n:4NT_args\n@rem Get arguments from the 4NT Shell from JP Software\nset CMD_LINE_ARGS=%$\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "library/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "library/LICENSE",
    "content": "Copyright (C) 2015 ogaclejapan\nCopyright (C) 2013 The Android Open Source Project\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "library/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply plugin: 'com.github.ben-manes.versions'\napply plugin: 'com.github.hierynomus.license'\n\nandroid {\n  compileSdkVersion COMPILE_SDK_VERSION as int\n  resourcePrefix 'stl_'\n\n  defaultConfig {\n    minSdkVersion 14\n    targetSdkVersion COMPILE_SDK_VERSION as int\n    versionCode VERSION_CODE as int\n    versionName VERSION_NAME\n\n  }\n  buildTypes {\n    release {\n      minifyEnabled false\n      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n    }\n  }\n}\n\ndependencies {\n  implementation \"androidx.viewpager:viewpager:${ANDROIDX_BASE_VERSION}\"\n  implementation \"androidx.fragment:fragment:${ANDROIDX_BASE_VERSION}\"\n}\n\nlicense {\n\n  sourceSets {\n    main.java.srcDirs = android.sourceSets.main.java.srcDirs\n    main.resources.srcDirs = android.sourceSets.main.resources.srcDirs\n  }\n\n  excludes([\"**/*.xml\"])\n\n}\n\npkginfo.name = ARTIFACT_NAME\napply from: \"${project.rootDir}/publish.gradle\"\n"
  },
  {
    "path": "library/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/msk/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n"
  },
  {
    "path": "library/src/main/AndroidManifest.xml",
    "content": "<manifest package=\"com.ogaclejapan.smarttablayout\">\n\n</manifest>\n"
  },
  {
    "path": "library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabIndicationInterpolator.java",
    "content": "/**\n * Copyright (C) 2015 ogaclejapan\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.ogaclejapan.smarttablayout;\n\nimport android.view.animation.AccelerateInterpolator;\nimport android.view.animation.DecelerateInterpolator;\nimport android.view.animation.Interpolator;\n\npublic abstract class SmartTabIndicationInterpolator {\n\n  public static final SmartTabIndicationInterpolator SMART = new SmartIndicationInterpolator();\n  public static final SmartTabIndicationInterpolator LINEAR = new LinearIndicationInterpolator();\n\n  static final int ID_SMART = 0;\n  static final int ID_LINEAR = 1;\n\n  public static SmartTabIndicationInterpolator of(int id) {\n    switch (id) {\n      case ID_SMART:\n        return SMART;\n      case ID_LINEAR:\n        return LINEAR;\n      default:\n        throw new IllegalArgumentException(\"Unknown id: \" + id);\n    }\n  }\n\n  public abstract float getLeftEdge(float offset);\n\n  public abstract float getRightEdge(float offset);\n\n  public float getThickness(float offset) {\n    return 1f; //Always the same thickness by default\n  }\n\n  public static class SmartIndicationInterpolator extends SmartTabIndicationInterpolator {\n\n    private static final float DEFAULT_INDICATOR_INTERPOLATION_FACTOR = 3.0f;\n\n    private final Interpolator leftEdgeInterpolator;\n    private final Interpolator rightEdgeInterpolator;\n\n    public SmartIndicationInterpolator() {\n      this(DEFAULT_INDICATOR_INTERPOLATION_FACTOR);\n    }\n\n    public SmartIndicationInterpolator(float factor) {\n      leftEdgeInterpolator = new AccelerateInterpolator(factor);\n      rightEdgeInterpolator = new DecelerateInterpolator(factor);\n    }\n\n    @Override\n    public float getLeftEdge(float offset) {\n      return leftEdgeInterpolator.getInterpolation(offset);\n    }\n\n    @Override\n    public float getRightEdge(float offset) {\n      return rightEdgeInterpolator.getInterpolation(offset);\n    }\n\n    @Override\n    public float getThickness(float offset) {\n      return 1f / (1.0f - getLeftEdge(offset) + getRightEdge(offset));\n    }\n\n  }\n\n  public static class LinearIndicationInterpolator extends SmartTabIndicationInterpolator {\n\n    @Override\n    public float getLeftEdge(float offset) {\n      return offset;\n    }\n\n    @Override\n    public float getRightEdge(float offset) {\n      return offset;\n    }\n\n  }\n}\n"
  },
  {
    "path": "library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabLayout.java",
    "content": "/**\n * Copyright (C) 2015 ogaclejapan\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.ogaclejapan.smarttablayout;\n\nimport android.content.Context;\nimport android.content.res.ColorStateList;\nimport android.content.res.TypedArray;\nimport android.graphics.Typeface;\nimport android.os.Build;\nimport android.util.AttributeSet;\nimport android.util.DisplayMetrics;\nimport android.util.TypedValue;\nimport android.view.Gravity;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.HorizontalScrollView;\nimport android.widget.LinearLayout;\nimport android.widget.TextView;\n\nimport androidx.core.view.ViewCompat;\nimport androidx.viewpager.widget.PagerAdapter;\nimport androidx.viewpager.widget.ViewPager;\n\n/**\n * To be used with ViewPager to provide a tab indicator component which give constant feedback as\n * to\n * the user's scroll progress.\n * <p>\n * To use the component, simply add it to your view hierarchy. Then in your\n * {@link android.app.Activity} or {@link androidx.fragment.app.Fragment} call\n * {@link #setViewPager(ViewPager)} providing it the ViewPager this\n * layout\n * is being used for.\n * <p>\n * The colors can be customized in two ways. The first and simplest is to provide an array of\n * colors\n * via {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)}. The\n * alternative is via the {@link TabColorizer} interface which provides you complete control over\n * which color is used for any individual position.\n * <p>\n * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},\n * providing the layout ID of your custom layout.\n * <p>\n * Forked from Google Samples &gt; SlidingTabsBasic &gt;\n * <a href=\"https://developer.android.com/samples/SlidingTabsBasic/src/com.example.android.common/view/SlidingTabLayout.html\">SlidingTabLayout</a>\n */\npublic class SmartTabLayout extends HorizontalScrollView {\n\n  private static final boolean DEFAULT_DISTRIBUTE_EVENLY = false;\n  private static final int TITLE_OFFSET_DIPS = 24;\n  private static final int TITLE_OFFSET_AUTO_CENTER = -1;\n  private static final int TAB_VIEW_PADDING_DIPS = 16;\n  private static final boolean TAB_VIEW_TEXT_ALL_CAPS = true;\n  private static final int TAB_VIEW_TEXT_SIZE_SP = 12;\n  private static final int TAB_VIEW_TEXT_COLOR = 0xFC000000;\n  private static final int TAB_VIEW_TEXT_MIN_WIDTH = 0;\n  private static final boolean TAB_CLICKABLE = true;\n\n  protected final SmartTabStrip tabStrip;\n  private int titleOffset;\n  private int tabViewBackgroundResId;\n  private boolean tabViewTextAllCaps;\n  private ColorStateList tabViewTextColors;\n  private float tabViewTextSize;\n  private int tabViewTextHorizontalPadding;\n  private int tabViewTextMinWidth;\n  private ViewPager viewPager;\n  private ViewPager.OnPageChangeListener viewPagerPageChangeListener;\n  private OnScrollChangeListener onScrollChangeListener;\n  private TabProvider tabProvider;\n  private InternalTabClickListener internalTabClickListener;\n  private OnTabClickListener onTabClickListener;\n  private boolean distributeEvenly;\n\n  public SmartTabLayout(Context context) {\n    this(context, null);\n  }\n\n  public SmartTabLayout(Context context, AttributeSet attrs) {\n    this(context, attrs, 0);\n  }\n\n  public SmartTabLayout(Context context, AttributeSet attrs, int defStyle) {\n    super(context, attrs, defStyle);\n\n    // Disable the Scroll Bar\n    setHorizontalScrollBarEnabled(false);\n\n    final DisplayMetrics dm = getResources().getDisplayMetrics();\n    final float density = dm.density;\n\n    int tabBackgroundResId = NO_ID;\n    boolean textAllCaps = TAB_VIEW_TEXT_ALL_CAPS;\n    ColorStateList textColors;\n    float textSize = TypedValue.applyDimension(\n        TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP, dm);\n    int textHorizontalPadding = (int) (TAB_VIEW_PADDING_DIPS * density);\n    int textMinWidth = (int) (TAB_VIEW_TEXT_MIN_WIDTH * density);\n    boolean distributeEvenly = DEFAULT_DISTRIBUTE_EVENLY;\n    int customTabLayoutId = NO_ID;\n    int customTabTextViewId = NO_ID;\n    boolean clickable = TAB_CLICKABLE;\n    int titleOffset = (int) (TITLE_OFFSET_DIPS * density);\n\n    TypedArray a = context.obtainStyledAttributes(\n        attrs, R.styleable.stl_SmartTabLayout, defStyle, 0);\n    tabBackgroundResId = a.getResourceId(\n        R.styleable.stl_SmartTabLayout_stl_defaultTabBackground, tabBackgroundResId);\n    textAllCaps = a.getBoolean(\n        R.styleable.stl_SmartTabLayout_stl_defaultTabTextAllCaps, textAllCaps);\n    textColors = a.getColorStateList(\n        R.styleable.stl_SmartTabLayout_stl_defaultTabTextColor);\n    textSize = a.getDimension(\n        R.styleable.stl_SmartTabLayout_stl_defaultTabTextSize, textSize);\n    textHorizontalPadding = a.getDimensionPixelSize(\n        R.styleable.stl_SmartTabLayout_stl_defaultTabTextHorizontalPadding, textHorizontalPadding);\n    textMinWidth = a.getDimensionPixelSize(\n        R.styleable.stl_SmartTabLayout_stl_defaultTabTextMinWidth, textMinWidth);\n    customTabLayoutId = a.getResourceId(\n        R.styleable.stl_SmartTabLayout_stl_customTabTextLayoutId, customTabLayoutId);\n    customTabTextViewId = a.getResourceId(\n        R.styleable.stl_SmartTabLayout_stl_customTabTextViewId, customTabTextViewId);\n    distributeEvenly = a.getBoolean(\n        R.styleable.stl_SmartTabLayout_stl_distributeEvenly, distributeEvenly);\n    clickable = a.getBoolean(\n        R.styleable.stl_SmartTabLayout_stl_clickable, clickable);\n    titleOffset = a.getLayoutDimension(\n        R.styleable.stl_SmartTabLayout_stl_titleOffset, titleOffset);\n    a.recycle();\n\n    this.titleOffset = titleOffset;\n    this.tabViewBackgroundResId = tabBackgroundResId;\n    this.tabViewTextAllCaps = textAllCaps;\n    this.tabViewTextColors = (textColors != null)\n        ? textColors\n        : ColorStateList.valueOf(TAB_VIEW_TEXT_COLOR);\n    this.tabViewTextSize = textSize;\n    this.tabViewTextHorizontalPadding = textHorizontalPadding;\n    this.tabViewTextMinWidth = textMinWidth;\n    this.internalTabClickListener = clickable ? new InternalTabClickListener() : null;\n    this.distributeEvenly = distributeEvenly;\n\n    if (customTabLayoutId != NO_ID) {\n      setCustomTabView(customTabLayoutId, customTabTextViewId);\n    }\n\n    this.tabStrip = new SmartTabStrip(context, attrs);\n\n    if (distributeEvenly && tabStrip.isIndicatorAlwaysInCenter()) {\n      throw new UnsupportedOperationException(\n          \"'distributeEvenly' and 'indicatorAlwaysInCenter' both use does not support\");\n    }\n\n    // Make sure that the Tab Strips fills this View\n    setFillViewport(!tabStrip.isIndicatorAlwaysInCenter());\n\n    addView(tabStrip, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);\n\n  }\n\n  @Override\n  protected void onScrollChanged(int l, int t, int oldl, int oldt) {\n    super.onScrollChanged(l, t, oldl, oldt);\n    if (onScrollChangeListener != null) {\n      onScrollChangeListener.onScrollChanged(l, oldl);\n    }\n  }\n\n  @Override\n  protected void onSizeChanged(int w, int h, int oldw, int oldh) {\n    super.onSizeChanged(w, h, oldw, oldh);\n    if (tabStrip.isIndicatorAlwaysInCenter() && tabStrip.getChildCount() > 0) {\n      View firstTab = tabStrip.getChildAt(0);\n      View lastTab = tabStrip.getChildAt(tabStrip.getChildCount() - 1);\n      int start = (w - Utils.getMeasuredWidth(firstTab)) / 2 - Utils.getMarginStart(firstTab);\n      int end = (w - Utils.getMeasuredWidth(lastTab)) / 2 - Utils.getMarginEnd(lastTab);\n      tabStrip.setMinimumWidth(tabStrip.getMeasuredWidth());\n      ViewCompat.setPaddingRelative(this, start, getPaddingTop(), end, getPaddingBottom());\n      setClipToPadding(false);\n    }\n  }\n\n  @Override\n  protected void onLayout(boolean changed, int l, int t, int r, int b) {\n    super.onLayout(changed, l, t, r, b);\n    // Ensure first scroll\n    if (changed && viewPager != null) {\n      scrollToTab(viewPager.getCurrentItem(), 0);\n    }\n  }\n\n  /**\n   * Set the behavior of the Indicator scrolling feedback.\n   *\n   * @param interpolator {@link com.ogaclejapan.smarttablayout.SmartTabIndicationInterpolator}\n   */\n  public void setIndicationInterpolator(SmartTabIndicationInterpolator interpolator) {\n    tabStrip.setIndicationInterpolator(interpolator);\n  }\n\n  /**\n   * Set the custom {@link TabColorizer} to be used.\n   *\n   * If you only require simple customisation then you can use\n   * {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)} to achieve\n   * similar effects.\n   */\n  public void setCustomTabColorizer(TabColorizer tabColorizer) {\n    tabStrip.setCustomTabColorizer(tabColorizer);\n  }\n\n  /**\n   * Set the color used for styling the tab text. This will need to be called prior to calling\n   * {@link #setViewPager(ViewPager)} otherwise it will not get set\n   *\n   * @param color to use for tab text\n   */\n  public void setDefaultTabTextColor(int color) {\n    tabViewTextColors = ColorStateList.valueOf(color);\n  }\n\n  /**\n   * Sets the colors used for styling the tab text. This will need to be called prior to calling\n   * {@link #setViewPager(ViewPager)} otherwise it will not get set\n   *\n   * @param colors ColorStateList to use for tab text\n   */\n  public void setDefaultTabTextColor(ColorStateList colors) {\n    tabViewTextColors = colors;\n  }\n\n  /**\n   * Set the same weight for tab\n   */\n  public void setDistributeEvenly(boolean distributeEvenly) {\n    this.distributeEvenly = distributeEvenly;\n  }\n\n  /**\n   * Sets the colors to be used for indicating the selected tab. These colors are treated as a\n   * circular array. Providing one color will mean that all tabs are indicated with the same color.\n   */\n  public void setSelectedIndicatorColors(int... colors) {\n    tabStrip.setSelectedIndicatorColors(colors);\n  }\n\n  /**\n   * Sets the colors to be used for tab dividers. These colors are treated as a circular array.\n   * Providing one color will mean that all tabs are indicated with the same color.\n   */\n  public void setDividerColors(int... colors) {\n    tabStrip.setDividerColors(colors);\n  }\n\n  /**\n   * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SmartTabLayout} you are\n   * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so\n   * that the layout can update it's scroll position correctly.\n   *\n   * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)\n   */\n  public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {\n    viewPagerPageChangeListener = listener;\n  }\n\n  /**\n   * Set {@link OnScrollChangeListener} for obtaining values of scrolling.\n   *\n   * @param listener the {@link OnScrollChangeListener} to set\n   */\n  public void setOnScrollChangeListener(OnScrollChangeListener listener) {\n    onScrollChangeListener = listener;\n  }\n\n  /**\n   * Set {@link OnTabClickListener} for obtaining click event.\n   *\n   * @param listener the {@link OnTabClickListener} to set\n   */\n  public void setOnTabClickListener(OnTabClickListener listener) {\n    onTabClickListener = listener;\n  }\n\n  /**\n   * Set the custom layout to be inflated for the tab views.\n   *\n   * @param layoutResId Layout id to be inflated\n   * @param textViewId id of the {@link android.widget.TextView} in the inflated view\n   */\n  public void setCustomTabView(int layoutResId, int textViewId) {\n    tabProvider = new SimpleTabProvider(getContext(), layoutResId, textViewId);\n  }\n\n  /**\n   * Set the custom layout to be inflated for the tab views.\n   *\n   * @param provider {@link TabProvider}\n   */\n  public void setCustomTabView(TabProvider provider) {\n    tabProvider = provider;\n  }\n\n  /**\n   * Sets the associated view pager. Note that the assumption here is that the pager content\n   * (number of tabs and tab titles) does not change after this call has been made.\n   */\n  public void setViewPager(ViewPager viewPager) {\n    tabStrip.removeAllViews();\n\n    this.viewPager = viewPager;\n    if (viewPager != null && viewPager.getAdapter() != null) {\n      viewPager.addOnPageChangeListener(new InternalViewPagerListener());\n      populateTabStrip();\n    }\n  }\n\n  /**\n   * Returns the view at the specified position in the tabs.\n   *\n   * @param position the position at which to get the view from\n   * @return the view at the specified position or null if the position does not exist within the\n   * tabs\n   */\n  public View getTabAt(int position) {\n    return tabStrip.getChildAt(position);\n  }\n\n  /**\n   * Create a default view to be used for tabs. This is called if a custom tab view is not set via\n   * {@link #setCustomTabView(int, int)}.\n   */\n  protected TextView createDefaultTabView(CharSequence title) {\n    TextView textView = new TextView(getContext());\n    textView.setGravity(Gravity.CENTER);\n    textView.setText(title);\n    textView.setTextColor(tabViewTextColors);\n    textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabViewTextSize);\n    textView.setTypeface(Typeface.DEFAULT_BOLD);\n    textView.setLayoutParams(new LinearLayout.LayoutParams(\n        LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));\n\n    if (tabViewBackgroundResId != NO_ID) {\n      textView.setBackgroundResource(tabViewBackgroundResId);\n    } else {\n      // If we're running on Honeycomb or newer, then we can use the Theme's\n      // selectableItemBackground to ensure that the View has a pressed state\n      TypedValue outValue = new TypedValue();\n      getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,\n          outValue, true);\n      textView.setBackgroundResource(outValue.resourceId);\n    }\n\n    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {\n      // If we're running on ICS or newer, enable all-caps to match the Action Bar tab style\n      textView.setAllCaps(tabViewTextAllCaps);\n    }\n\n    textView.setPadding(\n        tabViewTextHorizontalPadding, 0,\n        tabViewTextHorizontalPadding, 0);\n\n    if (tabViewTextMinWidth > 0) {\n      textView.setMinWidth(tabViewTextMinWidth);\n    }\n\n    return textView;\n  }\n\n  private void populateTabStrip() {\n    final PagerAdapter adapter = viewPager.getAdapter();\n\n    for (int i = 0; i < adapter.getCount(); i++) {\n\n      final View tabView = (tabProvider == null)\n          ? createDefaultTabView(adapter.getPageTitle(i))\n          : tabProvider.createTabView(tabStrip, i, adapter);\n\n      if (tabView == null) {\n        throw new IllegalStateException(\"tabView is null.\");\n      }\n\n      if (distributeEvenly) {\n        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams();\n        lp.width = 0;\n        lp.weight = 1;\n      }\n\n      if (internalTabClickListener != null) {\n        tabView.setOnClickListener(internalTabClickListener);\n      }\n\n      tabStrip.addView(tabView);\n\n      if (i == viewPager.getCurrentItem()) {\n        tabView.setSelected(true);\n      }\n\n    }\n  }\n\n  private void scrollToTab(int tabIndex, float positionOffset) {\n    final int tabStripChildCount = tabStrip.getChildCount();\n    if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {\n      return;\n    }\n\n    final boolean isLayoutRtl = Utils.isLayoutRtl(this);\n    View selectedTab = tabStrip.getChildAt(tabIndex);\n    int widthPlusMargin = Utils.getWidth(selectedTab) + Utils.getMarginHorizontally(selectedTab);\n    int extraOffset = (int) (positionOffset * widthPlusMargin);\n\n    if (tabStrip.isIndicatorAlwaysInCenter()) {\n\n      if (0f < positionOffset && positionOffset < 1f) {\n        View nextTab = tabStrip.getChildAt(tabIndex + 1);\n        int selectHalfWidth = Utils.getWidth(selectedTab) / 2 + Utils.getMarginEnd(selectedTab);\n        int nextHalfWidth = Utils.getWidth(nextTab) / 2 + Utils.getMarginStart(nextTab);\n        extraOffset = Math.round(positionOffset * (selectHalfWidth + nextHalfWidth));\n      }\n\n      View firstTab = tabStrip.getChildAt(0);\n      int x;\n      if (isLayoutRtl) {\n        int first = Utils.getWidth(firstTab) + Utils.getMarginEnd(firstTab);\n        int selected = Utils.getWidth(selectedTab) + Utils.getMarginEnd(selectedTab);\n        x = Utils.getEnd(selectedTab) - Utils.getMarginEnd(selectedTab) - extraOffset;\n        x -= (first - selected) / 2;\n      } else {\n        int first = Utils.getWidth(firstTab) + Utils.getMarginStart(firstTab);\n        int selected = Utils.getWidth(selectedTab) + Utils.getMarginStart(selectedTab);\n        x = Utils.getStart(selectedTab) - Utils.getMarginStart(selectedTab) + extraOffset;\n        x -= (first - selected) / 2;\n      }\n\n      scrollTo(x, 0);\n      return;\n\n    }\n\n    int x;\n    if (titleOffset == TITLE_OFFSET_AUTO_CENTER) {\n\n      if (0f < positionOffset && positionOffset < 1f) {\n        View nextTab = tabStrip.getChildAt(tabIndex + 1);\n        int selectHalfWidth = Utils.getWidth(selectedTab) / 2 + Utils.getMarginEnd(selectedTab);\n        int nextHalfWidth = Utils.getWidth(nextTab) / 2 + Utils.getMarginStart(nextTab);\n        extraOffset = Math.round(positionOffset * (selectHalfWidth + nextHalfWidth));\n      }\n\n      if (isLayoutRtl) {\n        x = -Utils.getWidthWithMargin(selectedTab) / 2 + getWidth() / 2;\n        x -= Utils.getPaddingStart(this);\n      } else {\n        x = Utils.getWidthWithMargin(selectedTab) / 2 - getWidth() / 2;\n        x += Utils.getPaddingStart(this);\n      }\n\n    } else {\n\n      if (isLayoutRtl) {\n        x = (tabIndex > 0 || positionOffset > 0) ? titleOffset : 0;\n      } else {\n        x = (tabIndex > 0 || positionOffset > 0) ? -titleOffset : 0;\n      }\n\n    }\n\n    int start = Utils.getStart(selectedTab);\n    int startMargin = Utils.getMarginStart(selectedTab);\n    if (isLayoutRtl) {\n      x += start + startMargin - extraOffset - getWidth() + Utils.getPaddingHorizontally(this);\n    } else {\n      x += start - startMargin + extraOffset;\n    }\n\n    scrollTo(x, 0);\n\n  }\n\n  /**\n   * Allows complete control over the colors drawn in the tab layout. Set with\n   * {@link #setCustomTabColorizer(TabColorizer)}.\n   */\n  public interface TabColorizer {\n\n    /**\n     * @return return the color of the indicator used when {@code position} is selected.\n     */\n    int getIndicatorColor(int position);\n\n    /**\n     * @return return the color of the divider drawn to the right of {@code position}.\n     */\n    int getDividerColor(int position);\n\n  }\n\n  /**\n   * Interface definition for a callback to be invoked when the scroll position of a view changes.\n   */\n  public interface OnScrollChangeListener {\n\n    /**\n     * Called when the scroll position of a view changes.\n     *\n     * @param scrollX Current horizontal scroll origin.\n     * @param oldScrollX Previous horizontal scroll origin.\n     */\n    void onScrollChanged(int scrollX, int oldScrollX);\n  }\n\n  /**\n   * Interface definition for a callback to be invoked when a tab is clicked.\n   */\n  public interface OnTabClickListener {\n\n    /**\n     * Called when a tab is clicked.\n     *\n     * @param position tab's position\n     */\n    void onTabClicked(int position);\n  }\n\n  /**\n   * Create the custom tabs in the tab layout. Set with\n   * {@link #setCustomTabView(com.ogaclejapan.smarttablayout.SmartTabLayout.TabProvider)}\n   */\n  public interface TabProvider {\n\n    /**\n     * @return Return the View of {@code position} for the Tabs\n     */\n    View createTabView(ViewGroup container, int position, PagerAdapter adapter);\n\n  }\n\n  private static class SimpleTabProvider implements TabProvider {\n\n    private final LayoutInflater inflater;\n    private final int tabViewLayoutId;\n    private final int tabViewTextViewId;\n\n    private SimpleTabProvider(Context context, int layoutResId, int textViewId) {\n      inflater = LayoutInflater.from(context);\n      tabViewLayoutId = layoutResId;\n      tabViewTextViewId = textViewId;\n    }\n\n    @Override\n    public View createTabView(ViewGroup container, int position, PagerAdapter adapter) {\n      View tabView = null;\n      TextView tabTitleView = null;\n\n      if (tabViewLayoutId != NO_ID) {\n        tabView = inflater.inflate(tabViewLayoutId, container, false);\n      }\n\n      if (tabViewTextViewId != NO_ID && tabView != null) {\n        tabTitleView = (TextView) tabView.findViewById(tabViewTextViewId);\n      }\n\n      if (tabTitleView == null && TextView.class.isInstance(tabView)) {\n        tabTitleView = (TextView) tabView;\n      }\n\n      if (tabTitleView != null) {\n        tabTitleView.setText(adapter.getPageTitle(position));\n      }\n\n      return tabView;\n    }\n\n  }\n\n  private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {\n\n    private int scrollState;\n\n    @Override\n    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {\n      int tabStripChildCount = tabStrip.getChildCount();\n      if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {\n        return;\n      }\n\n      tabStrip.onViewPagerPageChanged(position, positionOffset);\n\n      scrollToTab(position, positionOffset);\n\n      if (viewPagerPageChangeListener != null) {\n        viewPagerPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);\n      }\n    }\n\n    @Override\n    public void onPageScrollStateChanged(int state) {\n      scrollState = state;\n\n      if (viewPagerPageChangeListener != null) {\n        viewPagerPageChangeListener.onPageScrollStateChanged(state);\n      }\n    }\n\n    @Override\n    public void onPageSelected(int position) {\n      if (scrollState == ViewPager.SCROLL_STATE_IDLE) {\n        tabStrip.onViewPagerPageChanged(position, 0f);\n        scrollToTab(position, 0);\n      }\n\n      for (int i = 0, size = tabStrip.getChildCount(); i < size; i++) {\n        tabStrip.getChildAt(i).setSelected(position == i);\n      }\n\n      if (viewPagerPageChangeListener != null) {\n        viewPagerPageChangeListener.onPageSelected(position);\n      }\n    }\n\n  }\n\n  private class InternalTabClickListener implements OnClickListener {\n    @Override\n    public void onClick(View v) {\n      for (int i = 0; i < tabStrip.getChildCount(); i++) {\n        if (v == tabStrip.getChildAt(i)) {\n          if (onTabClickListener != null) {\n            onTabClickListener.onTabClicked(i);\n          }\n          viewPager.setCurrentItem(i);\n          return;\n        }\n      }\n    }\n  }\n\n}\n"
  },
  {
    "path": "library/src/main/java/com/ogaclejapan/smarttablayout/SmartTabStrip.java",
    "content": "/**\n * Copyright (C) 2015 ogaclejapan\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.ogaclejapan.smarttablayout;\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimport android.graphics.RectF;\nimport android.util.AttributeSet;\nimport android.util.TypedValue;\nimport android.view.View;\nimport android.widget.LinearLayout;\n\n/**\n * <p>\n * Forked from Google Samples &gt; SlidingTabsBasic &gt;\n * <a href=\"https://developer.android.com/samples/SlidingTabsBasic/src/com.example.android.common/view/SlidingTabLayout.html\">SlidingTabStrip</a>\n */\nclass SmartTabStrip extends LinearLayout {\n\n  private static final int GRAVITY_BOTTOM = 0;\n  private static final int GRAVITY_TOP = 1;\n  private static final int GRAVITY_CENTER = 2;\n\n  private static final int AUTO_WIDTH = -1;\n\n  private static final int DEFAULT_TOP_BORDER_THICKNESS_DIPS = 0;\n  private static final byte DEFAULT_TOP_BORDER_COLOR_ALPHA = 0x26;\n  private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 2;\n  private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;\n  private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 8;\n  private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5;\n  private static final float DEFAULT_INDICATOR_CORNER_RADIUS = 0f;\n  private static final int DEFAULT_DIVIDER_THICKNESS_DIPS = 1;\n  private static final byte DEFAULT_DIVIDER_COLOR_ALPHA = 0x20;\n  private static final float DEFAULT_DIVIDER_HEIGHT = 0.5f;\n  private static final boolean DEFAULT_INDICATOR_IN_CENTER = false;\n  private static final boolean DEFAULT_INDICATOR_IN_FRONT = false;\n  private static final boolean DEFAULT_INDICATOR_WITHOUT_PADDING = false;\n  private static final int DEFAULT_INDICATOR_GRAVITY = GRAVITY_BOTTOM;\n  private static final boolean DEFAULT_DRAW_DECORATION_AFTER_TAB = false;\n\n  private final int topBorderThickness;\n  private final int topBorderColor;\n  private final int bottomBorderThickness;\n  private final int bottomBorderColor;\n  private final Paint borderPaint;\n  private final RectF indicatorRectF = new RectF();\n  private final boolean indicatorWithoutPadding;\n  private final boolean indicatorAlwaysInCenter;\n  private final boolean indicatorInFront;\n  private final int indicatorThickness;\n  private final int indicatorWidth;\n  private final int indicatorGravity;\n  private final float indicatorCornerRadius;\n  private final Paint indicatorPaint;\n  private final int dividerThickness;\n  private final Paint dividerPaint;\n  private final float dividerHeight;\n  private final SimpleTabColorizer defaultTabColorizer;\n  private final boolean drawDecorationAfterTab;\n\n  private int lastPosition;\n  private int selectedPosition;\n  private float selectionOffset;\n  private SmartTabIndicationInterpolator indicationInterpolator;\n  private SmartTabLayout.TabColorizer customTabColorizer;\n\n  SmartTabStrip(Context context, AttributeSet attrs) {\n    super(context);\n    setWillNotDraw(false);\n\n    final float density = getResources().getDisplayMetrics().density;\n\n    TypedValue outValue = new TypedValue();\n    context.getTheme().resolveAttribute(android.R.attr.colorForeground, outValue, true);\n    final int themeForegroundColor = outValue.data;\n\n    boolean indicatorWithoutPadding = DEFAULT_INDICATOR_WITHOUT_PADDING;\n    boolean indicatorInFront = DEFAULT_INDICATOR_IN_FRONT;\n    boolean indicatorAlwaysInCenter = DEFAULT_INDICATOR_IN_CENTER;\n    int indicationInterpolatorId = SmartTabIndicationInterpolator.ID_SMART;\n    int indicatorGravity = DEFAULT_INDICATOR_GRAVITY;\n    int indicatorColor = DEFAULT_SELECTED_INDICATOR_COLOR;\n    int indicatorColorsId = NO_ID;\n    int indicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);\n    int indicatorWidth = AUTO_WIDTH;\n    float indicatorCornerRadius = DEFAULT_INDICATOR_CORNER_RADIUS * density;\n    int overlineColor = setColorAlpha(themeForegroundColor, DEFAULT_TOP_BORDER_COLOR_ALPHA);\n    int overlineThickness = (int) (DEFAULT_TOP_BORDER_THICKNESS_DIPS * density);\n    int underlineColor = setColorAlpha(themeForegroundColor, DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);\n    int underlineThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);\n    int dividerColor = setColorAlpha(themeForegroundColor, DEFAULT_DIVIDER_COLOR_ALPHA);\n    int dividerColorsId = NO_ID;\n    int dividerThickness = (int) (DEFAULT_DIVIDER_THICKNESS_DIPS * density);\n    boolean drawDecorationAfterTab = DEFAULT_DRAW_DECORATION_AFTER_TAB;\n\n    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.stl_SmartTabLayout);\n    indicatorAlwaysInCenter = a.getBoolean(\n        R.styleable.stl_SmartTabLayout_stl_indicatorAlwaysInCenter, indicatorAlwaysInCenter);\n    indicatorWithoutPadding = a.getBoolean(\n        R.styleable.stl_SmartTabLayout_stl_indicatorWithoutPadding, indicatorWithoutPadding);\n    indicatorInFront = a.getBoolean(\n        R.styleable.stl_SmartTabLayout_stl_indicatorInFront, indicatorInFront);\n    indicationInterpolatorId = a.getInt(\n        R.styleable.stl_SmartTabLayout_stl_indicatorInterpolation, indicationInterpolatorId);\n    indicatorGravity = a.getInt(\n        R.styleable.stl_SmartTabLayout_stl_indicatorGravity, indicatorGravity);\n    indicatorColor = a.getColor(\n        R.styleable.stl_SmartTabLayout_stl_indicatorColor, indicatorColor);\n    indicatorColorsId = a.getResourceId(\n        R.styleable.stl_SmartTabLayout_stl_indicatorColors, indicatorColorsId);\n    indicatorThickness = a.getDimensionPixelSize(\n        R.styleable.stl_SmartTabLayout_stl_indicatorThickness, indicatorThickness);\n    indicatorWidth = a.getLayoutDimension(\n        R.styleable.stl_SmartTabLayout_stl_indicatorWidth, indicatorWidth);\n    indicatorCornerRadius = a.getDimension(\n        R.styleable.stl_SmartTabLayout_stl_indicatorCornerRadius, indicatorCornerRadius);\n    overlineColor = a.getColor(\n        R.styleable.stl_SmartTabLayout_stl_overlineColor, overlineColor);\n    overlineThickness = a.getDimensionPixelSize(\n        R.styleable.stl_SmartTabLayout_stl_overlineThickness, overlineThickness);\n    underlineColor = a.getColor(\n        R.styleable.stl_SmartTabLayout_stl_underlineColor, underlineColor);\n    underlineThickness = a.getDimensionPixelSize(\n        R.styleable.stl_SmartTabLayout_stl_underlineThickness, underlineThickness);\n    dividerColor = a.getColor(\n        R.styleable.stl_SmartTabLayout_stl_dividerColor, dividerColor);\n    dividerColorsId = a.getResourceId(\n        R.styleable.stl_SmartTabLayout_stl_dividerColors, dividerColorsId);\n    dividerThickness = a.getDimensionPixelSize(\n        R.styleable.stl_SmartTabLayout_stl_dividerThickness, dividerThickness);\n    drawDecorationAfterTab = a.getBoolean(\n        R.styleable.stl_SmartTabLayout_stl_drawDecorationAfterTab, drawDecorationAfterTab);\n    a.recycle();\n\n    final int[] indicatorColors = (indicatorColorsId == NO_ID)\n        ? new int[] { indicatorColor }\n        : getResources().getIntArray(indicatorColorsId);\n\n    final int[] dividerColors = (dividerColorsId == NO_ID)\n        ? new int[] { dividerColor }\n        : getResources().getIntArray(dividerColorsId);\n\n    this.defaultTabColorizer = new SimpleTabColorizer();\n    this.defaultTabColorizer.setIndicatorColors(indicatorColors);\n    this.defaultTabColorizer.setDividerColors(dividerColors);\n\n    this.topBorderThickness = overlineThickness;\n    this.topBorderColor = overlineColor;\n    this.bottomBorderThickness = underlineThickness;\n    this.bottomBorderColor = underlineColor;\n    this.borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);\n\n    this.indicatorAlwaysInCenter = indicatorAlwaysInCenter;\n    this.indicatorWithoutPadding = indicatorWithoutPadding;\n    this.indicatorInFront = indicatorInFront;\n    this.indicatorThickness = indicatorThickness;\n    this.indicatorWidth = indicatorWidth;\n    this.indicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);\n    this.indicatorCornerRadius = indicatorCornerRadius;\n    this.indicatorGravity = indicatorGravity;\n\n    this.dividerHeight = DEFAULT_DIVIDER_HEIGHT;\n    this.dividerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);\n    this.dividerPaint.setStrokeWidth(dividerThickness);\n    this.dividerThickness = dividerThickness;\n\n    this.drawDecorationAfterTab = drawDecorationAfterTab;\n\n    this.indicationInterpolator = SmartTabIndicationInterpolator.of(indicationInterpolatorId);\n  }\n\n  /**\n   * Set the alpha value of the {@code color} to be the given {@code alpha} value.\n   */\n  private static int setColorAlpha(int color, byte alpha) {\n    return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));\n  }\n\n  /**\n   * Blend {@code color1} and {@code color2} using the given ratio.\n   *\n   * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,\n   * 0.0 will return {@code color2}.\n   */\n  private static int blendColors(int color1, int color2, float ratio) {\n    final float inverseRation = 1f - ratio;\n    float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);\n    float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);\n    float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);\n    return Color.rgb((int) r, (int) g, (int) b);\n  }\n\n  void setIndicationInterpolator(SmartTabIndicationInterpolator interpolator) {\n    indicationInterpolator = interpolator;\n    invalidate();\n  }\n\n  void setCustomTabColorizer(SmartTabLayout.TabColorizer customTabColorizer) {\n    this.customTabColorizer = customTabColorizer;\n    invalidate();\n  }\n\n  void setSelectedIndicatorColors(int... colors) {\n    // Make sure that the custom colorizer is removed\n    customTabColorizer = null;\n    defaultTabColorizer.setIndicatorColors(colors);\n    invalidate();\n  }\n\n  void setDividerColors(int... colors) {\n    // Make sure that the custom colorizer is removed\n    customTabColorizer = null;\n    defaultTabColorizer.setDividerColors(colors);\n    invalidate();\n  }\n\n  void onViewPagerPageChanged(int position, float positionOffset) {\n    selectedPosition = position;\n    selectionOffset = positionOffset;\n    if (positionOffset == 0f && lastPosition != selectedPosition) {\n      lastPosition = selectedPosition;\n    }\n    invalidate();\n  }\n\n  boolean isIndicatorAlwaysInCenter() {\n    return indicatorAlwaysInCenter;\n  }\n\n  SmartTabLayout.TabColorizer getTabColorizer() {\n    return (customTabColorizer != null) ? customTabColorizer : defaultTabColorizer;\n  }\n\n  @Override\n  protected void onDraw(Canvas canvas) {\n    if (!drawDecorationAfterTab) {\n      drawDecoration(canvas);\n    }\n  }\n\n  @Override\n  protected void dispatchDraw(Canvas canvas) {\n    super.dispatchDraw(canvas);\n    if (drawDecorationAfterTab) {\n      drawDecoration(canvas);\n    }\n  }\n\n  private void drawDecoration(Canvas canvas) {\n    final int height = getHeight();\n    final int width = getWidth();\n    final int tabCount = getChildCount();\n    final SmartTabLayout.TabColorizer tabColorizer = getTabColorizer();\n    final boolean isLayoutRtl = Utils.isLayoutRtl(this);\n\n    if (indicatorInFront) {\n      drawOverline(canvas, 0, width);\n      drawUnderline(canvas, 0, width, height);\n    }\n\n    // Thick colored underline below the current selection\n    if (tabCount > 0) {\n      View selectedTab = getChildAt(selectedPosition);\n      int selectedStart = Utils.getStart(selectedTab, indicatorWithoutPadding);\n      int selectedEnd = Utils.getEnd(selectedTab, indicatorWithoutPadding);\n      int left;\n      int right;\n      if (isLayoutRtl) {\n        left = selectedEnd;\n        right = selectedStart;\n      } else {\n        left = selectedStart;\n        right = selectedEnd;\n      }\n\n      int color = tabColorizer.getIndicatorColor(selectedPosition);\n      float thickness = indicatorThickness;\n\n      if (selectionOffset > 0f && selectedPosition < (getChildCount() - 1)) {\n        int nextColor = tabColorizer.getIndicatorColor(selectedPosition + 1);\n        if (color != nextColor) {\n          color = blendColors(nextColor, color, selectionOffset);\n        }\n\n        // Draw the selection partway between the tabs\n        float startOffset = indicationInterpolator.getLeftEdge(selectionOffset);\n        float endOffset = indicationInterpolator.getRightEdge(selectionOffset);\n        float thicknessOffset = indicationInterpolator.getThickness(selectionOffset);\n\n        View nextTab = getChildAt(selectedPosition + 1);\n        int nextStart = Utils.getStart(nextTab, indicatorWithoutPadding);\n        int nextEnd = Utils.getEnd(nextTab, indicatorWithoutPadding);\n        if (isLayoutRtl) {\n          left = (int) (endOffset * nextEnd + (1.0f - endOffset) * left);\n          right = (int) (startOffset * nextStart + (1.0f - startOffset) * right);\n        } else {\n          left = (int) (startOffset * nextStart + (1.0f - startOffset) * left);\n          right = (int) (endOffset * nextEnd + (1.0f - endOffset) * right);\n        }\n        thickness = thickness * thicknessOffset;\n      }\n\n      drawIndicator(canvas, left, right, height, thickness, color);\n\n    }\n\n    if (!indicatorInFront) {\n      drawOverline(canvas, 0, width);\n      drawUnderline(canvas, 0, getWidth(), height);\n    }\n\n    // Vertical separators between the titles\n    drawSeparator(canvas, height, tabCount);\n\n  }\n\n  private void drawSeparator(Canvas canvas, int height, int tabCount) {\n    if (dividerThickness <= 0) {\n      return;\n    }\n\n    final int dividerHeightPx = (int) (Math.min(Math.max(0f, dividerHeight), 1f) * height);\n    final SmartTabLayout.TabColorizer tabColorizer = getTabColorizer();\n\n    // Vertical separators between the titles\n    final int separatorTop = (height - dividerHeightPx) / 2;\n    final int separatorBottom = separatorTop + dividerHeightPx;\n\n    final boolean isLayoutRtl = Utils.isLayoutRtl(this);\n    for (int i = 0; i < tabCount - 1; i++) {\n      View child = getChildAt(i);\n      int end = Utils.getEnd(child);\n      int endMargin = Utils.getMarginEnd(child);\n      int separatorX = isLayoutRtl ? end - endMargin : end + endMargin;\n      dividerPaint.setColor(tabColorizer.getDividerColor(i));\n      canvas.drawLine(separatorX, separatorTop, separatorX, separatorBottom, dividerPaint);\n    }\n  }\n\n  private void drawIndicator(Canvas canvas, int left, int right, int height, float thickness,\n      int color) {\n    if (indicatorThickness <= 0 || indicatorWidth == 0) {\n      return;\n    }\n\n    float center;\n    float top;\n    float bottom;\n\n    switch (indicatorGravity) {\n      case GRAVITY_TOP:\n        center = indicatorThickness / 2f;\n        top = center - (thickness / 2f);\n        bottom = center + (thickness / 2f);\n        break;\n      case GRAVITY_CENTER:\n        center = height / 2f;\n        top = center - (thickness / 2f);\n        bottom = center + (thickness / 2f);\n        break;\n      case GRAVITY_BOTTOM:\n      default:\n        center = height - (indicatorThickness / 2f);\n        top = center - (thickness / 2f);\n        bottom = center + (thickness / 2f);\n    }\n\n    indicatorPaint.setColor(color);\n    if (indicatorWidth == AUTO_WIDTH) {\n      indicatorRectF.set(left, top, right, bottom);\n    } else {\n      float padding = (Math.abs(left - right) - indicatorWidth) / 2f;\n      indicatorRectF.set(left + padding, top, right - padding, bottom);\n    }\n\n    if (indicatorCornerRadius > 0f) {\n      canvas.drawRoundRect(\n          indicatorRectF, indicatorCornerRadius,\n          indicatorCornerRadius, indicatorPaint);\n    } else {\n      canvas.drawRect(indicatorRectF, indicatorPaint);\n    }\n  }\n\n  private void drawOverline(Canvas canvas, int left, int right) {\n    if (topBorderThickness <= 0) {\n      return;\n    }\n    // Thin overline along the entire top edge\n    borderPaint.setColor(topBorderColor);\n    canvas.drawRect(left, 0, right, topBorderThickness, borderPaint);\n  }\n\n  private void drawUnderline(Canvas canvas, int left, int right, int height) {\n    if (bottomBorderThickness <= 0) {\n      return;\n    }\n    // Thin underline along the entire bottom edge\n    borderPaint.setColor(bottomBorderColor);\n    canvas.drawRect(left, height - bottomBorderThickness, right, height, borderPaint);\n  }\n\n  private static class SimpleTabColorizer implements SmartTabLayout.TabColorizer {\n\n    private int[] indicatorColors;\n    private int[] dividerColors;\n\n    @Override\n    public final int getIndicatorColor(int position) {\n      return indicatorColors[position % indicatorColors.length];\n    }\n\n    @Override\n    public final int getDividerColor(int position) {\n      return dividerColors[position % dividerColors.length];\n    }\n\n    void setIndicatorColors(int... colors) {\n      indicatorColors = colors;\n    }\n\n    void setDividerColors(int... colors) {\n      dividerColors = colors;\n    }\n  }\n}\n"
  },
  {
    "path": "library/src/main/java/com/ogaclejapan/smarttablayout/Utils.java",
    "content": "/**\n * Copyright (C) 2015 ogaclejapan\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.ogaclejapan.smarttablayout;\n\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport androidx.core.view.MarginLayoutParamsCompat;\nimport androidx.core.view.ViewCompat;\n\nfinal class Utils {\n\n  static int getMeasuredWidth(View v) {\n    return (v == null) ? 0 : v.getMeasuredWidth();\n  }\n\n  static int getWidth(View v) {\n    return (v == null) ? 0 : v.getWidth();\n  }\n\n  static int getWidthWithMargin(View v) {\n    return getWidth(v) + getMarginHorizontally(v);\n  }\n\n  static int getStart(View v) {\n    return getStart(v, false);\n  }\n\n  static int getStart(View v, boolean withoutPadding) {\n    if (v == null) {\n      return 0;\n    }\n    if (isLayoutRtl(v)) {\n      return (withoutPadding) ? v.getRight() - getPaddingStart(v) : v.getRight();\n    } else {\n      return (withoutPadding) ? v.getLeft() + getPaddingStart(v) : v.getLeft();\n    }\n  }\n\n  static int getEnd(View v) {\n    return getEnd(v, false);\n  }\n\n  static int getEnd(View v, boolean withoutPadding) {\n    if (v == null) {\n      return 0;\n    }\n    if (isLayoutRtl(v)) {\n      return (withoutPadding) ? v.getLeft() + getPaddingEnd(v) : v.getLeft();\n    } else {\n      return (withoutPadding) ? v.getRight() - getPaddingEnd(v) : v.getRight();\n    }\n  }\n\n  static int getPaddingStart(View v) {\n    if (v == null) {\n      return 0;\n    }\n    return ViewCompat.getPaddingStart(v);\n  }\n\n  static int getPaddingEnd(View v) {\n    if (v == null) {\n      return 0;\n    }\n    return ViewCompat.getPaddingEnd(v);\n  }\n\n  static int getPaddingHorizontally(View v) {\n    if (v == null) {\n      return 0;\n    }\n    return v.getPaddingLeft() + v.getPaddingRight();\n  }\n\n  static int getMarginStart(View v) {\n    if (v == null) {\n      return 0;\n    }\n    ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();\n    return MarginLayoutParamsCompat.getMarginStart(lp);\n  }\n\n  static int getMarginEnd(View v) {\n    if (v == null) {\n      return 0;\n    }\n    ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();\n    return MarginLayoutParamsCompat.getMarginEnd(lp);\n  }\n\n  static int getMarginHorizontally(View v) {\n    if (v == null) {\n      return 0;\n    }\n    ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();\n    return MarginLayoutParamsCompat.getMarginStart(lp) + MarginLayoutParamsCompat.getMarginEnd(lp);\n  }\n\n  static boolean isLayoutRtl(View v) {\n    return ViewCompat.getLayoutDirection(v) == ViewCompat.LAYOUT_DIRECTION_RTL;\n  }\n\n  private Utils() { }\n\n}\n"
  },
  {
    "path": "library/src/main/res/values/attrs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n  <declare-styleable name=\"stl_SmartTabLayout\">\n    <attr name=\"stl_indicatorAlwaysInCenter\" format=\"boolean\"/>\n    <attr name=\"stl_indicatorWithoutPadding\" format=\"boolean\"/>\n    <attr name=\"stl_indicatorInFront\" format=\"boolean\"/>\n    <attr name=\"stl_indicatorInterpolation\" format=\"enum\">\n      <enum name=\"smart\" value=\"0\"/>\n      <enum name=\"linear\" value=\"1\"/>\n    </attr>\n    <attr name=\"stl_indicatorGravity\" format=\"enum\">\n      <enum name=\"bottom\" value=\"0\"/>\n      <enum name=\"top\" value=\"1\"/>\n      <enum name=\"center\" value=\"2\"/>\n    </attr>\n    <attr name=\"stl_indicatorColor\" format=\"color\"/>\n    <attr name=\"stl_indicatorColors\" format=\"reference\"/>\n    <attr name=\"stl_indicatorThickness\" format=\"dimension\"/>\n    <attr name=\"stl_indicatorWidth\" format=\"dimension\">\n      <enum name=\"auto\" value=\"-1\"/>\n    </attr>\n    <attr name=\"stl_indicatorCornerRadius\" format=\"dimension\"/>\n    <attr name=\"stl_overlineColor\" format=\"color\"/>\n    <attr name=\"stl_overlineThickness\" format=\"dimension\"/>\n    <attr name=\"stl_underlineColor\" format=\"color\"/>\n    <attr name=\"stl_underlineThickness\" format=\"dimension\"/>\n    <attr name=\"stl_dividerColor\" format=\"color\"/>\n    <attr name=\"stl_dividerColors\" format=\"reference\"/>\n    <attr name=\"stl_dividerThickness\" format=\"dimension\"/>\n    <attr name=\"stl_defaultTabBackground\" format=\"reference\"/>\n    <attr name=\"stl_defaultTabTextAllCaps\" format=\"boolean\"/>\n    <attr name=\"stl_defaultTabTextColor\" format=\"color|reference\"/>\n    <attr name=\"stl_defaultTabTextSize\" format=\"dimension\"/>\n    <attr name=\"stl_defaultTabTextHorizontalPadding\" format=\"dimension\"/>\n    <attr name=\"stl_defaultTabTextMinWidth\" format=\"dimension\"/>\n    <attr name=\"stl_customTabTextLayoutId\" format=\"reference\"/>\n    <attr name=\"stl_customTabTextViewId\" format=\"reference\"/>\n    <attr name=\"stl_distributeEvenly\" format=\"boolean\"/>\n    <attr name=\"stl_clickable\" format=\"boolean\"/>\n    <attr name=\"stl_titleOffset\" format=\"dimension\">\n      <enum name=\"auto_center\" value=\"-1\"/>\n    </attr>\n    <attr name=\"stl_drawDecorationAfterTab\" format=\"boolean\"/>\n  </declare-styleable>\n</resources>\n"
  },
  {
    "path": "publish.gradle",
    "content": "apply plugin: 'com.jfrog.bintray'\napply plugin: 'com.github.dcendents.android-maven'\n\n\n// build a jar with source files\ntask sourcesJar(type: Jar) {\n  from android.sourceSets.main.java.srcDirs\n  classifier = 'sources'\n}\n\ntask javadoc(type: Javadoc) {\n  failOnError false\n  source = android.sourceSets.main.java.sourceFiles\n  classpath += project.files(android.getBootClasspath().join(File.pathSeparator))\n  classpath += configurations.compile\n}\n\n// build a jar with javadoc\ntask javadocJar(type: Jar, dependsOn: javadoc) {\n  classifier = 'javadoc'\n  from javadoc.destinationDir\n}\n\nartifacts {\n  archives sourcesJar\n  archives javadocJar\n}\n\ninstall {\n  repositories.mavenInstaller {\n    // This generates POM.xml with proper parameters\n    pom {\n      project {\n        packaging 'aar'\n\n        name ARTIFACT_NAME\n        description ARTIFACT_DESCRIPTION\n        url SITE_URL\n\n        licenses {\n          license {\n            name LICENCE_NAME\n            url LICENCE_URL\n            distribution LICENCE_DIST\n          }\n        }\n\n        developers {\n          developer {\n            id DEVELOPER_ID\n            name DEVELOPER_NAME\n            email DEVELOPER_EMAIL\n          }\n        }\n        issueManagement {\n          system ISSUE_SYSTEM\n          url ISSUE_URL\n        }\n\n        scm {\n          connection SCM_CONNECTION\n          developerConnection SCM_DEV_CONNECTION\n          url SCM_URL\n\n        }\n      }\n    }\n  }\n}\n\nbintray {\n\n  user = findProperty('BINTRAY_USER')\n  key = findProperty('BINTRAY_APIKEY')\n\n  configurations = ['archives']\n\n  dryRun = false\n  publish = true\n\n  pkg {\n    repo = \"maven\"\n    name = pkginfo.name\n    desc = pkginfo.description\n    websiteUrl = pkginfo.site\n    issueTrackerUrl = pkginfo.issue\n    vcsUrl = pkginfo.vcs\n    licenses = [\"Apache-2.0\"]\n    labels = ['android']\n    publicDownloadNumbers = true\n\n    version {\n      gpg {\n        sign = true\n        passphrase = findProperty('BINTRAY_GPG_PASSPHRASE')\n      }\n\n      mavenCentralSync {\n        sync = true\n        user = findProperty('NEXUS_USER')\n        password = findProperty('NEXUS_PASSWORD')\n        close = '1'\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "settings.gradle",
    "content": "include ':demo', ':library', ':utils-v4'\n"
  },
  {
    "path": "utils-v4/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "utils-v4/LICENSE",
    "content": "Copyright (C) 2015 ogaclejapan\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "utils-v4/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply plugin: 'com.github.ben-manes.versions'\napply plugin: 'com.github.hierynomus.license'\n\nandroid {\n  compileSdkVersion COMPILE_SDK_VERSION as int\n\n  defaultConfig {\n    minSdkVersion 14\n    targetSdkVersion COMPILE_SDK_VERSION as int\n    versionCode VERSION_CODE as int\n    versionName VERSION_NAME\n\n  }\n  buildTypes {\n    release {\n      minifyEnabled false\n      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n    }\n  }\n}\n\ndependencies {\n  implementation \"androidx.fragment:fragment:${ANDROIDX_BASE_VERSION}\"\n}\n\nlicense {\n\n  sourceSets {\n    main.java.srcDirs = android.sourceSets.main.java.srcDirs\n    main.resources.srcDirs = android.sourceSets.main.resources.srcDirs\n  }\n\n  ext.year = Calendar.getInstance().get(Calendar.YEAR)\n  ext.name = DEVELOPER_ID\n\n}\n\npkginfo.name = ARTIFACT_NAME + '-V4Utils'\napply from: \"${project.rootDir}/publish.gradle\"\n"
  },
  {
    "path": "utils-v4/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/msk/Library/Android/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n"
  },
  {
    "path": "utils-v4/src/main/AndroidManifest.xml",
    "content": "<manifest package=\"com.ogaclejapan.smarttablayout.utils\">\n\n</manifest>\n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/PagerItem.java",
    "content": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.ogaclejapan.smarttablayout.utils;\n\npublic abstract class PagerItem {\n\n  protected static final float DEFAULT_WIDTH = 1.f;\n\n  private final CharSequence title;\n  private final float width;\n\n  protected PagerItem(CharSequence title, float width) {\n    this.title = title;\n    this.width = width;\n  }\n\n  public CharSequence getTitle() {\n    return title;\n  }\n\n  public float getWidth() {\n    return width;\n  }\n\n}\n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/PagerItems.java",
    "content": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.ogaclejapan.smarttablayout.utils;\n\nimport android.content.Context;\n\nimport java.util.ArrayList;\n\npublic abstract class PagerItems<T extends PagerItem> extends ArrayList<T> {\n\n  private final Context context;\n\n  protected PagerItems(Context context) {\n    this.context = context;\n  }\n\n  public Context getContext() {\n    return context;\n  }\n\n}\n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/ViewPagerItem.java",
    "content": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.ogaclejapan.smarttablayout.utils;\n\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport androidx.annotation.LayoutRes;\n\npublic class ViewPagerItem extends PagerItem {\n\n  private final int resource;\n\n  protected ViewPagerItem(CharSequence title, float width, @LayoutRes int resource) {\n    super(title, width);\n    this.resource = resource;\n  }\n\n  public static ViewPagerItem of(CharSequence title, @LayoutRes int resource) {\n    return of(title, DEFAULT_WIDTH, resource);\n  }\n\n  public static ViewPagerItem of(CharSequence title, float width, @LayoutRes int resource) {\n    return new ViewPagerItem(title, width, resource);\n  }\n\n  public View initiate(LayoutInflater inflater, ViewGroup container) {\n    return inflater.inflate(resource, container, false);\n  }\n\n}\n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/ViewPagerItemAdapter.java",
    "content": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.ogaclejapan.smarttablayout.utils;\n\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport java.lang.ref.WeakReference;\n\nimport androidx.annotation.NonNull;\nimport androidx.collection.SparseArrayCompat;\nimport androidx.viewpager.widget.PagerAdapter;\n\npublic class ViewPagerItemAdapter extends PagerAdapter {\n\n  private final ViewPagerItems pages;\n  private final SparseArrayCompat<WeakReference<View>> holder;\n  private final LayoutInflater inflater;\n\n  public ViewPagerItemAdapter(ViewPagerItems pages) {\n    this.pages = pages;\n    this.holder = new SparseArrayCompat<>(pages.size());\n    this.inflater = LayoutInflater.from(pages.getContext());\n  }\n\n  @Override\n  public int getCount() {\n    return pages.size();\n  }\n\n  @NonNull\n  @Override\n  public Object instantiateItem(@NonNull ViewGroup container, int position) {\n    View view = getPagerItem(position).initiate(inflater, container);\n    container.addView(view);\n    holder.put(position, new WeakReference<View>(view));\n    return view;\n  }\n\n  @Override\n  public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {\n    holder.remove(position);\n    container.removeView((View) object);\n  }\n\n  @Override\n  public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {\n    return object == view;\n  }\n\n  @Override\n  public CharSequence getPageTitle(int position) {\n    return getPagerItem(position).getTitle();\n  }\n\n  @Override\n  public float getPageWidth(int position) {\n    return getPagerItem(position).getWidth();\n  }\n\n  public View getPage(int position) {\n    final WeakReference<View> weakRefItem = holder.get(position);\n    return (weakRefItem != null) ? weakRefItem.get() : null;\n  }\n\n  protected ViewPagerItem getPagerItem(int position) {\n    return pages.get(position);\n  }\n}\n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/ViewPagerItems.java",
    "content": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.ogaclejapan.smarttablayout.utils;\n\nimport android.content.Context;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.StringRes;\n\npublic class ViewPagerItems extends PagerItems<ViewPagerItem> {\n\n  public ViewPagerItems(Context context) {\n    super(context);\n  }\n\n  public static Creator with(Context context) {\n    return new Creator(context);\n  }\n\n  public static class Creator {\n\n    private final ViewPagerItems items;\n\n    public Creator(Context context) {\n      items = new ViewPagerItems(context);\n    }\n\n    public Creator add(@StringRes int title, @LayoutRes int resource) {\n      return add(ViewPagerItem.of(items.getContext().getString(title), resource));\n    }\n\n    public Creator add(@StringRes int title, float width, @LayoutRes int resource) {\n      return add(ViewPagerItem.of(items.getContext().getString(title), width, resource));\n    }\n\n    public Creator add(CharSequence title, @LayoutRes int resource) {\n      return add(ViewPagerItem.of(title, resource));\n    }\n\n    public Creator add(ViewPagerItem item) {\n      items.add(item);\n      return this;\n    }\n\n    public ViewPagerItems create() {\n      return items;\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/Bundler.java",
    "content": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.ogaclejapan.smarttablayout.utils.v4;\n\nimport android.annotation.TargetApi;\nimport android.os.Bundle;\nimport android.os.IBinder;\nimport android.os.Parcelable;\nimport android.util.Size;\nimport android.util.SizeF;\nimport android.util.SparseArray;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\n\nimport androidx.fragment.app.Fragment;\n\npublic class Bundler {\n\n  private final Bundle bundle;\n\n  /**\n   * Constructs a new, empty Bundle.\n   */\n  public Bundler() {\n    this(null);\n  }\n\n  private Bundler(Bundle b) {\n    bundle = (b == null) ? new Bundle() : new Bundle(b);\n  }\n\n  /**\n   * Constructs a Bundle containing a copy of the mappings from the given\n   * Bundle.\n   *\n   * @param b a Bundle to be copied.\n   */\n  public static Bundler of(Bundle b) {\n    return new Bundler(b);\n  }\n\n  /**\n   * Inserts all mappings from the given Bundle into this Bundle.\n   *\n   * @param bundle a Bundle\n   * @return this\n   */\n  public Bundler putAll(Bundle bundle) {\n    this.bundle.putAll(bundle);\n    return this;\n  }\n\n  /**\n   * Inserts a byte value into the mapping of this Bundle, replacing\n   * any existing value for the given key.\n   *\n   * @param key a String, or null\n   * @param value a byte\n   * @return this\n   */\n  public Bundler putByte(String key, byte value) {\n    bundle.putByte(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a char value into the mapping of this Bundle, replacing\n   * any existing value for the given key.\n   *\n   * @param key a String, or null\n   * @param value a char, or null\n   * @return this\n   */\n  public Bundler putChar(String key, char value) {\n    bundle.putChar(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a short value into the mapping of this Bundle, replacing\n   * any existing value for the given key.\n   *\n   * @param key a String, or null\n   * @param value a short\n   * @return this\n   */\n  public Bundler putShort(String key, short value) {\n    bundle.putShort(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a float value into the mapping of this Bundle, replacing\n   * any existing value for the given key.\n   *\n   * @param key a String, or null\n   * @param value a float\n   * @return this\n   */\n  public Bundler putFloat(String key, float value) {\n    bundle.putFloat(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a CharSequence value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a CharSequence, or null\n   * @return this\n   */\n  public Bundler putCharSequence(String key, CharSequence value) {\n    bundle.putCharSequence(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a Parcelable value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a Parcelable object, or null\n   * @return this\n   */\n  public Bundler putParcelable(String key, Parcelable value) {\n    bundle.putParcelable(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a Size value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a Size object, or null\n   * @return this\n   */\n  @TargetApi(21)\n  public Bundler putSize(String key, Size value) {\n    bundle.putSize(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a SizeF value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a SizeF object, or null\n   * @return this\n   */\n  @TargetApi(21)\n  public Bundler putSizeF(String key, SizeF value) {\n    bundle.putSizeF(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts an array of Parcelable values into the mapping of this Bundle,\n   * replacing any existing value for the given key.  Either key or value may\n   * be null.\n   *\n   * @param key a String, or null\n   * @param value an array of Parcelable objects, or null\n   * @return this\n   */\n  public Bundler putParcelableArray(String key, Parcelable[] value) {\n    bundle.putParcelableArray(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a List of Parcelable values into the mapping of this Bundle,\n   * replacing any existing value for the given key.  Either key or value may\n   * be null.\n   *\n   * @param key a String, or null\n   * @param value an ArrayList of Parcelable objects, or null\n   * @return this\n   */\n  public Bundler putParcelableArrayList(String key,\n      ArrayList<? extends Parcelable> value) {\n    bundle.putParcelableArrayList(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a SparceArray of Parcelable values into the mapping of this\n   * Bundle, replacing any existing value for the given key.  Either key\n   * or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a SparseArray of Parcelable objects, or null\n   * @return this\n   */\n  public Bundler putSparseParcelableArray(String key,\n      SparseArray<? extends Parcelable> value) {\n    bundle.putSparseParcelableArray(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts an ArrayList<Integer> value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value an ArrayList<Integer> object, or null\n   * @return this\n   */\n  public Bundler putIntegerArrayList(String key, ArrayList<Integer> value) {\n    bundle.putIntegerArrayList(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts an ArrayList<String> value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value an ArrayList<String> object, or null\n   * @return this\n   */\n  public Bundler putStringArrayList(String key, ArrayList<String> value) {\n    bundle.putStringArrayList(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts an ArrayList<CharSequence> value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value an ArrayList<CharSequence> object, or null\n   * @return this\n   */\n  @TargetApi(8)\n  public Bundler putCharSequenceArrayList(String key, ArrayList<CharSequence> value) {\n    bundle.putCharSequenceArrayList(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a Serializable value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a Serializable object, or null\n   * @return this\n   */\n  public Bundler putSerializable(String key, Serializable value) {\n    bundle.putSerializable(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a byte array value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a byte array object, or null\n   * @return this\n   */\n  public Bundler putByteArray(String key, byte[] value) {\n    bundle.putByteArray(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a short array value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a short array object, or null\n   * @return this\n   */\n  public Bundler putShortArray(String key, short[] value) {\n    bundle.putShortArray(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a char array value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a char array object, or null\n   * @return this\n   */\n  public Bundler putCharArray(String key, char[] value) {\n    bundle.putCharArray(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a float array value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a float array object, or null\n   * @return this\n   */\n  public Bundler putFloatArray(String key, float[] value) {\n    bundle.putFloatArray(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a CharSequence array value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a CharSequence array object, or null\n   * @return this\n   */\n  @TargetApi(8)\n  public Bundler putCharSequenceArray(String key, CharSequence[] value) {\n    bundle.putCharSequenceArray(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a Bundle value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a Bundle object, or null\n   * @return this\n   */\n  public Bundler putBundle(String key, Bundle value) {\n    bundle.putBundle(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts an {@link android.os.IBinder} value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * <p class=\"note\">You should be very careful when using this function.  In many\n   * places where Bundles are used (such as inside of Intent objects), the Bundle\n   * can live longer inside of another process than the process that had originally\n   * created it.  In that case, the IBinder you supply here will become invalid\n   * when your process goes away, and no longer usable, even if a new process is\n   * created for you later on.</p>\n   *\n   * @param key a String, or null\n   * @param value an IBinder object, or null\n   * @return this\n   */\n  @TargetApi(18)\n  public Bundler putBinder(String key, IBinder value) {\n    bundle.putBinder(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a Boolean value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a Boolean, or null\n   * @return this\n   */\n  public Bundler putBoolean(String key, boolean value) {\n    bundle.putBoolean(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts an int value into the mapping of this Bundle, replacing\n   * any existing value for the given key.\n   *\n   * @param key a String, or null\n   * @param value an int, or null\n   * @return this\n   */\n  public Bundler putInt(String key, int value) {\n    bundle.putInt(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a long value into the mapping of this Bundle, replacing\n   * any existing value for the given key.\n   *\n   * @param key a String, or null\n   * @param value a long\n   * @return this\n   */\n  public Bundler putLong(String key, long value) {\n    bundle.putLong(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a double value into the mapping of this Bundle, replacing\n   * any existing value for the given key.\n   *\n   * @param key a String, or null\n   * @param value a double\n   * @return this\n   */\n  public Bundler putDouble(String key, double value) {\n    bundle.putDouble(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a String value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a String, or null\n   * @return this\n   */\n  public Bundler putString(String key, String value) {\n    bundle.putString(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a boolean array value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a boolean array object, or null\n   * @return this\n   */\n  public Bundler putBooleanArray(String key, boolean[] value) {\n    bundle.putBooleanArray(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts an int array value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value an int array object, or null\n   * @return this\n   */\n  public Bundler putIntArray(String key, int[] value) {\n    bundle.putIntArray(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a long array value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a long array object, or null\n   * @return this\n   */\n  public Bundler putLongArray(String key, long[] value) {\n    bundle.putLongArray(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a double array value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a double array object, or null\n   * @return this\n   */\n  public Bundler putDoubleArray(String key, double[] value) {\n    bundle.putDoubleArray(key, value);\n    return this;\n  }\n\n  /**\n   * Inserts a String array value into the mapping of this Bundle, replacing\n   * any existing value for the given key.  Either key or value may be null.\n   *\n   * @param key a String, or null\n   * @param value a String array object, or null\n   * @return this\n   */\n  public Bundler putStringArray(String key, String[] value) {\n    bundle.putStringArray(key, value);\n    return this;\n  }\n\n  /**\n   * Get the bundle.\n   *\n   * @return a bundle\n   */\n  public Bundle get() {\n    return bundle;\n  }\n\n  /**\n   * Set the argument of Fragment.\n   *\n   * @param fragment a fragment\n   * @return a fragment\n   */\n  public <T extends Fragment> T into(T fragment) {\n    fragment.setArguments(get());\n    return fragment;\n  }\n\n}\n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentPagerItem.java",
    "content": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.ogaclejapan.smarttablayout.utils.v4;\n\nimport android.content.Context;\nimport android.os.Bundle;\n\nimport com.ogaclejapan.smarttablayout.utils.PagerItem;\n\nimport androidx.fragment.app.Fragment;\n\npublic class FragmentPagerItem extends PagerItem {\n\n  private static final String TAG = \"FragmentPagerItem\";\n  private static final String KEY_POSITION = TAG + \":Position\";\n\n  private final String className;\n  private final Bundle args;\n\n  protected FragmentPagerItem(CharSequence title, float width, String className, Bundle args) {\n    super(title, width);\n    this.className = className;\n    this.args = args;\n  }\n\n  public static FragmentPagerItem of(CharSequence title, Class<? extends Fragment> clazz) {\n    return of(title, DEFAULT_WIDTH, clazz);\n  }\n\n  public static FragmentPagerItem of(CharSequence title, Class<? extends Fragment> clazz,\n      Bundle args) {\n    return of(title, DEFAULT_WIDTH, clazz, args);\n  }\n\n  public static FragmentPagerItem of(CharSequence title, float width,\n      Class<? extends Fragment> clazz) {\n    return of(title, width, clazz, new Bundle());\n  }\n\n  public static FragmentPagerItem of(CharSequence title, float width,\n      Class<? extends Fragment> clazz, Bundle args) {\n    return new FragmentPagerItem(title, width, clazz.getName(), args);\n  }\n\n  public static boolean hasPosition(Bundle args) {\n    return args != null && args.containsKey(KEY_POSITION);\n  }\n\n  public static int getPosition(Bundle args) {\n    return (hasPosition(args)) ? args.getInt(KEY_POSITION) : 0;\n  }\n\n  static void setPosition(Bundle args, int position) {\n    args.putInt(KEY_POSITION, position);\n  }\n\n  public Fragment instantiate(Context context, int position) {\n    setPosition(args, position);\n    return Fragment.instantiate(context, className, args);\n  }\n\n}\n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentPagerItemAdapter.java",
    "content": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.ogaclejapan.smarttablayout.utils.v4;\n\nimport android.view.ViewGroup;\n\nimport java.lang.ref.WeakReference;\n\nimport androidx.annotation.NonNull;\nimport androidx.collection.SparseArrayCompat;\nimport androidx.fragment.app.Fragment;\nimport androidx.fragment.app.FragmentManager;\nimport androidx.fragment.app.FragmentPagerAdapter;\n\npublic class FragmentPagerItemAdapter extends FragmentPagerAdapter {\n\n  private final FragmentPagerItems pages;\n  private final SparseArrayCompat<WeakReference<Fragment>> holder;\n\n  public FragmentPagerItemAdapter(FragmentManager fm, FragmentPagerItems pages) {\n    super(fm);\n    this.pages = pages;\n    this.holder = new SparseArrayCompat<>(pages.size());\n  }\n\n  @Override\n  public int getCount() {\n    return pages.size();\n  }\n\n  @Override\n  public Fragment getItem(int position) {\n    return getPagerItem(position).instantiate(pages.getContext(), position);\n  }\n\n  @NonNull\n  @Override\n  public Object instantiateItem(@NonNull ViewGroup container, int position) {\n    Object item = super.instantiateItem(container, position);\n    if (item instanceof Fragment) {\n      holder.put(position, new WeakReference<Fragment>((Fragment) item));\n    }\n    return item;\n  }\n\n  @Override\n  public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {\n    holder.remove(position);\n    super.destroyItem(container, position, object);\n  }\n\n  @Override\n  public CharSequence getPageTitle(int position) {\n    return getPagerItem(position).getTitle();\n  }\n\n  @Override\n  public float getPageWidth(int position) {\n    return super.getPageWidth(position);\n  }\n\n  public Fragment getPage(int position) {\n    final WeakReference<Fragment> weakRefItem = holder.get(position);\n    return (weakRefItem != null) ? weakRefItem.get() : null;\n  }\n\n  protected FragmentPagerItem getPagerItem(int position) {\n    return pages.get(position);\n  }\n\n}\n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentPagerItems.java",
    "content": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.ogaclejapan.smarttablayout.utils.v4;\n\nimport android.content.Context;\nimport android.os.Bundle;\n\nimport com.ogaclejapan.smarttablayout.utils.PagerItems;\n\nimport androidx.annotation.StringRes;\nimport androidx.fragment.app.Fragment;\n\npublic class FragmentPagerItems extends PagerItems<FragmentPagerItem> {\n\n  public FragmentPagerItems(Context context) {\n    super(context);\n  }\n\n  public static Creator with(Context context) {\n    return new Creator(context);\n  }\n\n  public static class Creator {\n\n    private final FragmentPagerItems items;\n\n    public Creator(Context context) {\n      items = new FragmentPagerItems(context);\n    }\n\n    public Creator add(@StringRes int title, Class<? extends Fragment> clazz) {\n      return add(FragmentPagerItem.of(items.getContext().getString(title), clazz));\n    }\n\n    public Creator add(@StringRes int title, Class<? extends Fragment> clazz, Bundle args) {\n      return add(FragmentPagerItem.of(items.getContext().getString(title), clazz, args));\n    }\n\n    public Creator add(@StringRes int title, float width, Class<? extends Fragment> clazz) {\n      return add(FragmentPagerItem.of(items.getContext().getString(title), width, clazz));\n    }\n\n    public Creator add(@StringRes int title, float width, Class<? extends Fragment> clazz,\n        Bundle args) {\n      return add(FragmentPagerItem.of(items.getContext().getString(title), width, clazz, args));\n    }\n\n    public Creator add(CharSequence title, Class<? extends Fragment> clazz) {\n      return add(FragmentPagerItem.of(title, clazz));\n    }\n\n    public Creator add(CharSequence title, Class<? extends Fragment> clazz, Bundle args) {\n      return add(FragmentPagerItem.of(title, clazz, args));\n    }\n\n    public Creator add(FragmentPagerItem item) {\n      items.add(item);\n      return this;\n    }\n\n    public FragmentPagerItems create() {\n      return items;\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "utils-v4/src/main/java/com/ogaclejapan/smarttablayout/utils/v4/FragmentStatePagerItemAdapter.java",
    "content": "/**\n * Copyright (C) 2015 ogaclejapan\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage com.ogaclejapan.smarttablayout.utils.v4;\n\nimport android.view.ViewGroup;\n\nimport java.lang.ref.WeakReference;\n\nimport androidx.annotation.NonNull;\nimport androidx.collection.SparseArrayCompat;\nimport androidx.fragment.app.Fragment;\nimport androidx.fragment.app.FragmentManager;\nimport androidx.fragment.app.FragmentStatePagerAdapter;\n\npublic class FragmentStatePagerItemAdapter extends FragmentStatePagerAdapter {\n\n  private final FragmentPagerItems pages;\n  private final SparseArrayCompat<WeakReference<Fragment>> holder;\n\n  public FragmentStatePagerItemAdapter(FragmentManager fm, FragmentPagerItems pages) {\n    super(fm);\n    this.pages = pages;\n    this.holder = new SparseArrayCompat<>(pages.size());\n  }\n\n  @Override\n  public int getCount() {\n    return pages.size();\n  }\n\n  @Override\n  public Fragment getItem(int position) {\n    return getPagerItem(position).instantiate(pages.getContext(), position);\n  }\n\n  @NonNull\n  @Override\n  public Object instantiateItem(@NonNull ViewGroup container, int position) {\n    Object item = super.instantiateItem(container, position);\n    if (item instanceof Fragment) {\n      holder.put(position, new WeakReference<Fragment>((Fragment) item));\n    }\n    return item;\n  }\n\n  @Override\n  public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {\n    holder.remove(position);\n    super.destroyItem(container, position, object);\n  }\n\n  @Override\n  public CharSequence getPageTitle(int position) {\n    return getPagerItem(position).getTitle();\n  }\n\n  @Override\n  public float getPageWidth(int position) {\n    return getPagerItem(position).getWidth();\n  }\n\n  public Fragment getPage(int position) {\n    final WeakReference<Fragment> weakRefItem = holder.get(position);\n    return (weakRefItem != null) ? weakRefItem.get() : null;\n  }\n\n  protected FragmentPagerItem getPagerItem(int position) {\n    return pages.get(position);\n  }\n\n}\n"
  }
]