├── .gitignore ├── CHANGELOG.md ├── README.md ├── art ├── material_tabs.gif └── material_tabs_middle.gif ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library ├── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── project.properties ├── res │ ├── drawable-v21 │ │ └── psts_background_tab.xml │ ├── drawable │ │ └── psts_background_tab.xml │ ├── layout │ │ └── psts_tab.xml │ └── values │ │ ├── attrs.xml │ │ └── colors.xml └── src │ └── com │ └── astuetz │ └── PagerSlidingTabStrip.java ├── sample ├── AndroidManifest.xml ├── build.gradle ├── ic_launcher-web.png ├── project.properties ├── res │ ├── drawable-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_actionbar.png │ ├── drawable-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_actionbar.png │ ├── drawable-xhdpi │ │ ├── actionbar_bottom.9.png │ │ ├── background_card.9.png │ │ ├── contact.png │ │ ├── ic_action_user.png │ │ ├── ic_launcher.png │ │ ├── ic_launcher_actionbar.png │ │ ├── ic_launcher_chrome.png │ │ ├── ic_launcher_gmail.png │ │ ├── ic_launcher_gmaps.png │ │ ├── ic_launcher_gplus.png │ │ ├── tabs_pattern.png │ │ └── tabs_pattern_diagonal.png │ ├── drawable-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_actionbar.png │ ├── drawable │ │ ├── background_tabs.xml │ │ └── background_tabs_diagonal.xml │ ├── layout-land │ │ └── fragment_quick_contact.xml │ ├── layout-v11 │ │ └── custom_tab.xml │ ├── layout │ │ ├── activity_main.xml │ │ ├── custom_tab.xml │ │ ├── fragment_card.xml │ │ ├── fragment_quick_contact.xml │ │ ├── fragment_quickcontact.xml │ │ └── toolbar.xml │ ├── menu │ │ └── main.xml │ ├── values-sw600dp │ │ └── dimens.xml │ ├── values-sw720dp-land │ │ └── dimens.xml │ ├── values-v11 │ │ ├── styles.xml │ │ └── themes.xml │ ├── values-v19 │ │ └── themes.xml │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── themes.xml └── src │ └── com │ └── astuetz │ └── viewpager │ └── extensions │ └── sample │ ├── LinearLayoutFeedback.java │ ├── MainActivity.java │ ├── QuickContactFragment.java │ └── SuperAwesomeCardFragment.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | #Android generated 2 | bin 3 | gen 4 | gen* 5 | 6 | #Eclipse 7 | .project 8 | .classpath 9 | .settings 10 | 11 | #IntelliJ IDEA 12 | .idea 13 | *.iml 14 | *.ipr 15 | *.iws 16 | out 17 | 18 | #Maven 19 | target 20 | release.properties 21 | pom.xml.* 22 | 23 | #Ant 24 | build.xml 25 | local.properties 26 | proguard.cfg 27 | 28 | #Gradle 29 | .gradle 30 | build 31 | 32 | #OSX 33 | .DS_Store 34 | 35 | #Personal Files 36 | signing.properties -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Change Log 2 | ========== 3 | 4 | Version 1.1.1 *(04-09-2016)* 5 | --------------------------------- 6 | * Bug fixes 7 | * Allow create custom animation for the tab indicator line #155 8 | 9 | Version 1.1.0 *(01-06-2015)* 10 | --------------------------------- 11 | * Bug fixes 12 | * Rename some custom attributes. 13 | * Default ripple effect selector in 21+ 14 | * Default sans-serif-medium tab's text in API 21+ 15 | * app:pstsTextFontFamily for overriding the typeface from the XML. The attribute works exactly like android:fontFamily for TextViews. 16 | * Remove custom attire `pstsTextColorSelected ` and `pstsTextSelectedStyle`. 17 | * `pstsTabTextColor` will handle the tab text color states. 18 | * `pstsTabTextSize` will handle the tab text size. 19 | * Callbacks for selection/deselection of tabs passing the tab view as parameter when custom tabs are use. 20 | 21 | Version 1.0.9 *(22-02-2015)* 22 | --------------------------------- 23 | * Bug fixes 24 | * Add parsing of independent padding attributes (#69) 25 | * pstsTextAlpha value range change from 0..1 to 0..255. 26 | * New attr pstsTextColorSelected 27 | * R.id.tab_title changed to R.id.psts_tab_title 28 | * R.layout.tab changed to R.layout.psts_tab 29 | * R.drawable.background_tab changed to R.drawable.psts_background_tab 30 | 31 | 32 | Version 1.0.8 *(14-01-2015)* 33 | ---------------------------- 34 | * Bug fixes 35 | * Ability to build the library using maven 36 | * Update support-v4 library to v21.0.3 37 | 38 | Version 1.0.7 *(08-01-2015)* 39 | ---------------------------- 40 | * Bug fixes 41 | * OnTabReselectedListener 42 | 43 | Version 1.0.6 *(21-11-2014)* 44 | ---------------------------- 45 | * Update support-v4 library to v21.0.2 46 | * Bug fixes 47 | 48 | Version 1.0.5 *(19-11-2014)* 49 | ---------------------------- 50 | * android:textColorPrimary value (from your theme) will be applied automatically to tab's text color , underlineColor, dividerColor and indicatorColor, if any of these values are define in the xml layout. 51 | * Bug fixes 52 | 53 | Version 1.0.4 *(18-11-2014)* 54 | ---------------------------- 55 | * Bug fixes 56 | 57 | Version 1.0.3 *(11-11-2014)* 58 | ---------------------------- 59 | 60 | * Fix issues #7 61 | * Add support for colour state lists. 62 | * Add support for custom text style. 63 | * Add support for custom alpha values. 64 | 65 | Version 1.0.2 *(05-11-2014)* 66 | ---------------------------- 67 | * MinSDK 10 68 | 69 | * Change the default parameters of the tabs layout to make 70 | it look like more material. 71 | 72 | * The indicator is center by default while swiping tabs and paddingMiddle attr 73 | has the possibility to start the tabs in the middle like newsstand google app. 74 | 75 | * The alpha value of the titles change depending the selected position. 76 | 77 | * Ability to change the divider width (No material change). 78 | 79 | * Ability to pass customTabs implementing the interface 80 | 'CustomTabProvider' in your adapter. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android PagerSlidingTabStrip (default Material Design) 2 | 3 | **This library is not maintained anymore and there will be no further releases. For most of the cases you can use [TabLayout](https://developer.android.com/reference/com/google/android/material/tabs/TabLayout) instead of this library.** 4 | 5 | Interactive paging indicator widget, compatible with the `ViewPager` from the 6 | Android Support Library. 7 | 8 | ![PagerSlidingTabStrip Sample Material](https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/master/art/material_tabs.gif) ------ 9 | ![PagerSlidingTabStrip Sample Material](https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/master/art/material_tabs_middle.gif) 10 | 11 | # Usage 12 | 13 | For a working implementation of this project see the `sample/` folder. 14 | 15 | 1. Include the following dependency in your `build.gradle` file. 16 | 17 | ```groovy 18 | compile 'com.jpardogo.materialtabstrip:library:1.1.1' 19 | ``` 20 | 21 | Or add the library as a project. I tried to send a pull request, but looks like the original developer doesn't maintain it anymore. 22 | 23 | 2. Include the `PagerSlidingTabStrip` widget in your layout. This should usually be placed above the `ViewPager` it represents. 24 | 25 | ```xml 26 | 31 | ``` 32 | 33 | 3. In your `onCreate` method (or `onCreateView` for a fragment), bind the widget to the `ViewPager`: 34 | 35 | ```java 36 | // Initialize the ViewPager and set an adapter 37 | ViewPager pager = (ViewPager) findViewById(R.id.pager); 38 | pager.setAdapter(new TestAdapter(getSupportFragmentManager())); 39 | 40 | // Bind the tabs to the ViewPager 41 | PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs); 42 | tabs.setViewPager(pager); 43 | ``` 44 | 45 | ### That's all you need to do, but if you want to use your own tabs, then... 46 | 47 | 1. If your adapter implements the interface `CustomTabProvider` you can paste your custom tab view/s. 48 | 49 | - In case the the view returned contains the id `R.id.psts_tab_title`, this view should be a `TextView` and 50 | will be used to placed the title and set the view state (pressed/selected/default). 51 | 52 | - If you don't want the library manage your TextView title for the tab, use a different id than `R.id.psts_tab_title` in your tab layout. 53 | 54 | - The interface provide callbacks for selection and unselection of tabs as well. 55 | 56 | - If your adapter doesn't implement the interface `CustomTabProvider` the default tab will be used, which is a `TextView` with id `R.id.psts_tab_title`). 57 | 58 | 2. *(Optional)* If you use an `OnPageChangeListener` with your view pager 59 | you should set it in the widget rather than on the pager directly. 60 | 61 | ```java 62 | // continued from above 63 | tabs.setOnPageChangeListener(mPageChangeListener); 64 | ``` 65 | 66 | # Customization 67 | 68 | From theme: 69 | 70 | * `android:textColorPrimary` value (from your theme) will be applied automatically to the tab's text color (Selected tab with 255 alpha and non selected tabs with 150 alpha), underlineColor, dividerColor and indicatorColor, if the values are not defined on the xml layout. 71 | 72 | Notes about some of the native attributes: 73 | 74 | * `android:paddingLeft` or `android:paddingRight` layout padding. If you apply both, they should be balanced. Check issue [#69](https://github.com/jpardogo/PagerSlidingTabStrip/pull/69) for more information. 75 | 76 | Custom attributes: 77 | 78 | * `pstsIndicatorColor` Color of the sliding indicator. `textColorPrimary` will be it's default color value. 79 | * `pstsIndicatorHeight`Height of the sliding indicator. 80 | * `pstsUnderlineColor` Color of the full-width line on the bottom of the view. `textColorPrimary` will be it's default color value. 81 | * `pstsUnderlineHeight` Height of the full-width line on the bottom of the view. 82 | * `pstsDividerColor` Color of the dividers between tabs. `textColorPrimary` will be it's default color value. 83 | * `pstsDividerWidth` Stroke width of divider line, defaults to 0. 84 | * `pstsDividerPadding` Top and bottom padding of the dividers. 85 | * `pstsShouldExpand` If set to true, each tab is given the same weight, default false. 86 | * `pstsScrollOffset` Scroll offset of the selected tab. 87 | * `pstsPaddingMiddle` If true, the tabs start at the middle of the view (Like Newsstand google app). 88 | * `pstsTabPaddingLeftRight` Left and right padding of each tab. 89 | * `pstsTabBackground` Background drawable of each tab, should be a StateListDrawable. 90 | * `pstsTabTextSize` Tab text size (sp). 91 | * `pstsTabTextColor` Tab text color that can either be a color (text color won't changed) or a selector with a color per state: pressed (tab pressed), selected (tab active), default (active non active). The order of states in the selector is important. Check issue [#68](https://github.com/jpardogo/PagerSlidingTabStrip/pull/70) for more information. 92 | * `pstsTabTextStyle` Set the text style, default normal on API 21, bold on older APIs. 93 | * `pstsTabTextAllCaps` If true, all tab titles will be upper case, default true. 94 | * `pstsTabTextAlpha` Set the text alpha transparency for non selected tabs. Range 0..255. 150 is it's default value. It **WON'T** be used if `pstsTabTextColor` is defined in the layout. If `pstsTabTextColor` is **NOT** defined, It will be applied to the non selected tabs. 95 | * `pstsTabTextFontFamily` Set the font family name. Default `sans-serif-medium` on API 21, `sans-serif` on older APIs. 96 | 97 | Almost all attributes have their respective getters and setters to change them at runtime. To change dynamically `pstsTabTextFontFamily` and `pstsTabTextStyle` you can call: 98 | 99 | * `public void setTypeface(Typeface typeface, int style)`. It can be used to define custom fonts in default tabs. Otherwise you can use custom tabs with `CustomTabProvider`. 100 | 101 | Please open an issue if you find any are missing. 102 | 103 | # Developed By 104 | 105 | * Javier Pardo de Santayana Gomez - [jpardogo.com](http://www.jpardogo.com) - 106 | * Andreas Stuetz - 107 | * And contributors. 108 | 109 | # Contributions 110 | 111 | * Please, read the README file before opening an issue, thanks. 112 | * Please, all the Pull Request must be sent to the dev branch, thanks.. 113 | 114 | # Credits 115 | 116 | * [Kirill Grouchnikov](https://plus.google.com/108761828584265913206/posts) - Author of [an explanation post on Google+](https://plus.google.com/108761828584265913206/posts/Cwk7joBV3AC) 117 | 118 | # License 119 | 120 | Copyright 2013 Andreas Stuetz 121 | 122 | Licensed under the Apache License, Version 2.0 (the "License"); 123 | you may not use this file except in compliance with the License. 124 | You may obtain a copy of the License at 125 | 126 | http://www.apache.org/licenses/LICENSE-2.0 127 | 128 | Unless required by applicable law or agreed to in writing, software 129 | distributed under the License is distributed on an "AS IS" BASIS, 130 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131 | See the License for the specific language governing permissions and 132 | limitations under the License. 133 | -------------------------------------------------------------------------------- /art/material_tabs.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/art/material_tabs.gif -------------------------------------------------------------------------------- /art/material_tabs_middle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/art/material_tabs_middle.gif -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | 3 | repositories { 4 | mavenCentral() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.1.3' 9 | classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' 10 | } 11 | 12 | } 13 | 14 | allprojects { 15 | version = VERSION_NAME 16 | group = GROUP 17 | 18 | repositories { 19 | mavenCentral() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | VERSION_NAME=1.1.1 2 | GROUP=com.jpardogo.materialtabstrip 3 | 4 | SAMPLE_VERSION_NAME=1.0.2 5 | SAMPLE_VERSION_CODE=3 6 | 7 | POM_DESCRIPTION= ViewPager Material Tabs 8 | POM_URL=https://github.com/jpardogo/PagerSlidingTabStrip 9 | POM_SCM_URL=https://github.com/jpardogo/PagerSlidingTabStrip 10 | POM_SCM_CONNECTION=scm:git@github.com:jpardogo/PagerSlidingTabStrip.git 11 | POM_SCM_DEV_CONNECTION=scm:git@github.com:jpardogo/PagerSlidingTabStrip.git 12 | POM_LICENCE_NAME=The Apache Software License, Version 2.0 13 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt 14 | POM_LICENCE_DIST=repo 15 | POM_DEVELOPER_ID=astuetz 16 | POM_DEVELOPER_NAME=Andreas Stuetz 17 | ANDROID_BUILD_TARGET_SDK_VERSION=24 18 | ANDROID_BUILD_TOOLS_VERSION=24.0.2 19 | ANDROID_BUILD_MIN_SDK_VERSION=10 -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Aug 26 16:50:50 BST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /library/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /library/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | dependencies { 4 | compile "com.android.support:support-core-ui:24.2.0" 5 | } 6 | 7 | android { 8 | compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION) 9 | buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION 10 | 11 | defaultConfig { 12 | minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION) 13 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION) 14 | } 15 | 16 | android { 17 | lintOptions { 18 | abortOnError false 19 | } 20 | } 21 | 22 | sourceSets { 23 | main { 24 | manifest.srcFile 'AndroidManifest.xml' 25 | java.srcDirs = ['src'] 26 | res.srcDirs = ['res'] 27 | } 28 | } 29 | } 30 | 31 | apply from: 'https://raw.githubusercontent.com/jpardogo/gradle-mvn-push/master/gradle-mvn-push.gradle' -------------------------------------------------------------------------------- /library/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=PagerSlidingTabStrip_Material Library 2 | POM_ARTIFACT_ID=library 3 | POM_PACKAGING=aar -------------------------------------------------------------------------------- /library/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-17 15 | android.library=true 16 | -------------------------------------------------------------------------------- /library/res/drawable-v21/psts_background_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /library/res/drawable/psts_background_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /library/res/layout/psts_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /library/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /library/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #1AFFFFFF 4 | #AAFFFFFF 5 | 6 | -------------------------------------------------------------------------------- /library/src/com/astuetz/PagerSlidingTabStrip.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Andreas Stuetz 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.astuetz; 18 | 19 | import android.content.Context; 20 | import android.content.res.ColorStateList; 21 | import android.content.res.TypedArray; 22 | import android.database.DataSetObserver; 23 | import android.graphics.Canvas; 24 | import android.graphics.Color; 25 | import android.graphics.Paint; 26 | import android.graphics.Paint.Style; 27 | import android.graphics.Typeface; 28 | import android.os.Build; 29 | import android.os.Parcel; 30 | import android.os.Parcelable; 31 | import android.support.v4.content.ContextCompat; 32 | import android.support.v4.util.Pair; 33 | import android.support.v4.view.ViewPager; 34 | import android.support.v4.view.ViewPager.OnPageChangeListener; 35 | import android.util.AttributeSet; 36 | import android.util.DisplayMetrics; 37 | import android.util.TypedValue; 38 | import android.view.LayoutInflater; 39 | import android.view.View; 40 | import android.view.ViewGroup; 41 | import android.widget.HorizontalScrollView; 42 | import android.widget.LinearLayout; 43 | import android.widget.TextView; 44 | 45 | import com.astuetz.pagerslidingtabstrip.R; 46 | 47 | public class PagerSlidingTabStrip extends HorizontalScrollView { 48 | 49 | public static final int DEF_VALUE_TAB_TEXT_ALPHA = 150; 50 | private static final int[] ANDROID_ATTRS = new int[]{ 51 | android.R.attr.textColorPrimary, 52 | android.R.attr.padding, 53 | android.R.attr.paddingLeft, 54 | android.R.attr.paddingRight, 55 | }; 56 | 57 | //These indexes must be related with the ATTR array above 58 | private static final int TEXT_COLOR_PRIMARY = 0; 59 | private static final int PADDING_INDEX = 1; 60 | private static final int PADDING_LEFT_INDEX = 2; 61 | private static final int PADDING_RIGHT_INDEX = 3; 62 | 63 | private LinearLayout mTabsContainer; 64 | private LinearLayout.LayoutParams mTabLayoutParams; 65 | 66 | private final PagerAdapterObserver mAdapterObserver = new PagerAdapterObserver(); 67 | private final PageListener mPageListener = new PageListener(); 68 | private OnTabReselectedListener mTabReselectedListener = null; 69 | public OnPageChangeListener mDelegatePageListener; 70 | private ViewPager mPager; 71 | 72 | private int mTabCount; 73 | 74 | private int mCurrentPosition = 0; 75 | private float mCurrentPositionOffset = 0f; 76 | 77 | private Paint mRectPaint; 78 | private Paint mDividerPaint; 79 | 80 | private int mIndicatorColor; 81 | private int mIndicatorHeight = 2; 82 | 83 | private int mUnderlineHeight = 0; 84 | private int mUnderlineColor; 85 | 86 | private int mDividerWidth = 0; 87 | private int mDividerPadding = 0; 88 | private int mDividerColor; 89 | 90 | private int mTabPadding = 12; 91 | private int mTabTextSize = 14; 92 | private ColorStateList mTabTextColor = null; 93 | 94 | private int mPaddingLeft = 0; 95 | private int mPaddingRight = 0; 96 | 97 | private boolean isExpandTabs = false; 98 | private boolean isCustomTabs; 99 | private boolean isPaddingMiddle = false; 100 | private boolean isTabTextAllCaps = true; 101 | 102 | private Typeface mTabTextTypeface = null; 103 | private int mTabTextTypefaceStyle = Typeface.BOLD; 104 | 105 | private int mScrollOffset; 106 | private int mLastScrollX = 0; 107 | 108 | private int mTabBackgroundResId = R.drawable.psts_background_tab; 109 | 110 | public PagerSlidingTabStrip(Context context) { 111 | this(context, null); 112 | } 113 | 114 | public PagerSlidingTabStrip(Context context, AttributeSet attrs) { 115 | this(context, attrs, 0); 116 | } 117 | 118 | public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) { 119 | super(context, attrs, defStyle); 120 | setFillViewport(true); 121 | setWillNotDraw(false); 122 | mTabsContainer = new LinearLayout(context); 123 | mTabsContainer.setOrientation(LinearLayout.HORIZONTAL); 124 | addView(mTabsContainer); 125 | 126 | mRectPaint = new Paint(); 127 | mRectPaint.setAntiAlias(true); 128 | mRectPaint.setStyle(Style.FILL); 129 | 130 | DisplayMetrics dm = getResources().getDisplayMetrics(); 131 | mScrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mScrollOffset, dm); 132 | mIndicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mIndicatorHeight, dm); 133 | mUnderlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mUnderlineHeight, dm); 134 | mDividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mDividerPadding, dm); 135 | mTabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mTabPadding, dm); 136 | mDividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mDividerWidth, dm); 137 | mTabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mTabTextSize, dm); 138 | 139 | mDividerPaint = new Paint(); 140 | mDividerPaint.setAntiAlias(true); 141 | mDividerPaint.setStrokeWidth(mDividerWidth); 142 | 143 | // get system attrs for container 144 | TypedArray a = context.obtainStyledAttributes(attrs, ANDROID_ATTRS); 145 | int textPrimaryColor = a.getColor(TEXT_COLOR_PRIMARY, ContextCompat.getColor(context, android.R.color.black)); 146 | mUnderlineColor = textPrimaryColor; 147 | mDividerColor = textPrimaryColor; 148 | mIndicatorColor = textPrimaryColor; 149 | int padding = a.getDimensionPixelSize(PADDING_INDEX, 0); 150 | mPaddingLeft = padding > 0 ? padding : a.getDimensionPixelSize(PADDING_LEFT_INDEX, 0); 151 | mPaddingRight = padding > 0 ? padding : a.getDimensionPixelSize(PADDING_RIGHT_INDEX, 0); 152 | a.recycle(); 153 | 154 | String tabTextTypefaceName = "sans-serif"; 155 | // Use Roboto Medium as the default typeface from API 21 onwards 156 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 157 | tabTextTypefaceName = "sans-serif-medium"; 158 | mTabTextTypefaceStyle = Typeface.NORMAL; 159 | } 160 | 161 | // get custom attrs for tabs and container 162 | a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip); 163 | mIndicatorColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsIndicatorColor, mIndicatorColor); 164 | mIndicatorHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight, mIndicatorHeight); 165 | mUnderlineColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsUnderlineColor, mUnderlineColor); 166 | mUnderlineHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight, mUnderlineHeight); 167 | mDividerColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsDividerColor, mDividerColor); 168 | mDividerWidth = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerWidth, mDividerWidth); 169 | mDividerPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerPadding, mDividerPadding); 170 | isExpandTabs = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsShouldExpand, isExpandTabs); 171 | mScrollOffset = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsScrollOffset, mScrollOffset); 172 | isPaddingMiddle = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsPaddingMiddle, isPaddingMiddle); 173 | mTabPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight, mTabPadding); 174 | mTabBackgroundResId = a.getResourceId(R.styleable.PagerSlidingTabStrip_pstsTabBackground, mTabBackgroundResId); 175 | mTabTextSize = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabTextSize, mTabTextSize); 176 | mTabTextColor = a.hasValue(R.styleable.PagerSlidingTabStrip_pstsTabTextColor) ? a.getColorStateList(R.styleable.PagerSlidingTabStrip_pstsTabTextColor) : null; 177 | mTabTextTypefaceStyle = a.getInt(R.styleable.PagerSlidingTabStrip_pstsTabTextStyle, mTabTextTypefaceStyle); 178 | isTabTextAllCaps = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsTabTextAllCaps, isTabTextAllCaps); 179 | int tabTextAlpha = a.getInt(R.styleable.PagerSlidingTabStrip_pstsTabTextAlpha, DEF_VALUE_TAB_TEXT_ALPHA); 180 | String fontFamily = a.getString(R.styleable.PagerSlidingTabStrip_pstsTabTextFontFamily); 181 | a.recycle(); 182 | 183 | //Tab text color selector 184 | if (mTabTextColor == null) { 185 | mTabTextColor = createColorStateList( 186 | textPrimaryColor, 187 | textPrimaryColor, 188 | Color.argb(tabTextAlpha, 189 | Color.red(textPrimaryColor), 190 | Color.green(textPrimaryColor), 191 | Color.blue(textPrimaryColor))); 192 | } 193 | 194 | //Tab text typeface and style 195 | if (fontFamily != null) { 196 | tabTextTypefaceName = fontFamily; 197 | } 198 | mTabTextTypeface = Typeface.create(tabTextTypefaceName, mTabTextTypefaceStyle); 199 | 200 | //Bottom padding for the tabs container parent view to show indicator and underline 201 | setTabsContainerParentViewPaddings(); 202 | 203 | //Configure tab's container LayoutParams for either equal divided space or just wrap tabs 204 | mTabLayoutParams = isExpandTabs ? 205 | new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f) : 206 | new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); 207 | } 208 | 209 | private void setTabsContainerParentViewPaddings() { 210 | int bottomMargin = mIndicatorHeight >= mUnderlineHeight ? mIndicatorHeight : mUnderlineHeight; 211 | setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), bottomMargin); 212 | } 213 | 214 | public void setViewPager(ViewPager pager) { 215 | this.mPager = pager; 216 | if (pager.getAdapter() == null) { 217 | throw new IllegalStateException("ViewPager does not have adapter instance."); 218 | } 219 | 220 | isCustomTabs = pager.getAdapter() instanceof CustomTabProvider; 221 | pager.addOnPageChangeListener(mPageListener); 222 | pager.getAdapter().registerDataSetObserver(mAdapterObserver); 223 | mAdapterObserver.setAttached(true); 224 | notifyDataSetChanged(); 225 | } 226 | 227 | public void notifyDataSetChanged() { 228 | mTabsContainer.removeAllViews(); 229 | mTabCount = mPager.getAdapter().getCount(); 230 | View tabView; 231 | for (int i = 0; i < mTabCount; i++) { 232 | if (isCustomTabs) { 233 | tabView = ((CustomTabProvider) mPager.getAdapter()).getCustomTabView(this, i); 234 | } else { 235 | tabView = LayoutInflater.from(getContext()).inflate(R.layout.psts_tab, this, false); 236 | } 237 | 238 | CharSequence title = mPager.getAdapter().getPageTitle(i); 239 | addTab(i, title, tabView); 240 | } 241 | 242 | updateTabStyles(); 243 | } 244 | 245 | private void addTab(final int position, CharSequence title, View tabView) { 246 | TextView textView = (TextView) tabView.findViewById(R.id.psts_tab_title); 247 | if (textView != null) { 248 | if (title != null) textView.setText(title); 249 | } 250 | 251 | tabView.setFocusable(true); 252 | tabView.setOnClickListener(new OnClickListener() { 253 | @Override 254 | public void onClick(View v) { 255 | if (mPager.getCurrentItem() != position) { 256 | View tab = mTabsContainer.getChildAt(mPager.getCurrentItem()); 257 | unSelect(tab); 258 | mPager.setCurrentItem(position); 259 | } else if (mTabReselectedListener != null) { 260 | mTabReselectedListener.onTabReselected(position); 261 | } 262 | } 263 | }); 264 | 265 | mTabsContainer.addView(tabView, position, mTabLayoutParams); 266 | } 267 | 268 | private void updateTabStyles() { 269 | for (int i = 0; i < mTabCount; i++) { 270 | View v = mTabsContainer.getChildAt(i); 271 | v.setBackgroundResource(mTabBackgroundResId); 272 | v.setPadding(mTabPadding, v.getPaddingTop(), mTabPadding, v.getPaddingBottom()); 273 | TextView tab_title = (TextView) v.findViewById(R.id.psts_tab_title); 274 | if (tab_title != null) { 275 | tab_title.setTextColor(mTabTextColor); 276 | tab_title.setTypeface(mTabTextTypeface, mTabTextTypefaceStyle); 277 | tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTabTextSize); 278 | // setAllCaps() is only available from API 14, so the upper case is made manually if we are on a 279 | // pre-ICS-build 280 | if (isTabTextAllCaps) { 281 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 282 | tab_title.setAllCaps(true); 283 | } else { 284 | tab_title.setText(tab_title.getText().toString().toUpperCase()); 285 | } 286 | } 287 | } 288 | } 289 | } 290 | 291 | private void scrollToChild(int position, int offset) { 292 | if (mTabCount == 0) { 293 | return; 294 | } 295 | 296 | int newScrollX = mTabsContainer.getChildAt(position).getLeft() + offset; 297 | if (position > 0 || offset > 0) { 298 | //Half screen offset. 299 | //- Either tabs start at the middle of the view scrolling straight away 300 | //- Or tabs start at the begging (no padding) scrolling when indicator gets 301 | // to the middle of the view width 302 | newScrollX -= mScrollOffset; 303 | Pair lines = getIndicatorCoordinates(); 304 | newScrollX += ((lines.second - lines.first) / 2); 305 | } 306 | 307 | if (newScrollX != mLastScrollX) { 308 | mLastScrollX = newScrollX; 309 | scrollTo(newScrollX, 0); 310 | } 311 | } 312 | 313 | public Pair getIndicatorCoordinates() { 314 | // default: line below current tab 315 | View currentTab = mTabsContainer.getChildAt(mCurrentPosition); 316 | float lineLeft = currentTab.getLeft(); 317 | float lineRight = currentTab.getRight(); 318 | // if there is an offset, start interpolating left and right coordinates between current and next tab 319 | if (mCurrentPositionOffset > 0f && mCurrentPosition < mTabCount - 1) { 320 | View nextTab = mTabsContainer.getChildAt(mCurrentPosition + 1); 321 | final float nextTabLeft = nextTab.getLeft(); 322 | final float nextTabRight = nextTab.getRight(); 323 | lineLeft = (mCurrentPositionOffset * nextTabLeft + (1f - mCurrentPositionOffset) * lineLeft); 324 | lineRight = (mCurrentPositionOffset * nextTabRight + (1f - mCurrentPositionOffset) * lineRight); 325 | } 326 | 327 | return new Pair<>(lineLeft, lineRight); 328 | } 329 | 330 | @Override 331 | protected void onLayout(boolean changed, int l, int t, int r, int b) { 332 | if (isPaddingMiddle && mTabsContainer.getChildCount() > 0) { 333 | View view = mTabsContainer.getChildAt(0); 334 | int halfWidthFirstTab = view.getMeasuredWidth() / 2; 335 | mPaddingLeft = mPaddingRight = getWidth() / 2 - halfWidthFirstTab; 336 | } 337 | 338 | if (isPaddingMiddle || mPaddingLeft > 0 || mPaddingRight > 0) { 339 | int width; 340 | if (isPaddingMiddle) { 341 | width = getWidth(); 342 | } else { 343 | // Account for manually set padding for offsetting tab start and end positions. 344 | width = getWidth() - mPaddingLeft - mPaddingRight; 345 | } 346 | 347 | //Make sure tabContainer is bigger than the HorizontalScrollView to be able to scroll 348 | mTabsContainer.setMinimumWidth(width); 349 | //Clipping padding to false to see the tabs while we pass them swiping 350 | setClipToPadding(false); 351 | } 352 | 353 | setPadding(mPaddingLeft, getPaddingTop(), mPaddingRight, getPaddingBottom()); 354 | if (mScrollOffset == 0) { 355 | mScrollOffset = getWidth() / 2 - mPaddingLeft; 356 | } 357 | 358 | if (mPager != null) { 359 | mCurrentPosition = mPager.getCurrentItem(); 360 | } 361 | 362 | mCurrentPositionOffset = 0f; 363 | scrollToChild(mCurrentPosition, 0); 364 | updateSelection(mCurrentPosition); 365 | super.onLayout(changed, l, t, r, b); 366 | } 367 | 368 | @Override 369 | protected void onDraw(Canvas canvas) { 370 | super.onDraw(canvas); 371 | if (isInEditMode() || mTabCount == 0) { 372 | return; 373 | } 374 | 375 | final int height = getHeight(); 376 | // draw divider 377 | if (mDividerWidth > 0) { 378 | mDividerPaint.setStrokeWidth(mDividerWidth); 379 | mDividerPaint.setColor(mDividerColor); 380 | for (int i = 0; i < mTabCount - 1; i++) { 381 | View tab = mTabsContainer.getChildAt(i); 382 | canvas.drawLine(tab.getRight(), mDividerPadding, tab.getRight(), height - mDividerPadding, mDividerPaint); 383 | } 384 | } 385 | 386 | // draw underline 387 | if (mUnderlineHeight > 0) { 388 | mRectPaint.setColor(mUnderlineColor); 389 | canvas.drawRect(mPaddingLeft, height - mUnderlineHeight, mTabsContainer.getWidth() + mPaddingRight, height, mRectPaint); 390 | } 391 | 392 | // draw indicator line 393 | if (mIndicatorHeight > 0) { 394 | mRectPaint.setColor(mIndicatorColor); 395 | Pair lines = getIndicatorCoordinates(); 396 | canvas.drawRect(lines.first + mPaddingLeft, height - mIndicatorHeight, lines.second + mPaddingLeft, height, mRectPaint); 397 | } 398 | } 399 | 400 | public void setOnTabReselectedListener(OnTabReselectedListener tabReselectedListener) { 401 | this.mTabReselectedListener = tabReselectedListener; 402 | } 403 | 404 | public void setOnPageChangeListener(OnPageChangeListener listener) { 405 | this.mDelegatePageListener = listener; 406 | } 407 | 408 | private class PageListener implements OnPageChangeListener { 409 | 410 | @Override 411 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 412 | mCurrentPosition = position; 413 | mCurrentPositionOffset = positionOffset; 414 | int offset = mTabCount > 0 ? (int) (positionOffset * mTabsContainer.getChildAt(position).getWidth()) : 0; 415 | scrollToChild(position, offset); 416 | invalidate(); 417 | if (mDelegatePageListener != null) { 418 | mDelegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels); 419 | } 420 | } 421 | 422 | @Override 423 | public void onPageScrollStateChanged(int state) { 424 | if (state == ViewPager.SCROLL_STATE_IDLE) { 425 | scrollToChild(mPager.getCurrentItem(), 0); 426 | } 427 | if (mDelegatePageListener != null) { 428 | mDelegatePageListener.onPageScrollStateChanged(state); 429 | } 430 | } 431 | 432 | @Override 433 | public void onPageSelected(int position) { 434 | updateSelection(position); 435 | 436 | //Select current item 437 | View currentTab = mTabsContainer.getChildAt(position); 438 | select(currentTab); 439 | //Unselect prev item 440 | if (position > 0) { 441 | View prevTab = mTabsContainer.getChildAt(position - 1); 442 | unSelect(prevTab); 443 | } 444 | //Unselect next item 445 | if (position < mPager.getAdapter().getCount() - 1) { 446 | View nextTab = mTabsContainer.getChildAt(position + 1); 447 | unSelect(nextTab); 448 | } 449 | 450 | if (mDelegatePageListener != null) { 451 | mDelegatePageListener.onPageSelected(position); 452 | } 453 | } 454 | 455 | } 456 | 457 | private void updateSelection(int position) { 458 | for (int i = 0; i < mTabCount; ++i) { 459 | View tv = mTabsContainer.getChildAt(i); 460 | final boolean selected = i == position; 461 | if (selected) { 462 | select(tv); 463 | } else { 464 | unSelect(tv); 465 | } 466 | } 467 | } 468 | 469 | private void unSelect(View tab) { 470 | if (tab != null) { 471 | TextView tab_title = (TextView) tab.findViewById(R.id.psts_tab_title); 472 | if (tab_title != null) { 473 | tab_title.setSelected(false); 474 | } 475 | if (isCustomTabs) ((CustomTabProvider) mPager.getAdapter()).tabUnselected(tab); 476 | } 477 | } 478 | 479 | private void select(View tab) { 480 | if (tab != null) { 481 | TextView tab_title = (TextView) tab.findViewById(R.id.psts_tab_title); 482 | if (tab_title != null) { 483 | tab_title.setSelected(true); 484 | } 485 | if (isCustomTabs) ((CustomTabProvider) mPager.getAdapter()).tabSelected(tab); 486 | } 487 | } 488 | 489 | private class PagerAdapterObserver extends DataSetObserver { 490 | 491 | private boolean attached = false; 492 | 493 | @Override 494 | public void onChanged() { 495 | notifyDataSetChanged(); 496 | } 497 | 498 | void setAttached(boolean attached) { 499 | this.attached = attached; 500 | } 501 | 502 | boolean isAttached() { 503 | return attached; 504 | } 505 | } 506 | 507 | @Override 508 | protected void onAttachedToWindow() { 509 | super.onAttachedToWindow(); 510 | if (mPager != null) { 511 | if (!mAdapterObserver.isAttached()) { 512 | mPager.getAdapter().registerDataSetObserver(mAdapterObserver); 513 | mAdapterObserver.setAttached(true); 514 | } 515 | } 516 | } 517 | 518 | @Override 519 | protected void onDetachedFromWindow() { 520 | super.onDetachedFromWindow(); 521 | if (mPager != null) { 522 | if (mAdapterObserver.isAttached()) { 523 | mPager.getAdapter().unregisterDataSetObserver(mAdapterObserver); 524 | mAdapterObserver.setAttached(false); 525 | } 526 | } 527 | } 528 | 529 | @Override 530 | public void onRestoreInstanceState(Parcelable state) { 531 | SavedState savedState = (SavedState) state; 532 | super.onRestoreInstanceState(savedState.getSuperState()); 533 | mCurrentPosition = savedState.currentPosition; 534 | if (mCurrentPosition != 0 && mTabsContainer.getChildCount() > 0) { 535 | unSelect(mTabsContainer.getChildAt(0)); 536 | select(mTabsContainer.getChildAt(mCurrentPosition)); 537 | } 538 | requestLayout(); 539 | } 540 | 541 | @Override 542 | public Parcelable onSaveInstanceState() { 543 | Parcelable superState = super.onSaveInstanceState(); 544 | SavedState savedState = new SavedState(superState); 545 | savedState.currentPosition = mCurrentPosition; 546 | return savedState; 547 | } 548 | 549 | static class SavedState extends BaseSavedState { 550 | int currentPosition; 551 | 552 | SavedState(Parcelable superState) { 553 | super(superState); 554 | } 555 | 556 | private SavedState(Parcel in) { 557 | super(in); 558 | currentPosition = in.readInt(); 559 | } 560 | 561 | @Override 562 | public void writeToParcel(Parcel dest, int flags) { 563 | super.writeToParcel(dest, flags); 564 | dest.writeInt(currentPosition); 565 | } 566 | 567 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 568 | @Override 569 | public SavedState createFromParcel(Parcel in) { 570 | return new SavedState(in); 571 | } 572 | 573 | @Override 574 | public SavedState[] newArray(int size) { 575 | return new SavedState[size]; 576 | } 577 | }; 578 | } 579 | 580 | public int getIndicatorColor() { 581 | return this.mIndicatorColor; 582 | } 583 | 584 | public int getIndicatorHeight() { 585 | return mIndicatorHeight; 586 | } 587 | 588 | public int getUnderlineColor() { 589 | return mUnderlineColor; 590 | } 591 | 592 | public int getDividerColor() { 593 | return mDividerColor; 594 | } 595 | 596 | public int getDividerWidth() { 597 | return mDividerWidth; 598 | } 599 | 600 | public int getUnderlineHeight() { 601 | return mUnderlineHeight; 602 | } 603 | 604 | public int getDividerPadding() { 605 | return mDividerPadding; 606 | } 607 | 608 | public int getScrollOffset() { 609 | return mScrollOffset; 610 | } 611 | 612 | public boolean getShouldExpand() { 613 | return isExpandTabs; 614 | } 615 | 616 | public int getTextSize() { 617 | return mTabTextSize; 618 | } 619 | 620 | public boolean isTextAllCaps() { 621 | return isTabTextAllCaps; 622 | } 623 | 624 | public ColorStateList getTextColor() { 625 | return mTabTextColor; 626 | } 627 | 628 | public int getTabBackground() { 629 | return mTabBackgroundResId; 630 | } 631 | 632 | public int getTabPaddingLeftRight() { 633 | return mTabPadding; 634 | } 635 | 636 | public LinearLayout getTabsContainer() { 637 | return mTabsContainer; 638 | } 639 | 640 | public int getTabCount() { 641 | return mTabCount; 642 | } 643 | 644 | public int getCurrentPosition() { 645 | return mCurrentPosition; 646 | } 647 | 648 | public float getCurrentPositionOffset() { 649 | return mCurrentPositionOffset; 650 | } 651 | 652 | public void setIndicatorColor(int indicatorColor) { 653 | this.mIndicatorColor = indicatorColor; 654 | invalidate(); 655 | } 656 | 657 | public void setIndicatorColorResource(int resId) { 658 | this.mIndicatorColor = ContextCompat.getColor(getContext(), resId); 659 | invalidate(); 660 | } 661 | 662 | public void setIndicatorHeight(int indicatorLineHeightPx) { 663 | this.mIndicatorHeight = indicatorLineHeightPx; 664 | invalidate(); 665 | } 666 | 667 | public void setUnderlineColor(int underlineColor) { 668 | this.mUnderlineColor = underlineColor; 669 | invalidate(); 670 | } 671 | 672 | public void setUnderlineColorResource(int resId) { 673 | this.mUnderlineColor = ContextCompat.getColor(getContext(), resId); 674 | invalidate(); 675 | } 676 | 677 | public void setDividerColor(int dividerColor) { 678 | this.mDividerColor = dividerColor; 679 | invalidate(); 680 | } 681 | 682 | public void setDividerColorResource(int resId) { 683 | this.mDividerColor = ContextCompat.getColor(getContext(), resId); 684 | invalidate(); 685 | } 686 | 687 | public void setDividerWidth(int dividerWidthPx) { 688 | this.mDividerWidth = dividerWidthPx; 689 | invalidate(); 690 | } 691 | 692 | public void setUnderlineHeight(int underlineHeightPx) { 693 | this.mUnderlineHeight = underlineHeightPx; 694 | invalidate(); 695 | } 696 | 697 | public void setDividerPadding(int dividerPaddingPx) { 698 | this.mDividerPadding = dividerPaddingPx; 699 | invalidate(); 700 | } 701 | 702 | public void setScrollOffset(int scrollOffsetPx) { 703 | this.mScrollOffset = scrollOffsetPx; 704 | invalidate(); 705 | } 706 | 707 | public void setShouldExpand(boolean shouldExpand) { 708 | this.isExpandTabs = shouldExpand; 709 | if (mPager != null) { 710 | requestLayout(); 711 | } 712 | } 713 | 714 | public void setAllCaps(boolean textAllCaps) { 715 | this.isTabTextAllCaps = textAllCaps; 716 | } 717 | 718 | public void setTextSize(int textSizePx) { 719 | this.mTabTextSize = textSizePx; 720 | updateTabStyles(); 721 | } 722 | 723 | public void setTextColorResource(int resId) { 724 | setTextColor(ContextCompat.getColor(getContext(), resId)); 725 | } 726 | 727 | public void setTextColor(int textColor) { 728 | setTextColor(createColorStateList(textColor)); 729 | } 730 | 731 | public void setTextColorStateListResource(int resId) { 732 | setTextColor(ContextCompat.getColorStateList(getContext(), resId)); 733 | } 734 | 735 | public void setTextColor(ColorStateList colorStateList) { 736 | this.mTabTextColor = colorStateList; 737 | updateTabStyles(); 738 | } 739 | 740 | private ColorStateList createColorStateList(int color_state_default) { 741 | return new ColorStateList( 742 | new int[][]{ 743 | new int[]{} //default 744 | }, 745 | new int[]{ 746 | color_state_default //default 747 | } 748 | ); 749 | } 750 | 751 | private ColorStateList createColorStateList(int color_state_pressed, int color_state_selected, int color_state_default) { 752 | return new ColorStateList( 753 | new int[][]{ 754 | new int[]{android.R.attr.state_pressed}, //pressed 755 | new int[]{android.R.attr.state_selected}, // enabled 756 | new int[]{} //default 757 | }, 758 | new int[]{ 759 | color_state_pressed, 760 | color_state_selected, 761 | color_state_default 762 | } 763 | ); 764 | } 765 | 766 | public void setTypeface(Typeface typeface, int style) { 767 | this.mTabTextTypeface = typeface; 768 | this.mTabTextTypefaceStyle = style; 769 | updateTabStyles(); 770 | } 771 | 772 | public void setTabBackground(int resId) { 773 | this.mTabBackgroundResId = resId; 774 | } 775 | 776 | public void setTabPaddingLeftRight(int paddingPx) { 777 | this.mTabPadding = paddingPx; 778 | updateTabStyles(); 779 | } 780 | 781 | public interface CustomTabProvider { 782 | View getCustomTabView(ViewGroup parent, int position); 783 | 784 | void tabSelected(View tab); 785 | 786 | void tabUnselected(View tab); 787 | } 788 | 789 | public interface OnTabReselectedListener { 790 | void onTabReselected(int position); 791 | } 792 | } 793 | -------------------------------------------------------------------------------- /sample/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /sample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'android-apt' 3 | 4 | repositories { 5 | maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } 6 | mavenCentral() 7 | } 8 | 9 | 10 | dependencies { 11 | compile project(':library') 12 | compile "com.android.support:appcompat-v7:24.2.0" 13 | compile 'com.android.support:cardview-v7:24.2.0' 14 | compile 'com.jakewharton:butterknife:8.4.0' 15 | apt 'com.jakewharton:butterknife-compiler:8.4.0' 16 | compile 'com.readystatesoftware.systembartint:systembartint:1.0.3' 17 | compile 'com.nineoldandroids:library:2.4.0' 18 | } 19 | 20 | android { 21 | compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION) 22 | buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION 23 | 24 | defaultConfig { 25 | minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION) 26 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION) 27 | 28 | versionName project.SAMPLE_VERSION_NAME 29 | versionCode Integer.parseInt(project.SAMPLE_VERSION_CODE) 30 | } 31 | 32 | signingConfigs { release } 33 | 34 | buildTypes { 35 | release { 36 | signingConfig signingConfigs.release 37 | } 38 | } 39 | 40 | sourceSets { 41 | main { 42 | manifest.srcFile 'AndroidManifest.xml' 43 | java.srcDirs = ['src'] 44 | res.srcDirs = ['res'] 45 | } 46 | } 47 | 48 | android { 49 | lintOptions { 50 | abortOnError false 51 | } 52 | } 53 | } 54 | 55 | File propFile = file('signing.properties'); 56 | if (propFile.exists()) { 57 | def Properties props = new Properties() 58 | props.load(new FileInputStream(propFile)) 59 | 60 | if (props.containsKey('STORE_FILE') && props.containsKey('STORE_PASSWORD') && 61 | props.containsKey('KEY_ALIAS') && props.containsKey('KEY_PASSWORD')) { 62 | android.signingConfigs.release.storeFile = file(props['STORE_FILE']) 63 | android.signingConfigs.release.storePassword = props['STORE_PASSWORD'] 64 | android.signingConfigs.release.keyAlias = props['KEY_ALIAS'] 65 | android.signingConfigs.release.keyPassword = props['KEY_PASSWORD'] 66 | } else { 67 | android.buildTypes.release.signingConfig = null 68 | } 69 | } else { 70 | android.buildTypes.release.signingConfig = null 71 | } 72 | -------------------------------------------------------------------------------- /sample/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/ic_launcher-web.png -------------------------------------------------------------------------------- /sample/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-19 15 | android.library.reference.1=../library 16 | -------------------------------------------------------------------------------- /sample/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/res/drawable-hdpi/ic_launcher_actionbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-hdpi/ic_launcher_actionbar.png -------------------------------------------------------------------------------- /sample/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/res/drawable-mdpi/ic_launcher_actionbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-mdpi/ic_launcher_actionbar.png -------------------------------------------------------------------------------- /sample/res/drawable-xhdpi/actionbar_bottom.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-xhdpi/actionbar_bottom.9.png -------------------------------------------------------------------------------- /sample/res/drawable-xhdpi/background_card.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-xhdpi/background_card.9.png -------------------------------------------------------------------------------- /sample/res/drawable-xhdpi/contact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-xhdpi/contact.png -------------------------------------------------------------------------------- /sample/res/drawable-xhdpi/ic_action_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-xhdpi/ic_action_user.png -------------------------------------------------------------------------------- /sample/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/res/drawable-xhdpi/ic_launcher_actionbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-xhdpi/ic_launcher_actionbar.png -------------------------------------------------------------------------------- /sample/res/drawable-xhdpi/ic_launcher_chrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-xhdpi/ic_launcher_chrome.png -------------------------------------------------------------------------------- /sample/res/drawable-xhdpi/ic_launcher_gmail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-xhdpi/ic_launcher_gmail.png -------------------------------------------------------------------------------- /sample/res/drawable-xhdpi/ic_launcher_gmaps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-xhdpi/ic_launcher_gmaps.png -------------------------------------------------------------------------------- /sample/res/drawable-xhdpi/ic_launcher_gplus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-xhdpi/ic_launcher_gplus.png -------------------------------------------------------------------------------- /sample/res/drawable-xhdpi/tabs_pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-xhdpi/tabs_pattern.png -------------------------------------------------------------------------------- /sample/res/drawable-xhdpi/tabs_pattern_diagonal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-xhdpi/tabs_pattern_diagonal.png -------------------------------------------------------------------------------- /sample/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/res/drawable-xxhdpi/ic_launcher_actionbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpardogo/PagerSlidingTabStrip/ab32788bda2742764871aea764c5aa3f038d1ace/sample/res/drawable-xxhdpi/ic_launcher_actionbar.png -------------------------------------------------------------------------------- /sample/res/drawable/background_tabs.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /sample/res/drawable/background_tabs_diagonal.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /sample/res/layout-land/fragment_quick_contact.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 16 | 17 | 30 | 31 | 36 | 37 | 48 | 49 | 56 | 57 | -------------------------------------------------------------------------------- /sample/res/layout-v11/custom_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 20 | -------------------------------------------------------------------------------- /sample/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 14 | 15 | 21 | 22 | 30 | 31 | 39 | 40 | 48 | 49 | 57 | 58 | 66 | 67 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /sample/res/layout/custom_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 21 | -------------------------------------------------------------------------------- /sample/res/layout/fragment_card.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | 23 | 24 | -------------------------------------------------------------------------------- /sample/res/layout/fragment_quick_contact.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12 | 13 | 24 | 25 | 31 | 32 | 37 | 38 | -------------------------------------------------------------------------------- /sample/res/layout/fragment_quickcontact.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /sample/res/layout/toolbar.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /sample/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /sample/res/values-sw600dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /sample/res/values-sw720dp-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 128dp 8 | 9 | -------------------------------------------------------------------------------- /sample/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /sample/res/values-v11/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /sample/res/values-v19/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /sample/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFE5E5E5 4 | #689F38 5 | #3E5F22 6 | #FFCC00 7 | -------------------------------------------------------------------------------- /sample/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | -------------------------------------------------------------------------------- /sample/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | PagerSlidingTabStrip 5 | Contact 6 | 7 | -------------------------------------------------------------------------------- /sample/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 |