├── .gitignore
├── LICENSE.md
├── README.md
├── build.gradle
├── device-2015-05-04-090851.png
├── device-2015-05-04-090914.png
├── device-2015-05-04-090952.png
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── library
├── AndroidManifest.xml
├── build.gradle
├── res
│ ├── layout
│ │ └── mt_tab.xml
│ └── values
│ │ └── attrs.xml
└── src
│ └── io
│ └── karim
│ ├── MaterialRippleLayout.java
│ ├── MaterialTabs.java
│ └── Utils.java
├── sample
├── AndroidManifest.xml
├── build.gradle
├── res
│ ├── drawable-hdpi
│ │ ├── ic_action_content_clear.png
│ │ ├── ic_action_github.png
│ │ ├── ic_action_info_outline.png
│ │ ├── ic_action_navigation_arrow_forward.png
│ │ ├── ic_action_social_mood.png
│ │ ├── ic_action_social_share.png
│ │ ├── ic_action_twitter.png
│ │ ├── ic_navigation_arrow_back_white.png
│ │ ├── ic_ripple_selected.png
│ │ ├── ic_ripple_unselected.png
│ │ ├── ic_tabs_selected.png
│ │ ├── ic_tabs_unselected.png
│ │ ├── ic_toggle_check_box_dark.png
│ │ └── ic_toggle_check_box_light.png
│ ├── drawable-mdpi
│ │ ├── ic_action_content_clear.png
│ │ ├── ic_action_github.png
│ │ ├── ic_action_info_outline.png
│ │ ├── ic_action_navigation_arrow_forward.png
│ │ ├── ic_action_social_mood.png
│ │ ├── ic_action_social_share.png
│ │ ├── ic_action_twitter.png
│ │ ├── ic_navigation_arrow_back_white.png
│ │ ├── ic_ripple_selected.png
│ │ ├── ic_ripple_unselected.png
│ │ ├── ic_tabs_selected.png
│ │ ├── ic_tabs_unselected.png
│ │ ├── ic_toggle_check_box_dark.png
│ │ └── ic_toggle_check_box_light.png
│ ├── drawable-xhdpi
│ │ ├── ic_action_content_clear.png
│ │ ├── ic_action_github.png
│ │ ├── ic_action_info_outline.png
│ │ ├── ic_action_navigation_arrow_forward.png
│ │ ├── ic_action_social_mood.png
│ │ ├── ic_action_social_share.png
│ │ ├── ic_action_twitter.png
│ │ ├── ic_navigation_arrow_back_blue.png
│ │ ├── ic_ripple_selected.png
│ │ ├── ic_ripple_unselected.png
│ │ ├── ic_tabs_selected.png
│ │ ├── ic_tabs_unselected.png
│ │ ├── ic_toggle_check_box_dark.png
│ │ └── ic_toggle_check_box_light.png
│ ├── drawable-xxhdpi
│ │ ├── ic_action_content_clear.png
│ │ ├── ic_action_github.png
│ │ ├── ic_action_info_outline.png
│ │ ├── ic_action_navigation_arrow_forward.png
│ │ ├── ic_action_social_mood.png
│ │ ├── ic_action_social_share.png
│ │ ├── ic_action_twitter.png
│ │ ├── ic_navigation_arrow_back_white.png
│ │ ├── ic_ripple_selected.png
│ │ ├── ic_ripple_unselected.png
│ │ ├── ic_tabs_selected.png
│ │ ├── ic_tabs_unselected.png
│ │ ├── ic_toggle_check_box_dark.png
│ │ └── ic_toggle_check_box_light.png
│ ├── drawable-xxxhdpi
│ │ ├── ic_action_content_clear.png
│ │ ├── ic_action_github.png
│ │ ├── ic_action_info_outline.png
│ │ ├── ic_action_navigation_arrow_forward.png
│ │ ├── ic_action_social_mood.png
│ │ ├── ic_action_social_share.png
│ │ ├── ic_action_twitter.png
│ │ ├── ic_navigation_arrow_back_white.png
│ │ ├── ic_ripple_selected.png
│ │ ├── ic_ripple_unselected.png
│ │ ├── ic_tabs_selected.png
│ │ ├── ic_tabs_unselected.png
│ │ ├── ic_toggle_check_box_dark.png
│ │ ├── ic_toggle_check_box_light.png
│ │ └── me.jpg
│ ├── drawable
│ │ ├── radio_button_dark.xml
│ │ └── radio_button_light.xml
│ ├── layout
│ │ ├── activity_tabs.xml
│ │ ├── dialog_me.xml
│ │ ├── fragment_card.xml
│ │ ├── fragment_ripple_settings.xml
│ │ ├── fragment_tabs_settings.xml
│ │ └── toolbar.xml
│ ├── menu
│ │ ├── menu_main.xml
│ │ └── menu_tabs.xml
│ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ ├── resize_xxxhdpi_pictures_to_other_dpis.sh
│ ├── values-v19
│ │ └── themes.xml
│ ├── values-v20
│ │ └── themes.xml
│ └── values
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── themes.xml
├── sample-release.apk
├── src
│ └── io
│ │ └── karim
│ │ └── materialtabs
│ │ └── sample
│ │ ├── MainActivity.java
│ │ ├── MyApplication.java
│ │ ├── ResettableFragment.java
│ │ ├── RippleSettingsFragment.java
│ │ ├── SampleFragment.java
│ │ ├── TabsActivity.java
│ │ ├── TabsSettingsFragment.java
│ │ └── ui
│ │ └── RadioButtonCenter.java
└── web_hi_res_512.png
└── 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
37 | fabric.properties
38 | material_tabs_sample_keystore.jks
39 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Karim Frenn
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MaterialTabs
2 |
3 | [](http://android-arsenal.com/details/1/1874)
4 |
5 | An easy-to-integrate tab bar for Android that completely respects the [Material Design guidelines] (http://www.google.com/design/spec/components/tabs.html) and **supports all versions of Android since API 9**!
6 |
7 | If you think that this library does not fully respect the Material Design guidelines, file an issue, send a pull request or reach out to me! The goal of this library is to be 100% MaterialDesign-compliant.
8 |
9 |
10 |
11 | ## Sample
12 |
13 | You can find a sample app showing what this library can do on the Google Play Store.
14 | **This sample can also generate the XML code you need instantly and export it!** You can then copy paste it in your corresponding layout XML file. Done!
15 |
16 |
17 |
18 |
19 |
20 | ## Download
21 |
22 | Download the [latest AAR](http://search.maven.org/remotecontent?filepath=io/karim/materialtabs/2.0.5/materialtabs-2.0.5.aar) or add the following dependency in your **build.gradle** file:
23 |
24 | ```groovy
25 | dependencies {
26 | compile 'io.karim:materialtabs:2.0.5'
27 | }
28 | ```
29 |
30 | ## Usage
31 |
32 | 1. Add the MaterialTabs widget (io.karim.MaterialTabs) in your `layout.xml` file:
33 |
34 | ```xml
35 |
42 | ```
43 | Normally, this should go below a Toolbar (android.support.v7.widget.Toolbar) and above a ViewPager (android.support.v4.view.ViewPager).
44 | Take a look at [this file] (https://github.com/pizza/MaterialTabs/blob/master/sample/res/layout/activity_tabs.xml) for a better understanding.
45 |
46 | 2. In your onCreate method (or onCreateView for a fragment), bind the widget to the ViewPager:
47 |
48 | ```java
49 | // Initialize the ViewPager and set an adapter
50 | ViewPager pager = (ViewPager) findViewById(R.id.pager);
51 | pager.setAdapter(new SamplePagerAdapter(getSupportFragmentManager()));
52 |
53 | // Bind the tabs to the ViewPager
54 | MaterialTabs tabs = (MaterialTabs) findViewById(R.id.tabs);
55 | tabs.setViewPager(pager);
56 | ```
57 |
58 | 3. Create a new class extending FragmentPagerAdapter, and take a look at the "Custom view" section for more info.
59 |
60 | ## Customization
61 |
62 | ### Custom view
63 |
64 | #### Just a TextView (titles)
65 | If you're looking for tabs with text, take a look at the `SamplePagerAdapter` in [this file] (https://github.com/pizza/MaterialTabs/blob/master/sample/src/io/karim/materialtabs/sample/TabsActivity.java#L331) for a better example.
66 |
67 | #### Everything else (icons and more complex views)
68 |
69 | Whether you're looking for tabs with icons instead of text or for more complex custom views, take a look at the `MainActivityPagerAdapter` in [this example](https://github.com/pizza/MaterialTabs/blob/master/sample/src/io/karim/materialtabs/sample/MainActivity.java#L152) instead.
70 |
71 | Specifically, make sure that your class implements `MaterialTabs.CustomTabProvider` and overrides the following methods:
72 |
73 | ```
74 | View getCustomTabView(ViewGroup parent, int position);
75 | void onCustomTabViewSelected(View view, int position, boolean alreadySelected);
76 | void onCustomTabViewUnselected(View view, int position, boolean alreadyUnselected);
77 | ```
78 |
79 | In the first one, create your View from scratch.
80 | In the second and third methods, write code that you want to run when a tab is selected and unselected. A common use case is to replace an icon with another icon when selected. This is exactly the use case demonstrated in the example linked above.
81 |
82 | *Note: these last two methods might be called several times even though the user just clicked on a tab once (for example). To deal with this case, the `alreadySelected` and `alreadyUnselected` boolean parameters specify if the corresponding tab was already selected or unselected respectively so that code that should only be executed once isn't executed more than once.*
83 |
84 | ### Custom font/typeface
85 |
86 | If you're using the default TextView (i.e. not using custom views) and would like to use a custom font in the tabs' title text, you can do so in your Java code by adding the last two lines just after binding the tabs to the ViewPager:
87 |
88 | ```java
89 | // Initialize the ViewPager and set an adapter
90 | ViewPager pager = (ViewPager) findViewById(R.id.pager);
91 | pager.setAdapter(new SamplePagerAdapter(getSupportFragmentManager()));
92 |
93 | // Bind the tabs to the ViewPager
94 | MaterialTabs tabs = (MaterialTabs) findViewById(R.id.tabs);
95 | tabs.setViewPager(pager);
96 |
97 | // Set custom font/typeface to text in tabs' title
98 | Typeface selectedTypeface = Typeface.createFromAsset(getAssets(), "fonts/Roboto-Bold.ttf");
99 | Typeface unselectedTypeface = Typeface.createFromAsset(getAssets(), "fonts/Roboto-Regular.ttf");
100 | tabs.setTypefaceSelected(selectedTypeface);
101 | tabs.setTypefaceUnselected(unselectedTypeface);
102 | ```
103 |
104 | For this to work, make sure to add your font file (in this case, `Roboto-Bold.ttf` and `Robot-Regular.ttf`) in the `fonts` folder under `assets`.
105 |
106 | ### Other customizations
107 |
108 | There are many attributes that you can override in the XML layout.
109 | Here is a table of these attributes, their descriptions and their default value:
110 |
111 | | Attribute | Description |
112 | | ------------- | ------------- |
113 | | android:textColor | Color of text in non-selected tabs |
114 | | app:mtIndicatorColor | Color of the sliding indicator |
115 | | app:mtUnderlineColor | Color of the full-width line on the bottom of the view |
116 | | app:mtIndicatorHeight | Height of the sliding indicator |
117 | | app:mtUnderlineHeight | Height of the full-width line on the bottom of the view |
118 | | app:mtTabPaddingLeftRight | Left and right padding of each tab |
119 | | app:mtSameWeightTabs | If set to true, each tab is given the same weight |
120 | | app:mtTextAllCaps | If true, all tab titles will be upper case |
121 | | app:mtPaddingMiddle | If true, the tabs start at the middle of the view |
122 | | app:mtTextColorSelected | Color of text in selected tab |
123 | | app:mtMrlRippleColor | Color of the ripple |
124 | | app:mtMrlRippleHighlightColor | Color of the background while the ripple is undergoing an animation |
125 | | app:mtMrlRippleDiameter | Radius of starting ripple |
126 | | app:mtMrlRippleOverlay | If true, ripple is drawn in foreground of view. Otherwise, it will drawn in the background |
127 | | app:mtMrlRippleAlpha | Level of transparency (alpha) of the ripple |
128 | | app:mtMrlRippleDuration | Duration of the ripple animation |
129 | | app:mtMrlRippleFadeDuration | Duration of fade out effect on ripple |
130 | | app:mtMrlRippleDelayClick | If true, delays calls to OnClickListeners until ripple effect ends. In that case, the indicator line's move to the clicked tab will also be delayed |
131 | | app:mtMrlRipplePersistent | If true, the ripple background color persists after animation, until setRadius(0) is called |
132 | | app:mtMrlRippleInAdapter | if true, MaterialRippleLayout will be optimized for use in AdapterViews |
133 | | app:mtMrlRippleRoundedCorners | Radius of corners of the ripple. Note: it uses software rendering pipeline for API 17 and below |
134 |
135 | Don't forget to add `xmlns:app="http://schemas.android.com/apk/res-auto"` to the root item in your layout.
136 |
137 | ## Contribution
138 | If you would like to contribute code you can do so through GitHub by forking the repository and sending a pull request.
139 |
140 | ## Credits
141 | This library is based on the great [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) library by [jpardogo](https://github.com/jpardogo) and [astuetz](https://github.com/astuetz) and on the great [material-ripple](https://github.com/balysv/material-ripple) library by [balysv](https://github.com/balysv).
142 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 |
3 | repositories {
4 | mavenCentral()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:1.2.3'
9 | classpath 'com.github.dcendents:android-maven-plugin:1.2'
10 |
11 | // NOTE: Do not place your application dependencies here; they belong
12 | // in the individual module build.gradle files
13 | }
14 | }
15 |
16 | def isReleaseBuild() {
17 | return version.contains("SNAPSHOT") == false
18 | }
19 |
20 | allprojects {
21 | version = VERSION_NAME
22 | group = GROUP
23 |
24 | repositories {
25 | mavenCentral()
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/device-2015-05-04-090851.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/device-2015-05-04-090851.png
--------------------------------------------------------------------------------
/device-2015-05-04-090914.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/device-2015-05-04-090914.png
--------------------------------------------------------------------------------
/device-2015-05-04-090952.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/device-2015-05-04-090952.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 22 11:17:57 BRST 2014
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.4-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 |
2 |
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.2"
6 |
7 | defaultConfig {
8 | minSdkVersion 9
9 | targetSdkVersion 23
10 | }
11 |
12 | android {
13 | lintOptions {
14 | abortOnError false
15 | }
16 | }
17 |
18 | sourceSets {
19 | main {
20 | manifest.srcFile 'AndroidManifest.xml'
21 | java.srcDirs = ['src']
22 | res.srcDirs = ['res']
23 | }
24 | }
25 | }
26 |
27 | dependencies {
28 | compile 'com.android.support:support-v4:23.1.1'
29 | compile 'com.nineoldandroids:library:2.4.0'
30 | }
31 |
32 | apply from: 'https://raw.github.com/chrisbanes/gradle-mvn-push/master/gradle-mvn-push.gradle'
33 |
--------------------------------------------------------------------------------
/library/res/layout/mt_tab.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
--------------------------------------------------------------------------------
/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 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/library/src/io/karim/MaterialRippleLayout.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Balys Valentukevicius
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 io.karim;
18 |
19 | import com.nineoldandroids.animation.Animator;
20 | import com.nineoldandroids.animation.AnimatorListenerAdapter;
21 | import com.nineoldandroids.animation.AnimatorSet;
22 | import com.nineoldandroids.animation.ObjectAnimator;
23 | import com.nineoldandroids.util.Property;
24 |
25 | import android.content.Context;
26 | import android.content.res.TypedArray;
27 | import android.graphics.Canvas;
28 | import android.graphics.Color;
29 | import android.graphics.Paint;
30 | import android.graphics.Path;
31 | import android.graphics.Point;
32 | import android.graphics.Rect;
33 | import android.graphics.RectF;
34 | import android.os.Build;
35 | import android.support.annotation.NonNull;
36 | import android.util.AttributeSet;
37 | import android.view.GestureDetector;
38 | import android.view.MotionEvent;
39 | import android.view.View;
40 | import android.view.ViewConfiguration;
41 | import android.view.ViewGroup;
42 | import android.view.ViewParent;
43 | import android.view.animation.AccelerateInterpolator;
44 | import android.view.animation.DecelerateInterpolator;
45 | import android.view.animation.LinearInterpolator;
46 | import android.widget.AdapterView;
47 | import android.widget.FrameLayout;
48 |
49 | import io.karim.materialtabs.R;
50 |
51 | import static android.view.GestureDetector.SimpleOnGestureListener;
52 | import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
53 |
54 | public class MaterialRippleLayout extends FrameLayout {
55 |
56 | private static final String TAG = MaterialRippleLayout.class.getSimpleName();
57 |
58 | public static final int DEFAULT_DURATION = 250;
59 | public static final int DEFAULT_FADE_DURATION = 125;
60 | public static final float DEFAULT_DIAMETER_DP = 20;
61 | public static final float DEFAULT_ALPHA = 0.2f;
62 | public static final int DEFAULT_COLOR = Color.WHITE;
63 | public static final boolean DEFAULT_DELAY_CLICK = false;
64 | public static final boolean DEFAULT_PERSISTENT = false;
65 | public static final boolean DEFAULT_SEARCH_ADAPTER = false;
66 | public static final boolean DEFAULT_RIPPLE_OVERLAY = false;
67 | public static final int DEFAULT_ROUNDED_CORNERS_DP = 0;
68 | public static final int FADE_EXTRA_DELAY = 50;
69 | public static final long HOVER_DURATION = 2500;
70 |
71 | private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
72 | private final Rect bounds = new Rect();
73 |
74 | private int rippleColor;
75 | private int rippleHighlightColor;
76 | private boolean rippleOverlay;
77 | private int rippleDiameterPx;
78 | private int rippleDuration;
79 | private int rippleAlphaInt;
80 | private boolean rippleDelayClick;
81 | private int rippleFadeDuration;
82 | private boolean ripplePersistent;
83 | private boolean rippleInAdapter;
84 | private float rippleRoundedCornersPx;
85 |
86 | private float radius;
87 |
88 | private AdapterView parentAdapter;
89 | private View childView;
90 |
91 | private AnimatorSet rippleAnimator;
92 | private ObjectAnimator hoverAnimator;
93 |
94 | private Point currentCoordinates = new Point();
95 | private Point previousCoordinates = new Point();
96 |
97 | private int layerType;
98 |
99 | private boolean eventCancelled;
100 | private boolean prepressed;
101 | private int positionInAdapter;
102 |
103 | private final GestureDetector gestureDetector;
104 | private PressedEvent pendingPressEvent;
105 |
106 | public static RippleBuilder on(View view) {
107 | return new RippleBuilder(view);
108 | }
109 |
110 | public MaterialRippleLayout(Context context) {
111 | this(context, null, 0);
112 | }
113 |
114 | public MaterialRippleLayout(Context context, AttributeSet attrs) {
115 | this(context, attrs, 0);
116 | }
117 |
118 | /**
119 | * Animations
120 | */
121 | private final Property radiusProperty = new Property(Float.class, "radius") {
122 | @Override
123 | public Float get(MaterialRippleLayout object) {
124 | return object.getRadius();
125 | }
126 |
127 | @Override
128 | public void set(MaterialRippleLayout object, Float value) {
129 | object.setRadius(value);
130 | }
131 | };
132 |
133 | @Override
134 | public final void addView(@NonNull View child, int index, ViewGroup.LayoutParams params) {
135 | if (getChildCount() > 0) {
136 | throw new IllegalStateException("MaterialRippleLayout can host only one child");
137 | }
138 | childView = child;
139 | super.addView(child, index, params);
140 | }
141 |
142 | @Override
143 | public void setOnClickListener(OnClickListener onClickListener) {
144 | if (childView == null) {
145 | throw new IllegalStateException("MaterialRippleLayout must have a child view to handle clicks");
146 | }
147 | childView.setOnClickListener(onClickListener);
148 | }
149 |
150 | @Override
151 | public boolean onInterceptTouchEvent(MotionEvent event) {
152 | return !findClickableViewInChild(childView, (int) event.getX(), (int) event.getY());
153 | }
154 |
155 | @Override
156 | public boolean onTouchEvent(@NonNull MotionEvent event) {
157 | boolean superOnTouchEvent = super.onTouchEvent(event);
158 |
159 | if (!isEnabled() || !childView.isEnabled()) {
160 | return superOnTouchEvent;
161 | }
162 |
163 | boolean isEventInBounds = bounds.contains((int) event.getX(), (int) event.getY());
164 |
165 | if (isEventInBounds) {
166 | previousCoordinates.set(currentCoordinates.x, currentCoordinates.y);
167 | currentCoordinates.set((int) event.getX(), (int) event.getY());
168 | }
169 |
170 | boolean gestureResult = gestureDetector.onTouchEvent(event);
171 | if (gestureResult || mHasPerformedLongPress) {
172 | return true;
173 | } else {
174 | int action = event.getActionMasked();
175 | switch (action) {
176 | case MotionEvent.ACTION_UP:
177 | if (prepressed) {
178 | childView.setPressed(true);
179 | postDelayed(new Runnable() {
180 | @Override
181 | public void run() {
182 | childView.setPressed(false);
183 | }
184 | }, ViewConfiguration.getPressedStateDuration());
185 | }
186 |
187 | if (isEventInBounds) {
188 | PerformClickEvent pendingClickEvent = new PerformClickEvent();
189 | startRipple(pendingClickEvent);
190 | if (!rippleDelayClick) {
191 | pendingClickEvent.run();
192 | }
193 | }
194 |
195 | cancelPressedEvent();
196 | break;
197 | case MotionEvent.ACTION_DOWN:
198 | setBackgroundColor(rippleHighlightColor);
199 |
200 | setPositionInAdapter();
201 | eventCancelled = false;
202 | pendingPressEvent = new PressedEvent(event);
203 | if (isInScrollingContainer()) {
204 | cancelPressedEvent();
205 | prepressed = true;
206 | postDelayed(pendingPressEvent, ViewConfiguration.getTapTimeout());
207 | } else {
208 | pendingPressEvent.run();
209 | }
210 | break;
211 | case MotionEvent.ACTION_CANCEL:
212 | if (rippleInAdapter) {
213 | // Do not use current coordinates in adapter since they tend to jump drastically on scroll.
214 | currentCoordinates.set(previousCoordinates.x, previousCoordinates.y);
215 | previousCoordinates = new Point();
216 | }
217 | childView.onTouchEvent(event);
218 | startRipple(null);
219 | cancelPressedEvent();
220 | break;
221 | case MotionEvent.ACTION_MOVE:
222 | setBackgroundColor(rippleHighlightColor);
223 |
224 | if (isEventInBounds && !eventCancelled) {
225 | invalidate();
226 | } else if (!isEventInBounds) {
227 | startRipple(null);
228 | }
229 |
230 | if (!isEventInBounds) {
231 | cancelPressedEvent();
232 | if (hoverAnimator != null) {
233 | hoverAnimator.cancel();
234 | }
235 | childView.onTouchEvent(event);
236 | eventCancelled = true;
237 | }
238 | break;
239 | }
240 | return true;
241 | }
242 | }
243 |
244 | private void cancelPressedEvent() {
245 | if (pendingPressEvent != null) {
246 | removeCallbacks(pendingPressEvent);
247 | prepressed = false;
248 | }
249 | }
250 |
251 | private boolean mHasPerformedLongPress;
252 |
253 | private void startHover() {
254 | if (eventCancelled) {
255 | return;
256 | }
257 |
258 | if (hoverAnimator != null) {
259 | hoverAnimator.cancel();
260 | }
261 | final float radius = (float) (Math.sqrt(Math.pow(getWidth(), 2) + Math.pow(getHeight(), 2)) * 1.2f);
262 | hoverAnimator = ObjectAnimator.ofFloat(this, radiusProperty, rippleDiameterPx, radius).setDuration(HOVER_DURATION);
263 | hoverAnimator.setInterpolator(new LinearInterpolator());
264 | hoverAnimator.start();
265 | }
266 |
267 | private void startRipple(final Runnable animationEndRunnable) {
268 | if (eventCancelled) {
269 | return;
270 | }
271 |
272 | float endRadius = getEndRadius();
273 |
274 | cancelAnimations();
275 |
276 | rippleAnimator = new AnimatorSet();
277 | rippleAnimator.addListener(new AnimatorListenerAdapter() {
278 | @Override
279 | public void onAnimationEnd(Animator animation) {
280 | if (!ripplePersistent) {
281 | setRadius(0);
282 | setRippleAlphaInt(rippleAlphaInt);
283 | }
284 | if (animationEndRunnable != null && rippleDelayClick) {
285 | animationEndRunnable.run();
286 | }
287 | childView.setPressed(false);
288 |
289 | setBackgroundColor(Color.TRANSPARENT);
290 | }
291 | });
292 |
293 | ObjectAnimator ripple = ObjectAnimator.ofFloat(this, radiusProperty, radius, endRadius);
294 | ripple.setDuration(rippleDuration);
295 | ripple.setInterpolator(new DecelerateInterpolator());
296 | ObjectAnimator fade = ObjectAnimator.ofInt(this, circleAlphaProperty, rippleAlphaInt, 0);
297 | fade.setDuration(rippleFadeDuration);
298 | fade.setInterpolator(new AccelerateInterpolator());
299 | fade.setStartDelay(rippleDuration - rippleFadeDuration - FADE_EXTRA_DELAY);
300 |
301 | if (ripplePersistent) {
302 | rippleAnimator.play(ripple);
303 | } else if (getRadius() > endRadius) {
304 | fade.setStartDelay(0);
305 | rippleAnimator.play(fade);
306 | } else {
307 | rippleAnimator.playTogether(ripple, fade);
308 | }
309 | rippleAnimator.start();
310 | }
311 |
312 | private void cancelAnimations() {
313 | if (rippleAnimator != null) {
314 | rippleAnimator.cancel();
315 | rippleAnimator.removeAllListeners();
316 | }
317 |
318 | if (hoverAnimator != null) {
319 | hoverAnimator.cancel();
320 | }
321 | }
322 |
323 | private final Property circleAlphaProperty = new Property(Integer.class,
324 | "rippleAlphaFloat") {
325 | @Override
326 | public Integer get(MaterialRippleLayout object) {
327 | return object.getRippleAlphaInt();
328 | }
329 |
330 | @Override
331 | public void set(MaterialRippleLayout object, Integer value) {
332 | object.setRippleAlphaInt(value);
333 | }
334 | };
335 |
336 | private boolean isInScrollingContainer() {
337 | ViewParent p = getParent();
338 | while (p != null && p instanceof ViewGroup) {
339 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
340 |
341 | if (((ViewGroup) p).shouldDelayChildPressedState()) {
342 | return true;
343 | }
344 | }
345 | p = p.getParent();
346 | }
347 | return false;
348 | }
349 |
350 | private AdapterView findParentAdapterView() {
351 | if (parentAdapter != null) {
352 | return parentAdapter;
353 | }
354 | ViewParent current = getParent();
355 | while (true) {
356 | if (current instanceof AdapterView) {
357 | parentAdapter = (AdapterView) current;
358 | return parentAdapter;
359 | } else {
360 | try {
361 | current = current.getParent();
362 | } catch (NullPointerException npe) {
363 | throw new RuntimeException("Could not find a parent AdapterView");
364 | }
365 | }
366 | }
367 | }
368 |
369 | private void setPositionInAdapter() {
370 | if (rippleInAdapter) {
371 | positionInAdapter = findParentAdapterView().getPositionForView(MaterialRippleLayout.this);
372 | }
373 | }
374 |
375 | private boolean adapterPositionChanged() {
376 | if (rippleInAdapter) {
377 | int newPosition = findParentAdapterView().getPositionForView(MaterialRippleLayout.this);
378 | final boolean changed = newPosition != positionInAdapter;
379 | positionInAdapter = newPosition;
380 | if (changed) {
381 | cancelPressedEvent();
382 | cancelAnimations();
383 | childView.setPressed(false);
384 | setRadius(0);
385 | }
386 | return changed;
387 | }
388 | return false;
389 | }
390 |
391 | private boolean findClickableViewInChild(View view, int x, int y) {
392 | if (view instanceof ViewGroup) {
393 | ViewGroup viewGroup = (ViewGroup) view;
394 | for (int i = 0; i < viewGroup.getChildCount(); i++) {
395 | View child = viewGroup.getChildAt(i);
396 | final Rect rect = new Rect();
397 | child.getHitRect(rect);
398 |
399 | final boolean contains = rect.contains(x, y);
400 | if (contains) {
401 | return findClickableViewInChild(child, x - rect.left, y - rect.top);
402 | }
403 | }
404 | } else if (view != childView) {
405 | return (view.isEnabled() && (view.isClickable() || view.isLongClickable() || view.isFocusableInTouchMode()));
406 | }
407 |
408 | return view.isFocusableInTouchMode();
409 | }
410 |
411 | @Override
412 | protected void onSizeChanged(int w, int h, int oldw, int oldh) {
413 | super.onSizeChanged(w, h, oldw, oldh);
414 | bounds.set(0, 0, w, h);
415 | }
416 |
417 | @Override
418 | public boolean isInEditMode() {
419 | return true;
420 | }
421 |
422 | /**
423 | * Drawing
424 | */
425 | @Override
426 | public void draw(@NonNull Canvas canvas) {
427 | final boolean positionChanged = adapterPositionChanged();
428 | if (rippleOverlay) {
429 | super.draw(canvas);
430 | if (!positionChanged) {
431 | if (rippleRoundedCornersPx != 0) {
432 | Path clipPath = new Path();
433 | RectF rect = new RectF(0, 0, canvas.getWidth(), canvas.getHeight());
434 | clipPath.addRoundRect(rect, rippleRoundedCornersPx, rippleRoundedCornersPx, Path.Direction.CW);
435 | canvas.clipPath(clipPath);
436 | }
437 | canvas.drawCircle(currentCoordinates.x, currentCoordinates.y, radius, paint);
438 | }
439 | } else {
440 | if (!positionChanged) {
441 | canvas.drawCircle(currentCoordinates.x, currentCoordinates.y, radius, paint);
442 | }
443 | super.draw(canvas);
444 | }
445 | }
446 |
447 | public MaterialRippleLayout(Context context, AttributeSet attrs, int defStyle) {
448 | super(context, attrs, defStyle);
449 |
450 | setWillNotDraw(false);
451 | gestureDetector = new GestureDetector(context, new SimpleOnGestureListener() {
452 | public void onLongPress(MotionEvent e) {
453 | mHasPerformedLongPress = childView.performLongClick();
454 | if (mHasPerformedLongPress) {
455 | startRipple(null);
456 | cancelPressedEvent();
457 | }
458 | }
459 |
460 | @Override
461 | public boolean onDown(MotionEvent e) {
462 | mHasPerformedLongPress = false;
463 | return super.onDown(e);
464 | }
465 | });
466 |
467 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MaterialRippleLayout);
468 | rippleColor = a.getColor(R.styleable.MaterialRippleLayout_mrlRippleColor, DEFAULT_COLOR);
469 |
470 | // Making default ripple highlight color the same as rippleColor but with 1/4 the alpha.
471 | rippleHighlightColor = Color.argb((int) (Color.alpha(rippleColor) * 0.25), Color.red(rippleColor), Color.green(rippleColor),
472 | Color.blue(rippleColor));
473 | rippleHighlightColor = a.getColor(R.styleable.MaterialRippleLayout_mrlRippleHighlightColor, rippleHighlightColor);
474 | rippleDiameterPx = a.getDimensionPixelSize(R.styleable.MaterialRippleLayout_mrlRippleDiameter,
475 | Utils.dpToPx(getResources(), DEFAULT_DIAMETER_DP));
476 | rippleOverlay = a.getBoolean(R.styleable.MaterialRippleLayout_mrlRippleOverlay, DEFAULT_RIPPLE_OVERLAY);
477 | rippleDuration = a.getInt(R.styleable.MaterialRippleLayout_mrlRippleDuration, DEFAULT_DURATION);
478 | rippleAlphaInt = (int) (255 * a.getFloat(R.styleable.MaterialRippleLayout_mrlRippleAlpha, DEFAULT_ALPHA));
479 | rippleDelayClick = a.getBoolean(R.styleable.MaterialRippleLayout_mrlRippleDelayClick, DEFAULT_DELAY_CLICK);
480 | rippleFadeDuration = a.getInteger(R.styleable.MaterialRippleLayout_mrlRippleFadeDuration, DEFAULT_FADE_DURATION);
481 | ripplePersistent = a.getBoolean(R.styleable.MaterialRippleLayout_mrlRipplePersistent, DEFAULT_PERSISTENT);
482 | rippleInAdapter = a.getBoolean(R.styleable.MaterialRippleLayout_mrlRippleInAdapter, DEFAULT_SEARCH_ADAPTER);
483 | rippleRoundedCornersPx = a.getDimensionPixelSize(R.styleable.MaterialRippleLayout_mrlRippleRoundedCorners, DEFAULT_ROUNDED_CORNERS_DP);
484 |
485 | a.recycle();
486 |
487 | paint.setColor(rippleColor);
488 | paint.setAlpha(rippleAlphaInt);
489 |
490 | enableClipPathSupportIfNecessary();
491 | }
492 |
493 | private float getRadius() {
494 | return radius;
495 | }
496 |
497 |
498 | public void setRadius(float radius) {
499 | this.radius = radius;
500 | invalidate();
501 | }
502 |
503 | private float getEndRadius() {
504 | final int width = getWidth();
505 | final int height = getHeight();
506 |
507 | final int halfWidth = width / 2;
508 | final int halfHeight = height / 2;
509 |
510 | final float radiusX = halfWidth > currentCoordinates.x ? width - currentCoordinates.x : currentCoordinates.x;
511 | final float radiusY = halfHeight > currentCoordinates.y ? height - currentCoordinates.y : currentCoordinates.y;
512 |
513 | //noinspection SuspiciousNameCombination
514 | return (float) Math.sqrt(Math.pow(radiusX, 2) + Math.pow(radiusY, 2)) * 1.2f;
515 | }
516 |
517 | public int getRippleAlphaInt() {
518 | return paint.getAlpha();
519 | }
520 |
521 | public void setRippleAlphaInt(Integer alphaInt) {
522 | paint.setAlpha(alphaInt);
523 | invalidate();
524 | }
525 |
526 | /**
527 | * Accessor
528 | */
529 | public void setRippleColor(int rippleColor) {
530 | this.rippleColor = rippleColor;
531 | this.rippleHighlightColor = Color.argb((int) (Color.alpha(rippleColor) * 0.25), Color.red(rippleColor), Color.green(rippleColor),
532 | Color.blue(rippleColor));
533 | paint.setColor(rippleColor);
534 | paint.setAlpha(rippleAlphaInt);
535 | invalidate();
536 | }
537 |
538 | public void setRippleHighlightColor(int rippleHighlightColor) {
539 | this.rippleHighlightColor = rippleHighlightColor;
540 | invalidate();
541 | }
542 |
543 | public void setRippleOverlay(boolean rippleOverlay) {
544 | this.rippleOverlay = rippleOverlay;
545 | }
546 |
547 | public void setRippleDiameterPx(int rippleDiameterPx) {
548 | this.rippleDiameterPx = rippleDiameterPx;
549 | }
550 |
551 | public void setRippleDuration(int rippleDuration) {
552 | this.rippleDuration = rippleDuration;
553 | }
554 |
555 | public void setRippleDelayClick(boolean rippleDelayClick) {
556 | this.rippleDelayClick = rippleDelayClick;
557 | }
558 |
559 | public void setRippleFadeDuration(int rippleFadeDuration) {
560 | this.rippleFadeDuration = rippleFadeDuration;
561 | }
562 |
563 | public void setRipplePersistent(boolean ripplePersistent) {
564 | this.ripplePersistent = ripplePersistent;
565 | }
566 |
567 | public void setRippleInAdapter(boolean rippleInAdapter) {
568 | this.rippleInAdapter = rippleInAdapter;
569 | }
570 |
571 | public void setRippleRoundedCornersPx(int rippleRoundedCornerPx) {
572 | this.rippleRoundedCornersPx = rippleRoundedCornerPx;
573 | enableClipPathSupportIfNecessary();
574 | }
575 |
576 | public void setDefaultRippleAlphaInt(int alphaInt) {
577 | this.rippleAlphaInt = alphaInt;
578 | paint.setAlpha(alphaInt);
579 | invalidate();
580 | }
581 |
582 | public void performRipple() {
583 | currentCoordinates = new Point(getWidth() / 2, getHeight() / 2);
584 | startRipple(null);
585 | }
586 |
587 | public void performRipple(Point anchor) {
588 | currentCoordinates = new Point(anchor.x, anchor.y);
589 | startRipple(null);
590 | }
591 |
592 | /**
593 | * {@link Canvas#clipPath(Path)} is not supported in hardware accelerated layers before API 18. Use software layer instead
594 | *
595 | * https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
596 | */
597 | private void enableClipPathSupportIfNecessary() {
598 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR1 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
599 | if (rippleRoundedCornersPx != 0) {
600 | layerType = getLayerType();
601 | setLayerType(LAYER_TYPE_SOFTWARE, null);
602 | } else {
603 | setLayerType(layerType, null);
604 | }
605 | }
606 | }
607 |
608 | /**
609 | * Helper
610 | */
611 | private class PerformClickEvent implements Runnable {
612 |
613 | @Override
614 | public void run() {
615 | if (mHasPerformedLongPress) {
616 | return;
617 | }
618 |
619 | // If parent is an AdapterView, try to call its ItemClickListener.
620 | if (getParent() instanceof AdapterView) {
621 | clickAdapterView((AdapterView) getParent());
622 | } else if (rippleInAdapter) {
623 | // Find adapter view.
624 | clickAdapterView(findParentAdapterView());
625 | } else {
626 | // Otherwise, just perform click on child.
627 | childView.performClick();
628 | }
629 | }
630 |
631 | private void clickAdapterView(AdapterView parent) {
632 | final int position = parent.getPositionForView(MaterialRippleLayout.this);
633 | final long itemId = parent.getAdapter() != null ? parent.getAdapter().getItemId(position) : 0;
634 | if (position != AdapterView.INVALID_POSITION) {
635 | parent.performItemClick(MaterialRippleLayout.this, position, itemId);
636 | }
637 | }
638 | }
639 |
640 | private final class PressedEvent implements Runnable {
641 |
642 | private final MotionEvent event;
643 |
644 | public PressedEvent(MotionEvent event) {
645 | this.event = event;
646 | }
647 |
648 | @Override
649 | public void run() {
650 | prepressed = false;
651 |
652 | // Prevent the child's long click, let the ripple layout call its performLongClick
653 | childView.setLongClickable(false);
654 | childView.onTouchEvent(event);
655 | childView.setPressed(true);
656 | startHover();
657 | }
658 | }
659 |
660 | /**
661 | * Builder
662 | */
663 | public static class RippleBuilder {
664 |
665 | private final Context context;
666 | private final View child;
667 |
668 | private int rippleColor = DEFAULT_COLOR;
669 | private int rippleHighlightColor;
670 | private boolean rippleOverlay = DEFAULT_RIPPLE_OVERLAY;
671 | private float rippleDiameterDp = DEFAULT_DIAMETER_DP;
672 | private int rippleDuration = DEFAULT_DURATION;
673 | private float rippleAlphaFloat = DEFAULT_ALPHA;
674 | private boolean rippleDelayClick = DEFAULT_DELAY_CLICK;
675 | private int rippleFadeDuration = DEFAULT_FADE_DURATION;
676 | private boolean ripplePersistent = DEFAULT_PERSISTENT;
677 | private boolean rippleSearchAdapter = DEFAULT_SEARCH_ADAPTER;
678 | private float rippleRoundedCornerDp = DEFAULT_ROUNDED_CORNERS_DP;
679 |
680 | public RippleBuilder(View child) {
681 | this.child = child;
682 | this.context = child.getContext();
683 | }
684 |
685 | public RippleBuilder rippleColor(int color) {
686 | this.rippleColor = color;
687 | this.rippleHighlightColor = Color.argb((int) (Color.alpha(rippleColor) * 0.25), Color.red(rippleColor), Color.green(rippleColor),
688 | Color.blue(rippleColor));
689 | return this;
690 | }
691 |
692 | /**
693 | * Make sure to call this after rippleColor() in the Builder.
694 | */
695 | public RippleBuilder rippleHighlightColor(int highlightColor) {
696 | this.rippleHighlightColor = highlightColor;
697 | return this;
698 | }
699 |
700 | public RippleBuilder rippleOverlay(boolean overlay) {
701 | this.rippleOverlay = overlay;
702 | return this;
703 | }
704 |
705 | public RippleBuilder rippleDiameterDp(float diameterDp) {
706 | this.rippleDiameterDp = diameterDp;
707 | return this;
708 | }
709 |
710 | public RippleBuilder rippleDuration(int duration) {
711 | this.rippleDuration = duration;
712 | return this;
713 | }
714 |
715 | /**
716 | * @param alpha value between 0 and 1
717 | */
718 | public RippleBuilder rippleAlpha(float alpha) {
719 | this.rippleAlphaFloat = alpha;
720 | return this;
721 | }
722 |
723 | public RippleBuilder rippleDelayClick(boolean delayClick) {
724 | this.rippleDelayClick = delayClick;
725 | return this;
726 | }
727 |
728 | public RippleBuilder rippleFadeDuration(int fadeDuration) {
729 | this.rippleFadeDuration = fadeDuration;
730 | return this;
731 | }
732 |
733 | public RippleBuilder ripplePersistent(boolean persistent) {
734 | this.ripplePersistent = persistent;
735 | return this;
736 | }
737 |
738 | public RippleBuilder rippleInAdapter(boolean inAdapter) {
739 | this.rippleSearchAdapter = inAdapter;
740 | return this;
741 | }
742 |
743 | public RippleBuilder rippleRoundedCornersDp(float radiusDp) {
744 | this.rippleRoundedCornerDp = radiusDp;
745 | return this;
746 | }
747 |
748 | public MaterialRippleLayout create() {
749 | MaterialRippleLayout layout = new MaterialRippleLayout(context);
750 | layout.setRippleColor(rippleColor);
751 | layout.setDefaultRippleAlphaInt((int) (255 * rippleAlphaFloat));
752 | layout.setRippleDelayClick(rippleDelayClick);
753 | layout.setRippleDiameterPx(Utils.dpToPx(context.getResources(), rippleDiameterDp));
754 | layout.setRippleDuration(rippleDuration);
755 | layout.setRippleFadeDuration(rippleFadeDuration);
756 | layout.setRippleHighlightColor(rippleHighlightColor);
757 | layout.setRipplePersistent(ripplePersistent);
758 | layout.setRippleOverlay(rippleOverlay);
759 | layout.setRippleInAdapter(rippleSearchAdapter);
760 | layout.setRippleRoundedCornersPx(Utils.dpToPx(context.getResources(), rippleRoundedCornerDp));
761 |
762 | ViewGroup.LayoutParams params = child.getLayoutParams();
763 | ViewGroup parent = (ViewGroup) child.getParent();
764 | int index = 0;
765 |
766 | if (parent != null && parent instanceof MaterialRippleLayout) {
767 | throw new IllegalStateException("MaterialRippleLayout could not be created: parent of the view already is a MaterialRippleLayout");
768 | }
769 |
770 | if (parent != null) {
771 | index = parent.indexOfChild(child);
772 | parent.removeView(child);
773 | }
774 |
775 | layout.addView(child, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
776 |
777 | if (parent != null) {
778 | parent.addView(layout, index, params);
779 | }
780 |
781 | return layout;
782 | }
783 | }
784 | }
785 |
--------------------------------------------------------------------------------
/library/src/io/karim/Utils.java:
--------------------------------------------------------------------------------
1 | package io.karim;
2 |
3 | import android.content.res.Resources;
4 | import android.util.TypedValue;
5 |
6 | public class Utils {
7 | public static int dpToPx(Resources resources, float dp) {
8 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, resources.getDisplayMetrics());
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/sample/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | maven { url 'https://maven.fabric.io/public' }
4 | }
5 |
6 | dependencies {
7 | classpath 'io.fabric.tools:gradle:1.19.0'
8 | }
9 | }
10 |
11 | apply plugin: 'com.android.application'
12 | apply plugin: 'io.fabric'
13 |
14 | repositories {
15 | mavenCentral()
16 |
17 | maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
18 | maven { url 'https://maven.fabric.io/public' }
19 | }
20 |
21 |
22 | dependencies {
23 | compile project(':library')
24 | compile 'com.android.support:appcompat-v7:23.1.1'
25 | compile 'com.android.support:cardview-v7:23.1.1'
26 | compile 'com.jakewharton:butterknife:6.0.0'
27 | compile 'com.readystatesoftware.systembartint:systembartint:1.0.3'
28 | compile 'com.nineoldandroids:library:2.4.0'
29 | compile('com.crashlytics.sdk.android:crashlytics:2.5.5@aar') {
30 | transitive = true;
31 | }
32 | }
33 |
34 | android {
35 | compileSdkVersion 23
36 | buildToolsVersion "23.0.2"
37 |
38 | defaultConfig {
39 | minSdkVersion 9
40 | targetSdkVersion 23
41 |
42 | versionName "1.0.7"
43 | versionCode 11
44 | }
45 |
46 | signingConfigs { release }
47 |
48 | buildTypes {
49 | release {
50 | signingConfig signingConfigs.release
51 | }
52 | }
53 |
54 | sourceSets {
55 | main {
56 | manifest.srcFile 'AndroidManifest.xml'
57 | java.srcDirs = ['src']
58 | res.srcDirs = ['res']
59 | }
60 | }
61 |
62 | android {
63 | lintOptions {
64 | abortOnError false
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_action_content_clear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-hdpi/ic_action_content_clear.png
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_action_github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-hdpi/ic_action_github.png
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_action_info_outline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-hdpi/ic_action_info_outline.png
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_action_navigation_arrow_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-hdpi/ic_action_navigation_arrow_forward.png
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_action_social_mood.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-hdpi/ic_action_social_mood.png
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_action_social_share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-hdpi/ic_action_social_share.png
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_action_twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-hdpi/ic_action_twitter.png
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_navigation_arrow_back_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-hdpi/ic_navigation_arrow_back_white.png
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_ripple_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-hdpi/ic_ripple_selected.png
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_ripple_unselected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-hdpi/ic_ripple_unselected.png
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_tabs_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-hdpi/ic_tabs_selected.png
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_tabs_unselected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-hdpi/ic_tabs_unselected.png
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_toggle_check_box_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-hdpi/ic_toggle_check_box_dark.png
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_toggle_check_box_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-hdpi/ic_toggle_check_box_light.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_action_content_clear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-mdpi/ic_action_content_clear.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_action_github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-mdpi/ic_action_github.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_action_info_outline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-mdpi/ic_action_info_outline.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_action_navigation_arrow_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-mdpi/ic_action_navigation_arrow_forward.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_action_social_mood.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-mdpi/ic_action_social_mood.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_action_social_share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-mdpi/ic_action_social_share.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_action_twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-mdpi/ic_action_twitter.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_navigation_arrow_back_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-mdpi/ic_navigation_arrow_back_white.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_ripple_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-mdpi/ic_ripple_selected.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_ripple_unselected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-mdpi/ic_ripple_unselected.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_tabs_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-mdpi/ic_tabs_selected.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_tabs_unselected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-mdpi/ic_tabs_unselected.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_toggle_check_box_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-mdpi/ic_toggle_check_box_dark.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_toggle_check_box_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-mdpi/ic_toggle_check_box_light.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_action_content_clear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xhdpi/ic_action_content_clear.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_action_github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xhdpi/ic_action_github.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_action_info_outline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xhdpi/ic_action_info_outline.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_action_navigation_arrow_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xhdpi/ic_action_navigation_arrow_forward.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_action_social_mood.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xhdpi/ic_action_social_mood.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_action_social_share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xhdpi/ic_action_social_share.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_action_twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xhdpi/ic_action_twitter.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_navigation_arrow_back_blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xhdpi/ic_navigation_arrow_back_blue.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_ripple_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xhdpi/ic_ripple_selected.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_ripple_unselected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xhdpi/ic_ripple_unselected.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_tabs_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xhdpi/ic_tabs_selected.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_tabs_unselected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xhdpi/ic_tabs_unselected.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_toggle_check_box_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xhdpi/ic_toggle_check_box_dark.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_toggle_check_box_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xhdpi/ic_toggle_check_box_light.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_action_content_clear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxhdpi/ic_action_content_clear.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_action_github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxhdpi/ic_action_github.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_action_info_outline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxhdpi/ic_action_info_outline.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_action_navigation_arrow_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxhdpi/ic_action_navigation_arrow_forward.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_action_social_mood.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxhdpi/ic_action_social_mood.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_action_social_share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxhdpi/ic_action_social_share.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_action_twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxhdpi/ic_action_twitter.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_navigation_arrow_back_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxhdpi/ic_navigation_arrow_back_white.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_ripple_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxhdpi/ic_ripple_selected.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_ripple_unselected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxhdpi/ic_ripple_unselected.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_tabs_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxhdpi/ic_tabs_selected.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_tabs_unselected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxhdpi/ic_tabs_unselected.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_toggle_check_box_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxhdpi/ic_toggle_check_box_dark.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_toggle_check_box_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxhdpi/ic_toggle_check_box_light.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/ic_action_content_clear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxxhdpi/ic_action_content_clear.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/ic_action_github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxxhdpi/ic_action_github.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/ic_action_info_outline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxxhdpi/ic_action_info_outline.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/ic_action_navigation_arrow_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxxhdpi/ic_action_navigation_arrow_forward.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/ic_action_social_mood.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxxhdpi/ic_action_social_mood.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/ic_action_social_share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxxhdpi/ic_action_social_share.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/ic_action_twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxxhdpi/ic_action_twitter.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/ic_navigation_arrow_back_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxxhdpi/ic_navigation_arrow_back_white.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/ic_ripple_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxxhdpi/ic_ripple_selected.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/ic_ripple_unselected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxxhdpi/ic_ripple_unselected.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/ic_tabs_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxxhdpi/ic_tabs_selected.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/ic_tabs_unselected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxxhdpi/ic_tabs_unselected.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/ic_toggle_check_box_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxxhdpi/ic_toggle_check_box_dark.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/ic_toggle_check_box_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxxhdpi/ic_toggle_check_box_light.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxxhdpi/me.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/drawable-xxxhdpi/me.jpg
--------------------------------------------------------------------------------
/sample/res/drawable/radio_button_dark.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/sample/res/drawable/radio_button_light.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/sample/res/layout/activity_tabs.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
20 |
21 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/sample/res/layout/dialog_me.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
11 |
12 |
17 |
18 |
25 |
26 |
32 |
33 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/sample/res/layout/fragment_card.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/sample/res/layout/fragment_ripple_settings.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
10 |
11 |
12 |
16 |
17 |
21 |
22 |
29 |
30 |
40 |
41 |
42 |
46 |
47 |
48 |
49 |
52 |
53 |
54 |
58 |
59 |
63 |
64 |
71 |
72 |
82 |
83 |
84 |
88 |
89 |
90 |
91 |
94 |
95 |
96 |
100 |
101 |
105 |
106 |
113 |
114 |
123 |
124 |
128 |
137 |
138 |
147 |
148 |
157 |
158 |
167 |
168 |
177 |
178 |
187 |
188 |
197 |
198 |
199 |
200 |
201 |
204 |
205 |
206 |
207 |
212 |
213 |
220 |
221 |
227 |
228 |
235 |
236 |
239 |
240 |
241 |
242 |
243 |
244 |
247 |
248 |
249 |
253 |
254 |
258 |
259 |
266 |
267 |
277 |
278 |
279 |
283 |
284 |
285 |
286 |
289 |
290 |
291 |
295 |
296 |
300 |
301 |
308 |
309 |
319 |
320 |
321 |
325 |
326 |
327 |
328 |
331 |
332 |
333 |
337 |
338 |
342 |
343 |
350 |
351 |
360 |
361 |
362 |
366 |
375 |
376 |
385 |
386 |
395 |
396 |
405 |
406 |
415 |
416 |
425 |
426 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
444 |
445 |
446 |
447 |
452 |
453 |
460 |
461 |
467 |
468 |
475 |
478 |
479 |
480 |
481 |
482 |
483 |
486 |
487 |
488 |
489 |
494 |
495 |
502 |
503 |
509 |
510 |
517 |
518 |
521 |
522 |
523 |
524 |
525 |
526 |
529 |
530 |
531 |
535 |
536 |
540 |
541 |
548 |
549 |
559 |
560 |
564 |
565 |
566 |
567 |
568 |
--------------------------------------------------------------------------------
/sample/res/layout/toolbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/sample/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
21 |
--------------------------------------------------------------------------------
/sample/res/menu/menu_tabs.xml:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/sample/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/res/resize_xxxhdpi_pictures_to_other_dpis.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #---------------------------------------------------------------
3 | # Given an xxxhdpi image or an App Icon (launcher), this script
4 | # creates different dpis resources
5 | #
6 | # Place this script, as well as the source image, inside res
7 | # folder and execute it passing the image filename as argument
8 | #
9 | # Example:
10 | # ./drawables_dpis_creation.sh ic_launcher.png
11 | # OR
12 | # ./drawables_dpis_creation.sh my_cool_xxhdpi_image.png
13 | #---------------------------------------------------------------
14 |
15 | echo " Creating different dimensions (dips) of "$1" ..."
16 |
17 | if [ $1 = "ic_launcher.png" ]; then
18 | echo " App icon detected"
19 |
20 | convert ic_launcher.png -resize 192x192 drawable-xxxhdpi/ic_launcher.png
21 | convert ic_launcher.png -resize 144x144 drawable-xxhdpi/ic_launcher.png
22 | convert ic_launcher.png -resize 96x96 drawable-xhdpi/ic_launcher.png
23 | convert ic_launcher.png -resize 72x72 drawable-hdpi/ic_launcher.png
24 | convert ic_launcher.png -resize 48x48 drawable-mdpi/ic_launcher.png
25 | # convert ic_launcher.png -resize 36x36 drawable-ldpi/ic_launcher.png
26 |
27 | rm -i ic_launcher.png
28 | else
29 | convert $1 -resize 75% drawable-xxhdpi/$1
30 | convert $1 -resize 50% drawable-xhdpi/$1
31 | convert $1 -resize 37.5% drawable-hdpi/$1
32 | convert $1 -resize 25% drawable-mdpi/$1
33 | # convert $1 -resize 18.75% drawable-ldpi/$1
34 | mv $1 drawable-xxxhdpi/$1
35 |
36 | fi
37 |
38 | echo " Done"
39 |
--------------------------------------------------------------------------------
/sample/res/values-v19/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/sample/res/values-v20/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/sample/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/sample/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFF
4 | #000
5 | #40FFFFFF
6 | #40000000
7 |
8 | #80888888
9 |
10 | #FFE5E5E5
11 | #3E5F22
12 |
13 |
14 | #8BC24A
15 | #FF9700
16 | #FFEB3C
17 | #D01715
18 | #00BCD5
19 |
20 |
21 |
22 | #408BC24A
23 | #40FF9700
24 | #40FFEB3C
25 | #40D01715
26 | #4000BCD5
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/sample/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | MaterialTabs
4 | Cook Your Tabs
5 |
6 | Underline Height
7 | Indicator Height
8 | Tab Padding Left Right
9 | Same Weight Tabs
10 | Underline Color
11 | Indicator Color
12 | Text All Caps
13 | Padding Middle
14 | Tab Text Unselected Color
15 | Tab Text Selected Color
16 | Tab Bar Background Color
17 | Selected Text Style
18 | Unselected Text Style
19 | Ripple Duration
20 | Ripple Alpha Float
21 | Ripple Color
22 | Ripple Delay Click
23 | Ripple Diameter
24 | Ripple Fade Duration
25 | Ripple Highlight Color
26 | Ripple Overlay
27 | Ripple Persistent
28 | Ripple Rounded Corners Radius
29 | Me
30 | Go
31 | Normal
32 | Bold
33 | Italic
34 | Share
35 | Reset
36 | Toolbar (ActionBar) Color
37 |
38 | Level of transparency (alpha) of the ripple
39 | Color of the ripple
40 | Radius of starting ripple
41 | Duration of the ripple animation
42 | If true, delays calls to OnClickListeners until ripple effect ends. In that case, the indicator line\'s
43 | move to the clicked tab will also be delayed
44 |
45 | Duration of fade out effect on ripple
46 | If true, ripple is drawn in foreground of view. Otherwise, it will drawn in the background
47 | If true, the ripple background color persists after animation, until setRadius(0) is called
48 | Color of the background while the ripple is undergoing an animation
49 | Radius of corners of the ripple. Note: it uses software rendering pipeline for API 17 and
50 | below
51 |
52 |
53 | If set to true, each tab is given the same weight
54 | If true, the tabs start at the middle of the view
55 | Height of the sliding indicator
56 | Color of the sliding indicator
57 | Height of the full-width line on the bottom of the view
58 | Color of the full-width line on the bottom of the view
59 | If true, all tab titles will be upper case
60 | Style of text in unselected tab
61 | Style of text in selected tab
62 | Left and right padding of each tab
63 | Color of text in selected tab
64 | Color of text in non-selected tabs
65 | Color of toolbar in the next Activity
66 | Background color of tab bar
67 | pizza
68 | \@KarimFrenn
69 | Karim Frenn
70 | http://github.com/pizza
71 | http://twitter.com/karimfrenn
72 | Show Toolbar
73 | Show/hide toolbar in next Activity
74 | Number of Tabs
75 | Send to
76 | The number of tabs to be shown in next Activity
77 |
78 |
--------------------------------------------------------------------------------
/sample/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
15 |
16 |
19 |
20 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/sample/sample-release.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/sample-release.apk
--------------------------------------------------------------------------------
/sample/src/io/karim/materialtabs/sample/MainActivity.java:
--------------------------------------------------------------------------------
1 | package io.karim.materialtabs.sample;
2 |
3 | import com.readystatesoftware.systembartint.SystemBarTintManager;
4 |
5 | import android.app.AlertDialog;
6 | import android.content.DialogInterface;
7 | import android.content.Intent;
8 | import android.os.Bundle;
9 | import android.support.v4.app.DialogFragment;
10 | import android.support.v4.app.Fragment;
11 | import android.support.v4.app.FragmentManager;
12 | import android.support.v4.app.FragmentPagerAdapter;
13 | import android.support.v4.view.ViewPager;
14 | import android.support.v7.app.AppCompatActivity;
15 | import android.support.v7.widget.Toolbar;
16 | import android.text.Spannable;
17 | import android.text.SpannableString;
18 | import android.text.Spanned;
19 | import android.text.method.LinkMovementMethod;
20 | import android.text.style.URLSpan;
21 | import android.util.Log;
22 | import android.util.TypedValue;
23 | import android.view.LayoutInflater;
24 | import android.view.Menu;
25 | import android.view.MenuItem;
26 | import android.view.View;
27 | import android.view.ViewGroup;
28 | import android.view.Window;
29 | import android.widget.ImageView;
30 | import android.widget.TextView;
31 |
32 | import java.util.ArrayList;
33 |
34 | import butterknife.ButterKnife;
35 | import butterknife.InjectView;
36 | import io.karim.MaterialTabs;
37 |
38 |
39 | public class MainActivity extends AppCompatActivity {
40 |
41 | private static final String TAG = MainActivity.class.getSimpleName();
42 |
43 | @InjectView(R.id.toolbar)
44 | Toolbar mToolbar;
45 |
46 | @InjectView(R.id.material_tabs)
47 | MaterialTabs mMaterialTabs;
48 |
49 | @InjectView(R.id.view_pager)
50 | ViewPager mViewPager;
51 |
52 | /**
53 | * Intent used to start {@link TabsActivity}.
54 | */
55 | public Intent startTabsActivityIntent;
56 |
57 | /**
58 | * Holds references to fragments from the time they are attached to Activity until they are dettached.
59 | */
60 | private ArrayList mFragments = new ArrayList<>();
61 |
62 | @Override
63 | protected void onCreate(Bundle savedInstanceState) {
64 | super.onCreate(savedInstanceState);
65 | setContentView(R.layout.activity_tabs);
66 | ButterKnife.inject(this);
67 | setSupportActionBar(mToolbar);
68 | getSupportActionBar().setTitle(getString(R.string.title_activity_main));
69 |
70 | // Apply background tinting to the Android system UI when using KitKat translucent modes.
71 | SystemBarTintManager tintManager = new SystemBarTintManager(this);
72 | tintManager.setStatusBarTintEnabled(true);
73 |
74 | startTabsActivityIntent = new Intent(this, TabsActivity.class);
75 |
76 | MainActivityPagerAdapter adapter = new MainActivityPagerAdapter(getSupportFragmentManager());
77 | mViewPager.setAdapter(adapter);
78 |
79 | mMaterialTabs.setViewPager(mViewPager);
80 |
81 | final int pageMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getResources().getDisplayMetrics());
82 | mViewPager.setPageMargin(pageMargin);
83 | mViewPager.setCurrentItem(0);
84 | }
85 |
86 | @Override
87 | public boolean onCreateOptionsMenu(Menu menu) {
88 | // Inflate the menu; this adds items to the action bar if it is present.
89 | getMenuInflater().inflate(R.menu.menu_main, menu);
90 | return true;
91 | }
92 |
93 | @Override
94 | public boolean onOptionsItemSelected(MenuItem item) {
95 | // Handle action bar item clicks here. The action bar will automatically handle clicks on the Home/Up button, so long
96 | // as you specify a parent activity in AndroidManifest.xml.
97 | switch (item.getItemId()) {
98 | case R.id.action_me:
99 | DialogFragment newFragment = new MeDialogFragment();
100 | newFragment.show(getSupportFragmentManager(), "dialog");
101 | return true;
102 | case R.id.action_reset:
103 | AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
104 | alertDialogBuilder.setMessage("Reset everything to default?")
105 | .setCancelable(false)
106 | .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
107 | public void onClick(DialogInterface dialog, int id) {
108 | resetDefaults();
109 | }
110 | })
111 | .setNegativeButton("No", new DialogInterface.OnClickListener() {
112 | public void onClick(DialogInterface dialog, int id) {
113 | dialog.cancel();
114 | }
115 | });
116 | AlertDialog alertDialog = alertDialogBuilder.create();
117 | // show it
118 | alertDialog.show();
119 | return true;
120 | case R.id.action_go:
121 | startActivity(startTabsActivityIntent);
122 | return true;
123 | }
124 |
125 | return super.onOptionsItemSelected(item);
126 | }
127 |
128 | /**
129 | * Resets default values of all the settings in both {@link TabsSettingsFragment} and {@link RippleSettingsFragment}.
130 | */
131 | private void resetDefaults() {
132 | for (ResettableFragment f : mFragments) {
133 | f.setupAndReset();
134 | }
135 | }
136 |
137 | /**
138 | * Add fragment to {@link #mFragments} when attached to Activity.
139 | */
140 | public void addFragment(ResettableFragment f) {
141 | mFragments.add(f);
142 | }
143 |
144 |
145 | /**
146 | * Remove fragment from {@link #mFragments} when detached to Activity.
147 | */
148 | public void removeFragment(ResettableFragment f) {
149 | mFragments.remove(f);
150 | }
151 |
152 | public class MainActivityPagerAdapter extends FragmentPagerAdapter implements MaterialTabs.CustomTabProvider {
153 |
154 | private final String[] TITLES = {"Tabs", "Ripple"};
155 |
156 | private final int[] UNSELECTED_ICONS = {R.drawable.ic_tabs_unselected, R.drawable.ic_ripple_unselected};
157 | private final int[] SELECTED_ICONS = {R.drawable.ic_tabs_selected, R.drawable.ic_ripple_selected};
158 |
159 | public MainActivityPagerAdapter(FragmentManager fm) {
160 | super(fm);
161 | }
162 |
163 | @Override
164 | public CharSequence getPageTitle(int position) {
165 | return TITLES[position];
166 | }
167 |
168 | @Override
169 | public int getCount() {
170 | return TITLES.length;
171 | }
172 |
173 | @Override
174 | public Fragment getItem(int position) {
175 | switch (position) {
176 | case 0:
177 | default:
178 | return new TabsSettingsFragment();
179 | case 1:
180 | return new RippleSettingsFragment();
181 | }
182 | }
183 |
184 | @Override
185 | public View getCustomTabView(ViewGroup parent, int position) {
186 | ImageView imageView = new ImageView(MainActivity.this);
187 | imageView.setImageResource(UNSELECTED_ICONS[position]);
188 | return imageView;
189 | }
190 |
191 | @Override
192 | public void onCustomTabViewSelected(View view, int position, boolean alreadySelected) {
193 | Log.i(TAG, "custom tab view selected with position = " + position);
194 | if (view instanceof ImageView) {
195 | ((ImageView) view).setImageResource(SELECTED_ICONS[position]);
196 | }
197 | }
198 |
199 | @Override
200 | public void onCustomTabViewUnselected(View view, int position, boolean alreadyUnselected) {
201 | Log.i(TAG, "custom tab view unselected with position = " + position);
202 | if (view instanceof ImageView) {
203 | ((ImageView) view).setImageResource(UNSELECTED_ICONS[position]);
204 | }
205 | }
206 | }
207 |
208 |
209 | public static class MeDialogFragment extends DialogFragment {
210 | @Override
211 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
212 | View view = inflater.inflate(R.layout.dialog_me, container, false);
213 | TextView githubTextView = (TextView) view.findViewById(R.id.github_text_view);
214 | TextView twitterTextView = (TextView) view.findViewById(R.id.twitter_text_view);
215 |
216 | String link = getString(R.string.github);
217 | Spannable spannable = new SpannableString(link);
218 | spannable.setSpan(new URLSpan(getString(R.string.github_link)), 0, link.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
219 | githubTextView.setText(spannable, TextView.BufferType.SPANNABLE);
220 | githubTextView.setMovementMethod(LinkMovementMethod.getInstance());
221 |
222 | link = getString(R.string.twitter);
223 | spannable = new SpannableString(link);
224 | spannable.setSpan(new URLSpan(getString(R.string.twitter_link)), 0, link.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
225 | twitterTextView.setText(spannable, TextView.BufferType.SPANNABLE);
226 | twitterTextView.setMovementMethod(LinkMovementMethod.getInstance());
227 |
228 | getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
229 | return view;
230 | }
231 | }
232 | }
233 |
--------------------------------------------------------------------------------
/sample/src/io/karim/materialtabs/sample/MyApplication.java:
--------------------------------------------------------------------------------
1 | package io.karim.materialtabs.sample;
2 |
3 | import com.crashlytics.android.Crashlytics;
4 |
5 | import android.app.Application;
6 |
7 | import io.fabric.sdk.android.Fabric;
8 |
9 | /**
10 | * Created by karim on 5/20/15.
11 | */
12 | public class MyApplication extends Application {
13 |
14 | /**
15 | * Called when the application is starting, before any activity, service, or receiver objects (excluding content providers) have been created.
16 | * Implementations should be as quick as possible (for example using lazy initialization of state) since the time spent in this function directly
17 | * impacts the performance of starting the first activity, service, or receiver in a process. If you override this method, be sure to call
18 | * super.onCreate().
19 | */
20 | @Override
21 | public void onCreate() {
22 | super.onCreate();
23 | Fabric.with(this, new Crashlytics());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/sample/src/io/karim/materialtabs/sample/ResettableFragment.java:
--------------------------------------------------------------------------------
1 | package io.karim.materialtabs.sample;
2 |
3 | public interface ResettableFragment {
4 | void setupAndReset();
5 | }
6 |
--------------------------------------------------------------------------------
/sample/src/io/karim/materialtabs/sample/RippleSettingsFragment.java:
--------------------------------------------------------------------------------
1 | package io.karim.materialtabs.sample;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.support.v4.app.Fragment;
6 | import android.support.v7.app.AlertDialog;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.CheckBox;
11 | import android.widget.CompoundButton;
12 | import android.widget.RadioButton;
13 | import android.widget.RadioGroup;
14 | import android.widget.SeekBar;
15 | import android.widget.TextView;
16 |
17 | import butterknife.ButterKnife;
18 | import butterknife.InjectView;
19 | import butterknife.OnClick;
20 | import io.karim.MaterialRippleLayout;
21 |
22 | public class RippleSettingsFragment extends Fragment implements ResettableFragment {
23 |
24 | public static final String RIPPLE_DURATION = "RIPPLE_DURATION";
25 | public static final String RIPPLE_ALPHA_FLOAT = "RIPPLE_ALPHA_FLOAT";
26 | public static final String RIPPLE_COLOR = "RIPPLE_COLOR";
27 | public static final String RIPPLE_DELAY_CLICK = "RIPPLE_DELAY_CLICK";
28 | public static final String RIPPLE_DIAMETER = "RIPPLE_DIAMETER";
29 | public static final String RIPPLE_FADE_DURATION = "RIPPLE_FADE_DURATION";
30 | public static final String RIPPLE_HIGHLIGHT_COLOR = "RIPPLE_HIGHLIGHT_COLOR";
31 | public static final String RIPPLE_OVERLAY = "RIPPLE_OVERLAY";
32 | public static final String RIPPLE_PERSISTENT = "RIPPLE_PERSISTENT";
33 | public static final String RIPPLE_ROUNDED_CORNERS_RADIUS = "RIPPLE_ROUNDED_CORNERS_RADIUS";
34 |
35 | private static final int RIPPLE_DURATION_MULTIPLIER = 50;
36 |
37 | private MainActivity mainActivity;
38 |
39 | int rippleDurationMs;
40 | float rippleAlphaFloat;
41 | int rippleFadeDurationMs;
42 | int rippleRoundedCornersRadiusDp;
43 | float rippleDiameterDp;
44 |
45 | // Ripple Duration
46 | @InjectView(R.id.rippleDurationSeekBar)
47 | SeekBar rippleDurationSeekBar;
48 | @InjectView(R.id.rippleDurationTextView)
49 | TextView rippleDurationTextView;
50 |
51 | // Ripple Alpha Float
52 | @InjectView(R.id.rippleAlphaFloatSeekBar)
53 | SeekBar rippleAlphaFloatSeekBar;
54 | @InjectView(R.id.rippleAlphaFloatTextView)
55 | TextView rippleAlphaFloatTextView;
56 |
57 | // Ripple Color
58 | @InjectView(R.id.rippleColorRadioGroup)
59 | RadioGroup rippleColorRadioGroup;
60 | @InjectView(R.id.rippleColorButtonWhite)
61 | RadioButton rippleColorButtonWhite;
62 |
63 | // Ripple Delay Click
64 | @InjectView(R.id.rippleDelayClickCheckBox)
65 | CheckBox rippleDelayClickCheckBox;
66 |
67 | // Ripple Diameter
68 | @InjectView(R.id.rippleDiameterSeekBar)
69 | SeekBar rippleDiameterSeekBar;
70 | @InjectView(R.id.rippleDiameterTextView)
71 | TextView rippleDiameterTextView;
72 |
73 | // Ripple Fade Duration
74 | @InjectView(R.id.rippleFadeDurationSeekBar)
75 | SeekBar rippleFadeDurationSeekBar;
76 | @InjectView(R.id.rippleFadeDurationTextView)
77 | TextView rippleFadeDurationTextView;
78 |
79 | // Ripple Highlight Color
80 | @InjectView(R.id.rippleHighlightColorRadioGroup)
81 | RadioGroup rippleHighlightColorRadioGroup;
82 | @InjectView(R.id.rippleHighlightColorButtonWhite)
83 | RadioButton rippleHighlightColorButtonWhite;
84 |
85 | // Ripple Overlay
86 | @InjectView(R.id.rippleOverlayCheckBox)
87 | CheckBox rippleOverlayCheckBox;
88 |
89 | // Ripple Persistent
90 | @InjectView(R.id.ripplePersistentCheckBox)
91 | CheckBox ripplePersistentCheckBox;
92 |
93 | // Ripple Rounded Corners Radius
94 | @InjectView(R.id.rippleRoundedCornersRadiusSeekBar)
95 | SeekBar rippleRoundedCornersRadiusSeekBar;
96 | @InjectView(R.id.rippleRoundedCornersRadiusTextView)
97 | TextView rippleRoundedCornersRadiusTextView;
98 |
99 | @Override
100 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
101 | View rootView = inflater.inflate(R.layout.fragment_ripple_settings, container, false);
102 | ButterKnife.inject(this, rootView);
103 |
104 | setupAndReset();
105 | return rootView;
106 | }
107 |
108 | @Override
109 | public void onAttach(Activity activity) {
110 | super.onAttach(activity);
111 | mainActivity = (MainActivity) getActivity();
112 | mainActivity.addFragment(this);
113 | }
114 |
115 | @Override
116 | public void onDetach() {
117 | mainActivity.removeFragment(this);
118 | super.onDetach();
119 | }
120 |
121 | @Override
122 | public void setupAndReset() {
123 | /** SeekBars **/
124 |
125 | rippleDurationMs = MaterialRippleLayout.DEFAULT_DURATION;
126 | rippleDurationTextView.setText(getString(R.string.ripple_duration) + ": " + rippleDurationMs + "ms");
127 | rippleDurationSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
128 | @Override
129 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
130 | rippleDurationMs = progress * RIPPLE_DURATION_MULTIPLIER;
131 | rippleDurationTextView.setText(getString(R.string.ripple_duration) + ": " + rippleDurationMs + "ms");
132 | mainActivity.startTabsActivityIntent.putExtra(RIPPLE_DURATION, rippleDurationMs);
133 | }
134 |
135 | @Override
136 | public void onStartTrackingTouch(SeekBar seekBar) {
137 | }
138 |
139 | @Override
140 | public void onStopTrackingTouch(SeekBar seekBar) {
141 | }
142 | });
143 |
144 | rippleAlphaFloat = MaterialRippleLayout.DEFAULT_ALPHA;
145 | rippleAlphaFloatTextView.setText(getString(R.string.ripple_alpha_float) + ": " + rippleAlphaFloat);
146 | rippleAlphaFloatSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
147 | @Override
148 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
149 | rippleAlphaFloat = (float) progress / rippleAlphaFloatSeekBar.getMax();
150 | rippleAlphaFloatTextView.setText(getString(R.string.ripple_alpha_float) + ": " + rippleAlphaFloat);
151 | mainActivity.startTabsActivityIntent.putExtra(RIPPLE_ALPHA_FLOAT, rippleAlphaFloat);
152 | }
153 |
154 | @Override
155 | public void onStartTrackingTouch(SeekBar seekBar) {
156 | }
157 |
158 | @Override
159 | public void onStopTrackingTouch(SeekBar seekBar) {
160 | }
161 | });
162 |
163 | rippleFadeDurationMs = MaterialRippleLayout.DEFAULT_FADE_DURATION;
164 | rippleFadeDurationTextView.setText(getString(R.string.ripple_fade_duration) + ": " + rippleFadeDurationMs + "ms");
165 | rippleFadeDurationSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
166 | @Override
167 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
168 | rippleFadeDurationMs = progress * RIPPLE_DURATION_MULTIPLIER;
169 | rippleFadeDurationTextView.setText(getString(R.string.ripple_fade_duration) + ": " + rippleFadeDurationMs + "ms");
170 | mainActivity.startTabsActivityIntent.putExtra(RIPPLE_FADE_DURATION, rippleFadeDurationMs);
171 | }
172 |
173 | @Override
174 | public void onStartTrackingTouch(SeekBar seekBar) {
175 | }
176 |
177 | @Override
178 | public void onStopTrackingTouch(SeekBar seekBar) {
179 | }
180 | });
181 |
182 | rippleRoundedCornersRadiusDp = MaterialRippleLayout.DEFAULT_ROUNDED_CORNERS_DP;
183 | rippleRoundedCornersRadiusTextView.setText(getString(R.string.ripple_rounded_corners_radius) + ": " + rippleRoundedCornersRadiusDp + "dp");
184 | rippleRoundedCornersRadiusSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
185 | @Override
186 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
187 | rippleRoundedCornersRadiusDp = progress;
188 | rippleRoundedCornersRadiusTextView.setText(
189 | getString(R.string.ripple_rounded_corners_radius) + ": " + rippleRoundedCornersRadiusDp + "dp");
190 | mainActivity.startTabsActivityIntent.putExtra(RIPPLE_ROUNDED_CORNERS_RADIUS, rippleRoundedCornersRadiusDp);
191 | }
192 |
193 | @Override
194 | public void onStartTrackingTouch(SeekBar seekBar) {
195 | }
196 |
197 | @Override
198 | public void onStopTrackingTouch(SeekBar seekBar) {
199 | }
200 | });
201 |
202 | rippleDiameterDp = MaterialRippleLayout.DEFAULT_DIAMETER_DP;
203 | rippleDiameterTextView.setText(getString(R.string.ripple_diameter) + ": " + rippleDiameterDp + "dp");
204 | rippleDiameterSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
205 | @Override
206 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
207 | rippleDiameterDp = progress;
208 | rippleDiameterTextView.setText(getString(R.string.ripple_diameter) + ": " + rippleDiameterDp + "dp");
209 | mainActivity.startTabsActivityIntent.putExtra(RIPPLE_DIAMETER, rippleDiameterDp);
210 | }
211 |
212 | @Override
213 | public void onStartTrackingTouch(SeekBar seekBar) {
214 | }
215 |
216 | @Override
217 | public void onStopTrackingTouch(SeekBar seekBar) {
218 | }
219 | });
220 |
221 | rippleDurationSeekBar.setProgress(rippleDurationMs / RIPPLE_DURATION_MULTIPLIER);
222 | rippleAlphaFloatSeekBar.setProgress((int) (rippleAlphaFloat * rippleAlphaFloatSeekBar.getMax()));
223 | rippleFadeDurationSeekBar.setProgress(rippleFadeDurationMs / RIPPLE_DURATION_MULTIPLIER);
224 | rippleRoundedCornersRadiusSeekBar.setProgress(rippleRoundedCornersRadiusDp);
225 | rippleDiameterSeekBar.setProgress((int) rippleDiameterDp);
226 |
227 | /** RadioGroups **/
228 |
229 | // Ripple Color
230 | rippleColorRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
231 | @Override
232 | public void onCheckedChanged(RadioGroup group, int checkedId) {
233 | String key = RIPPLE_COLOR;
234 | switch (checkedId) {
235 | case R.id.rippleColorButtonFireEngineRed:
236 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.fire_engine_red);
237 | break;
238 | case R.id.rippleColorButtonGorse:
239 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.gorse);
240 | break;
241 | case R.id.rippleColorButtonIrisBlue:
242 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.iris_blue);
243 | break;
244 | case R.id.rippleColorButtonSafetyOrange:
245 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.safety_orange);
246 | break;
247 | case R.id.rippleColorButtonWhite:
248 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.white);
249 | break;
250 | case R.id.rippleColorButtonBlack:
251 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.black);
252 | break;
253 | case R.id.rippleColorButtonMantis:
254 | default:
255 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.mantis);
256 | break;
257 | }
258 | }
259 | });
260 |
261 | // Ripple Highlight Color
262 | rippleHighlightColorRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
263 | @Override
264 | public void onCheckedChanged(RadioGroup group, int checkedId) {
265 | String key = RIPPLE_HIGHLIGHT_COLOR;
266 | switch (checkedId) {
267 | case R.id.rippleHighlightColorButtonFireEngineRed:
268 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.fire_engine_red_75);
269 | break;
270 | case R.id.rippleHighlightColorButtonGorse:
271 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.gorse_75);
272 | break;
273 | case R.id.rippleHighlightColorButtonIrisBlue:
274 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.iris_blue_75);
275 | break;
276 | case R.id.rippleHighlightColorButtonSafetyOrange:
277 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.safety_orange_75);
278 | break;
279 | case R.id.rippleHighlightColorButtonWhite:
280 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.white_75);
281 | break;
282 | case R.id.rippleHighlightColorButtonBlack:
283 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.black_75);
284 | break;
285 | case R.id.rippleHighlightColorButtonMantis:
286 | default:
287 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.mantis_75);
288 | break;
289 | }
290 | }
291 | });
292 |
293 | rippleColorButtonWhite.setChecked(true);
294 | rippleHighlightColorButtonWhite.setChecked(true);
295 |
296 | /** Checkboxes **/
297 |
298 | rippleDelayClickCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
299 | @Override
300 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
301 | mainActivity.startTabsActivityIntent.putExtra(RippleSettingsFragment.RIPPLE_DELAY_CLICK, isChecked);
302 | }
303 | });
304 |
305 | ripplePersistentCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
306 | @Override
307 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
308 | mainActivity.startTabsActivityIntent.putExtra(RippleSettingsFragment.RIPPLE_PERSISTENT, isChecked);
309 | }
310 | });
311 |
312 | rippleOverlayCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
313 | @Override
314 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
315 | mainActivity.startTabsActivityIntent.putExtra(RippleSettingsFragment.RIPPLE_OVERLAY, isChecked);
316 | }
317 | });
318 |
319 | rippleDelayClickCheckBox.setChecked(MaterialRippleLayout.DEFAULT_DELAY_CLICK);
320 | ripplePersistentCheckBox.setChecked(MaterialRippleLayout.DEFAULT_PERSISTENT);
321 | rippleOverlayCheckBox.setChecked(MaterialRippleLayout.DEFAULT_RIPPLE_OVERLAY);
322 | }
323 |
324 | @OnClick(R.id.rippleAlphaFloatInfoButton)
325 | public void rippleAlphaFloatInfoButtonClicked() {
326 | new AlertDialog.Builder(getActivity()).setTitle(R.string.ripple_alpha_float).setMessage(R.string.ripple_alpha_float_details).create().show();
327 | }
328 |
329 | @OnClick(R.id.rippleColorInfoButton)
330 | public void rippleColorInfoButtonClicked() {
331 | new AlertDialog.Builder(getActivity()).setTitle(R.string.ripple_color).setMessage(R.string.ripple_color_details).create().show();
332 | }
333 |
334 | @OnClick(R.id.rippleDiameterInfoButton)
335 | public void rippleDiameterInfoButtonClicked() {
336 | new AlertDialog.Builder(getActivity()).setTitle(R.string.ripple_diameter).setMessage(R.string.ripple_diameter_details).create().show();
337 | }
338 |
339 | @OnClick(R.id.rippleDurationInfoButton)
340 | public void rippleDurationInfoButtonClicked() {
341 | new AlertDialog.Builder(getActivity()).setTitle(R.string.ripple_duration).setMessage(R.string.ripple_duration_details).create().show();
342 | }
343 |
344 | @OnClick(R.id.rippleDelayClickInfoButton)
345 | public void rippleDelayClickInfoButtonClicked() {
346 | new AlertDialog.Builder(getActivity()).setTitle(R.string.ripple_delay_click).setMessage(R.string.ripple_delay_click_details).create().show();
347 | }
348 |
349 | @OnClick(R.id.rippleFadeDurationInfoButton)
350 | public void rippleFadeDurationInfoButtonClicked() {
351 | new AlertDialog.Builder(getActivity()).setTitle(R.string.ripple_fade_duration)
352 | .setMessage(R.string.ripple_fade_duration_details)
353 | .create()
354 | .show();
355 | }
356 |
357 | @OnClick(R.id.rippleOverlayInfoButton)
358 | public void rippleOverlayInfoButtonClicked() {
359 | new AlertDialog.Builder(getActivity()).setTitle(R.string.ripple_overlay).setMessage(R.string.ripple_overlay_details).create().show();
360 | }
361 |
362 | @OnClick(R.id.ripplePersistentInfoButton)
363 | public void ripplePersistentInfoButtonClicked() {
364 | new AlertDialog.Builder(getActivity()).setTitle(R.string.ripple_persistent).setMessage(R.string.ripple_persistent_details).create().show();
365 | }
366 |
367 | @OnClick(R.id.rippleHighlightColorInfoButton)
368 | public void rippleHighlightColorInfoButtonClicked() {
369 | new AlertDialog.Builder(getActivity()).setTitle(R.string.ripple_highlight_color)
370 | .setMessage(R.string.ripple_highlight_color_details)
371 | .create()
372 | .show();
373 | }
374 |
375 | @OnClick(R.id.rippleRoundedCornersRadiusInfoButton)
376 | public void rippleRoundedCornersRadiusInfoButtonClicked() {
377 | new AlertDialog.Builder(getActivity()).setTitle(R.string.ripple_rounded_corners_radius)
378 | .setMessage(R.string.ripple_rounded_corners_radius_details)
379 | .create()
380 | .show();
381 | }
382 | }
383 |
--------------------------------------------------------------------------------
/sample/src/io/karim/materialtabs/sample/SampleFragment.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 io.karim.materialtabs.sample;
18 |
19 |
20 | import android.os.Bundle;
21 | import android.support.v4.app.Fragment;
22 | import android.support.v4.view.ViewCompat;
23 | import android.view.LayoutInflater;
24 | import android.view.View;
25 | import android.view.ViewGroup;
26 | import android.widget.TextView;
27 |
28 | import butterknife.ButterKnife;
29 | import butterknife.InjectView;
30 |
31 | public class SampleFragment extends Fragment {
32 |
33 | private static final String ARG_POSITION = "position";
34 |
35 | @InjectView(R.id.textView)
36 | TextView mTextView;
37 |
38 | private int position;
39 |
40 | public static SampleFragment newInstance(int position) {
41 | SampleFragment f = new SampleFragment();
42 | Bundle b = new Bundle();
43 | b.putInt(ARG_POSITION, position);
44 | f.setArguments(b);
45 | return f;
46 | }
47 |
48 | @Override
49 | public void onCreate(Bundle savedInstanceState) {
50 | super.onCreate(savedInstanceState);
51 | position = getArguments().getInt(ARG_POSITION);
52 | }
53 |
54 | @Override
55 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
56 | View rootView = inflater.inflate(R.layout.fragment_card, container, false);
57 | ButterKnife.inject(this, rootView);
58 | ViewCompat.setElevation(rootView, 50);
59 | mTextView.setText("Fragment #" + position);
60 | return rootView;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/sample/src/io/karim/materialtabs/sample/TabsActivity.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 io.karim.materialtabs.sample;
18 |
19 | import com.readystatesoftware.systembartint.SystemBarTintManager;
20 |
21 | import android.annotation.TargetApi;
22 | import android.content.Context;
23 | import android.content.Intent;
24 | import android.content.res.Resources;
25 | import android.graphics.Color;
26 | import android.graphics.Typeface;
27 | import android.graphics.drawable.Drawable;
28 | import android.os.Build;
29 | import android.os.Bundle;
30 | import android.support.annotation.DrawableRes;
31 | import android.support.v4.app.Fragment;
32 | import android.support.v4.app.FragmentManager;
33 | import android.support.v4.app.FragmentPagerAdapter;
34 | import android.support.v4.view.ViewPager;
35 | import android.support.v7.app.AppCompatActivity;
36 | import android.support.v7.widget.Toolbar;
37 | import android.util.Log;
38 | import android.util.TypedValue;
39 | import android.view.Menu;
40 | import android.view.MenuItem;
41 | import android.view.View;
42 | import android.view.Window;
43 | import android.view.WindowManager;
44 |
45 | import java.util.ArrayList;
46 |
47 | import butterknife.ButterKnife;
48 | import butterknife.InjectView;
49 | import io.karim.MaterialTabs;
50 | import io.karim.Utils;
51 |
52 | public class TabsActivity extends AppCompatActivity {
53 |
54 | private static final String TAG = TabsActivity.class.getSimpleName();
55 |
56 | @InjectView(R.id.toolbar)
57 | Toolbar mToolbar;
58 |
59 | @InjectView(R.id.material_tabs)
60 | MaterialTabs mMaterialTabs;
61 |
62 | @InjectView(R.id.view_pager)
63 | ViewPager mViewPager;
64 |
65 | private String mExportableString;
66 |
67 | @Override
68 | protected void onCreate(Bundle savedInstanceState) {
69 | super.onCreate(savedInstanceState);
70 | setContentView(R.layout.activity_tabs);
71 | ButterKnife.inject(this);
72 | setSupportActionBar(mToolbar);
73 |
74 | // Setting navigation icon
75 | mToolbar.setNavigationIcon(getDrawable(this, R.drawable.ic_navigation_arrow_back_white));
76 |
77 | // Setting this navigation icon's onClickListener
78 | mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
79 | @Override
80 | public void onClick(View v) {
81 | onBackPressed();
82 | }
83 | });
84 |
85 | // Apply background tinting to the Android system UI when using KitKat translucent modes.
86 | SystemBarTintManager tintManager = new SystemBarTintManager(this);
87 | tintManager.setStatusBarTintEnabled(true);
88 |
89 | int numberOfTabs = 3;
90 | if (getIntent() != null && getIntent().getExtras() != null) {
91 | numberOfTabs = getIntent().getExtras().getInt(TabsSettingsFragment.NUMBER_OF_TABS);
92 | }
93 |
94 | SamplePagerAdapter adapter = new SamplePagerAdapter(getSupportFragmentManager(), numberOfTabs);
95 | mViewPager.setAdapter(adapter);
96 |
97 | mMaterialTabs.setViewPager(mViewPager);
98 |
99 | mMaterialTabs.setOnTabSelectedListener(new MaterialTabs.OnTabSelectedListener() {
100 | @Override
101 | public void onTabSelected(int position) {
102 | Log.i(TAG, "onTabSelected called with position " + position);
103 | }
104 | });
105 |
106 | mMaterialTabs.setOnTabReselectedListener(new MaterialTabs.OnTabReselectedListener() {
107 | @Override
108 | public void onTabReselected(int position) {
109 | Log.i(TAG, "onTabReselected called with position " + position);
110 | }
111 | });
112 |
113 | applyParametersFromIntentExtras();
114 |
115 | final int pageMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getResources().getDisplayMetrics());
116 | mViewPager.setPageMargin(pageMargin);
117 | }
118 |
119 | @Override
120 | public boolean onCreateOptionsMenu(Menu menu) {
121 | // Inflate the menu; this adds items to the action bar if it is present.
122 | getMenuInflater().inflate(R.menu.menu_tabs, menu);
123 | return true;
124 | }
125 |
126 | @Override
127 | public boolean onOptionsItemSelected(MenuItem item) {
128 | // Handle action bar item clicks here. The action bar will automatically handle clicks on the Home/Up button, so long
129 | // as you specify a parent activity in AndroidManifest.xml.
130 | switch (item.getItemId()) {
131 | case R.id.action_share:
132 | Intent sendIntent = new Intent();
133 | sendIntent.setAction(Intent.ACTION_SEND);
134 | sendIntent.putExtra(Intent.EXTRA_TEXT, mExportableString);
135 | sendIntent.setType("text/plain");
136 | startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));
137 | return true;
138 | }
139 |
140 | return super.onOptionsItemSelected(item);
141 | }
142 |
143 | private void applyParametersFromIntentExtras() {
144 | Intent intent = getIntent();
145 | if (intent != null) {
146 | Bundle extras = intent.getExtras();
147 | if (extras != null) {
148 | Resources resources = getResources();
149 |
150 | int showToolbar = extras.getBoolean(TabsSettingsFragment.SHOW_TOOLBAR) ? View.VISIBLE : View.GONE;
151 | int indicatorColor = resources.getColor(extras.getInt(TabsSettingsFragment.INDICATOR_COLOR));
152 | int underlineColor = resources.getColor(extras.getInt(TabsSettingsFragment.UNDERLINE_COLOR));
153 | int indicatorHeightDp = extras.getInt(TabsSettingsFragment.INDICATOR_HEIGHT);
154 | int underlineHeightDp = extras.getInt(TabsSettingsFragment.UNDERLINE_HEIGHT);
155 | int tabPaddingDp = extras.getInt(TabsSettingsFragment.TAB_PADDING);
156 |
157 | mToolbar.setVisibility(showToolbar);
158 |
159 | mMaterialTabs.setIndicatorColor(indicatorColor);
160 | mMaterialTabs.setUnderlineColor(underlineColor);
161 | mMaterialTabs.setIndicatorHeight(Utils.dpToPx(resources, indicatorHeightDp));
162 | mMaterialTabs.setUnderlineHeight(Utils.dpToPx(resources, underlineHeightDp));
163 | mMaterialTabs.setTabPaddingLeftRight(Utils.dpToPx(resources, tabPaddingDp));
164 |
165 | boolean paddingMiddle = extras.getBoolean(TabsSettingsFragment.PADDING_MIDDLE);
166 | boolean sameWeightTabs = extras.getBoolean(TabsSettingsFragment.SAME_WEIGHT_TABS);
167 | boolean textAllCaps = extras.getBoolean(TabsSettingsFragment.TEXT_ALL_CAPS);
168 |
169 | mMaterialTabs.setPaddingMiddle(paddingMiddle);
170 | mMaterialTabs.setSameWeightTabs(sameWeightTabs);
171 | mMaterialTabs.setAllCaps(textAllCaps);
172 |
173 | int toolbarColor = resources.getColor(extras.getInt(TabsSettingsFragment.TOOLBAR_BACKGROUND));
174 | int tabBackgroundColor = resources.getColor(extras.getInt(TabsSettingsFragment.TAB_BACKGROUND));
175 | mToolbar.setBackgroundColor(toolbarColor);
176 | mMaterialTabs.setBackgroundColor(tabBackgroundColor);
177 |
178 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
179 | Window window = getWindow();
180 | window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
181 | window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
182 | window.setStatusBarColor(Color.argb(Color.alpha(toolbarColor), Color.red(toolbarColor) / 2, Color.green(toolbarColor) / 2,
183 | Color.blue(toolbarColor) / 2));
184 | }
185 |
186 | int textColorSelected = resources.getColor(extras.getInt(TabsSettingsFragment.TEXT_COLOR_SELECTED));
187 | int textColorUnselected = resources.getColor(extras.getInt(TabsSettingsFragment.TEXT_COLOR_UNSELECTED));
188 |
189 | mMaterialTabs.setTextColorSelected(textColorSelected);
190 | mMaterialTabs.setTextColorUnselected(textColorUnselected);
191 |
192 | int rippleDuration = extras.getInt(RippleSettingsFragment.RIPPLE_DURATION);
193 | float rippleAlphaFloat = extras.getFloat(RippleSettingsFragment.RIPPLE_ALPHA_FLOAT);
194 | int rippleColor = resources.getColor(extras.getInt(RippleSettingsFragment.RIPPLE_COLOR));
195 | boolean rippleDelayClick = extras.getBoolean(RippleSettingsFragment.RIPPLE_DELAY_CLICK);
196 | float rippleDiameterDp = extras.getFloat(RippleSettingsFragment.RIPPLE_DIAMETER);
197 | int rippleFadeDuration = extras.getInt(RippleSettingsFragment.RIPPLE_FADE_DURATION);
198 | int rippleHighlightColor = resources.getColor(extras.getInt(RippleSettingsFragment.RIPPLE_HIGHLIGHT_COLOR));
199 | boolean rippleOverlay = extras.getBoolean(RippleSettingsFragment.RIPPLE_OVERLAY);
200 | boolean ripplePersistent = extras.getBoolean(RippleSettingsFragment.RIPPLE_PERSISTENT);
201 | int rippleRoundedCornusRadiusDp = extras.getInt(RippleSettingsFragment.RIPPLE_ROUNDED_CORNERS_RADIUS);
202 |
203 | mMaterialTabs.setRippleDuration(rippleDuration);
204 | mMaterialTabs.setRippleAlphaFloat(rippleAlphaFloat);
205 | mMaterialTabs.setRippleColor(rippleColor);
206 | mMaterialTabs.setRippleDelayClick(rippleDelayClick);
207 | mMaterialTabs.setRippleDiameterDp(rippleDiameterDp);
208 | mMaterialTabs.setRippleFadeDuration(rippleFadeDuration);
209 | mMaterialTabs.setRippleHighlightColor(rippleHighlightColor);
210 | mMaterialTabs.setRippleInAdapter(false);
211 | mMaterialTabs.setRippleOverlay(rippleOverlay);
212 | mMaterialTabs.setRipplePersistent(ripplePersistent);
213 | mMaterialTabs.setRippleRoundedCornersDp(rippleRoundedCornusRadiusDp);
214 |
215 | mExportableString = createExportableText(showToolbar, indicatorColor, underlineColor, indicatorHeightDp, underlineHeightDp,
216 | tabPaddingDp, paddingMiddle, sameWeightTabs, textAllCaps, toolbarColor, tabBackgroundColor, textColorSelected,
217 | textColorUnselected, rippleDuration, rippleAlphaFloat, rippleColor, rippleDelayClick,
218 | rippleDiameterDp, rippleFadeDuration, rippleHighlightColor, rippleOverlay, ripplePersistent, rippleRoundedCornusRadiusDp);
219 | }
220 | }
221 | }
222 |
223 | private static String createExportableText(int showToolbar, int indicatorColor, int underlineColor, int indicatorHeightDp, int underlineHeightDp,
224 | int tabPaddingDp, boolean paddingMiddle, boolean sameWeightTabs, boolean textAllCaps, int toolbarColor, int tabBackgroundColor,
225 | int textColorSelected, int textColorUnselected, int rippleDuration, float rippleAlphaFloat,
226 | int rippleColor, boolean rippleDelayClick, float rippleDiameterDp, int rippleFadeDuration, int rippleHighlightColor,
227 | boolean rippleOverlay, boolean ripplePersistent, int rippleRoundedCornusRadiusDp) {
228 |
229 | StringBuilder stringBuilder = new StringBuilder();
230 | stringBuilder.append("");
304 | return stringBuilder.toString();
305 | }
306 |
307 | private static String getStyleFromStyleInt(int styleInt) {
308 | switch (styleInt) {
309 | case Typeface.BOLD:
310 | default:
311 | return "bold";
312 | case Typeface.ITALIC:
313 | return "italic";
314 | case Typeface.NORMAL:
315 | return "normal";
316 | }
317 | }
318 |
319 | /**
320 | * Convenience to use the new getDrawable(...) on Lollipop and the deprecated one on preLollipop.
321 | */
322 | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
323 | private static Drawable getDrawable(Context context, @DrawableRes int drawableResId) {
324 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
325 | return context.getDrawable(drawableResId);
326 | } else {
327 | return context.getResources().getDrawable(drawableResId);
328 | }
329 | }
330 |
331 | public class SamplePagerAdapter extends FragmentPagerAdapter {
332 |
333 | private final String[] TITLES = {"Item One", "Item Two", "Item Three", "Item Four", "Item Five", "Item Six", "Item Seven", "Item Eight",
334 | "Item Nine", "Item Ten", "Item Eleven"};
335 |
336 | private final ArrayList mTitles;
337 |
338 | public SamplePagerAdapter(FragmentManager fm, int numberOfTabs) {
339 | super(fm);
340 | mTitles = new ArrayList<>();
341 | for (int i = 0; i < numberOfTabs; i++) {
342 | mTitles.add(TITLES[i]);
343 | }
344 | }
345 |
346 | @Override
347 | public CharSequence getPageTitle(int position) {
348 | return mTitles.get(position);
349 | }
350 |
351 | @Override
352 | public int getCount() {
353 | return mTitles.size();
354 | }
355 |
356 | @Override
357 | public Fragment getItem(int position) {
358 | return SampleFragment.newInstance(position);
359 | }
360 | }
361 | }
362 |
--------------------------------------------------------------------------------
/sample/src/io/karim/materialtabs/sample/TabsSettingsFragment.java:
--------------------------------------------------------------------------------
1 | package io.karim.materialtabs.sample;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.support.v4.app.Fragment;
6 | import android.support.v7.app.AlertDialog;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.CheckBox;
11 | import android.widget.CompoundButton;
12 | import android.widget.RadioGroup;
13 | import android.widget.SeekBar;
14 | import android.widget.TextView;
15 |
16 | import butterknife.ButterKnife;
17 | import butterknife.InjectView;
18 | import butterknife.OnClick;
19 | import io.karim.materialtabs.sample.ui.RadioButtonCenter;
20 |
21 | public class TabsSettingsFragment extends Fragment implements ResettableFragment {
22 |
23 | public static final String INDICATOR_COLOR = "INDICATOR_COLOR";
24 | public static final String UNDERLINE_COLOR = "UNDERLINE_COLOR";
25 | public static final String INDICATOR_HEIGHT = "INDICATOR_HEIGHT";
26 | public static final String UNDERLINE_HEIGHT = "UNDERLINE_HEIGHT";
27 | public static final String TAB_PADDING = "TAB_PADDING";
28 | public static final String PADDING_MIDDLE = "PADDING_MIDDLE";
29 | public static final String SAME_WEIGHT_TABS = "SAME_WEIGHT_TABS";
30 | public static final String TEXT_ALL_CAPS = "TEXT_ALL_CAPS";
31 | public static final String TAB_BACKGROUND = "TAB_BACKGROUND";
32 | public static final String TOOLBAR_BACKGROUND = "TOOLBAR_BACKGROUND";
33 | public static final String TEXT_COLOR_UNSELECTED = "TEXT_COLOR_UNSELECTED";
34 | public static final String TEXT_COLOR_SELECTED = "TEXT_COLOR_SELECTED";
35 | public static final String SHOW_TOOLBAR = "SHOW_TOOLBAR";
36 | public static final String NUMBER_OF_TABS = "NUMBER_OF_TABS";
37 |
38 | private static final int UNDERLINE_HEIGHT_DEFAULT_DP = 0;
39 | private static final int INDICATOR_HEIGHT_DEFAULT_DP = 2;
40 | private static final int TAB_PADDING_DEFAULT_DP = 12;
41 | private static final int NUMBER_OF_TABS_DEFAULT = 3;
42 |
43 | private MainActivity mainActivity;
44 |
45 | // Indicator Height
46 | @InjectView(R.id.numberOfTabsSeekBar)
47 | SeekBar numberOfTabsSeekBar;
48 | @InjectView(R.id.numberOfTabsTextView)
49 | TextView numberOfTabsTextView;
50 |
51 | // Indicator Color
52 | @InjectView(R.id.indicatorColorRadioGroup)
53 | RadioGroup indicatorColorRadioGroup;
54 | @InjectView(R.id.indicatorColorButtonWhite)
55 | RadioButtonCenter indicatorColorButtonWhite;
56 |
57 | // Underline Color
58 | @InjectView(R.id.underlineColorRadioGroup)
59 | RadioGroup underlineColorRadioGroup;
60 | @InjectView(R.id.underlineColorButtonMantis)
61 | RadioButtonCenter underlineColorButtonMantis;
62 |
63 | // Indicator Height
64 | @InjectView(R.id.indicatorHeightSeekBar)
65 | SeekBar indicatorHeightSeekBar;
66 | @InjectView(R.id.indicatorHeightTextView)
67 | TextView indicatorHeightTextView;
68 |
69 | // Underline Height
70 | @InjectView(R.id.underlineHeightSeekBar)
71 | SeekBar underlineHeightSeekBar;
72 | @InjectView(R.id.underlineHeightTextView)
73 | TextView underlineHeightTextView;
74 |
75 | // Tab Padding Left Right
76 | @InjectView(R.id.tabPaddingSeekBar)
77 | SeekBar tabPaddingSeekBar;
78 | @InjectView(R.id.tabPaddingTextView)
79 | TextView tabPaddingTextView;
80 |
81 | // Padding Middle
82 | @InjectView(R.id.paddingMiddleCheckBox)
83 | CheckBox paddingMiddleCheckBox;
84 |
85 | // Should Expand
86 | @InjectView(R.id.sameWeightTabsCheckBox)
87 | CheckBox sameWeightTabsCheckBox;
88 |
89 | // Text All Caps
90 | @InjectView(R.id.textAllCapsCheckBox)
91 | CheckBox textAllCapsCheckBox;
92 |
93 | // Show Toolbar
94 | @InjectView(R.id.showToolbarCheckBox)
95 | CheckBox showToolbarCheckBox;
96 |
97 | // Tab Text Color
98 | @InjectView(R.id.tabTextColorRadioGroup)
99 | RadioGroup tabTextColorRadioGroup;
100 | @InjectView(R.id.tabTextColorButtonWhite)
101 | RadioButtonCenter tabTextColorButtonWhite;
102 |
103 | // Tab Text Selected Color
104 | @InjectView(R.id.tabTextSelectedColorRadioGroup)
105 | RadioGroup tabTextSelectedColorRadioGroup;
106 | @InjectView(R.id.tabTextSelectedColorButtonWhite)
107 | RadioButtonCenter tabTextSelectedColorButtonWhite;
108 |
109 | // Tab Background Color
110 | @InjectView(R.id.tabBackgroundColorRadioGroup)
111 | RadioGroup tabBackgroundColorRadioGroup;
112 | @InjectView(R.id.tabBackgroundColorButtonFireEngineRed)
113 | RadioButtonCenter tabBackgroundColorButtonFireEngineRed;
114 |
115 | // Toolbar Background Color
116 | @InjectView(R.id.toolbarColorRadioGroup)
117 | RadioGroup toolbarColorRadioGroup;
118 | @InjectView(R.id.toolbarColorButtonFireEngineRed)
119 | RadioButtonCenter toolbarColorButtonFireEngineRed;
120 |
121 | int underlineHeightDp;
122 | int indicatorHeightDp;
123 | int tabPaddingDp;
124 | int numberOfTabs;
125 |
126 | @Override
127 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
128 | View rootView = inflater.inflate(R.layout.fragment_tabs_settings, container, false);
129 | ButterKnife.inject(this, rootView);
130 |
131 | setupAndReset();
132 | return rootView;
133 | }
134 |
135 | @Override
136 | public void onAttach(Activity activity) {
137 | super.onAttach(activity);
138 | mainActivity = (MainActivity) getActivity();
139 | mainActivity.addFragment(this);
140 | }
141 |
142 | @Override
143 | public void onDetach() {
144 | mainActivity.removeFragment(this);
145 | super.onDetach();
146 | }
147 |
148 | @Override
149 | public void setupAndReset() {
150 | /** SeekBars **/
151 |
152 | underlineHeightDp = UNDERLINE_HEIGHT_DEFAULT_DP;
153 | underlineHeightTextView.setText(getString(R.string.underline_height) + ": " + underlineHeightDp + "dp");
154 | underlineHeightSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
155 | @Override
156 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
157 | underlineHeightDp = progress;
158 | underlineHeightTextView.setText(getString(R.string.underline_height) + ": " + underlineHeightDp + "dp");
159 | mainActivity.startTabsActivityIntent.putExtra(UNDERLINE_HEIGHT, underlineHeightDp);
160 | }
161 |
162 | @Override
163 | public void onStartTrackingTouch(SeekBar seekBar) {
164 | }
165 |
166 | @Override
167 | public void onStopTrackingTouch(SeekBar seekBar) {
168 | }
169 | });
170 |
171 | numberOfTabs = NUMBER_OF_TABS_DEFAULT;
172 | numberOfTabsTextView.setText(getString(R.string.number_of_tabs) + ": " + numberOfTabs);
173 | numberOfTabsSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
174 | @Override
175 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
176 | numberOfTabs = progress + 1;
177 | numberOfTabsTextView.setText(getString(R.string.number_of_tabs) + ": " + numberOfTabs);
178 | mainActivity.startTabsActivityIntent.putExtra(NUMBER_OF_TABS, numberOfTabs);
179 | }
180 |
181 | @Override
182 | public void onStartTrackingTouch(SeekBar seekBar) {
183 | }
184 |
185 | @Override
186 | public void onStopTrackingTouch(SeekBar seekBar) {
187 | }
188 | });
189 |
190 | indicatorHeightDp = INDICATOR_HEIGHT_DEFAULT_DP;
191 | indicatorHeightTextView.setText(getString(R.string.indicator_height) + ": " + indicatorHeightDp + "dp");
192 | indicatorHeightSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
193 | @Override
194 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
195 | indicatorHeightDp = progress;
196 | indicatorHeightTextView.setText(getString(R.string.indicator_height) + ": " + indicatorHeightDp + "dp");
197 | mainActivity.startTabsActivityIntent.putExtra(INDICATOR_HEIGHT, indicatorHeightDp);
198 | }
199 |
200 | @Override
201 | public void onStartTrackingTouch(SeekBar seekBar) {
202 | }
203 |
204 | @Override
205 | public void onStopTrackingTouch(SeekBar seekBar) {
206 | }
207 | });
208 |
209 | tabPaddingDp = TAB_PADDING_DEFAULT_DP;
210 | tabPaddingTextView.setText(getString(R.string.tab_padding) + ": " + tabPaddingDp + "dp");
211 | tabPaddingSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
212 | @Override
213 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
214 | tabPaddingDp = progress;
215 | tabPaddingTextView.setText(getString(R.string.tab_padding) + ": " + tabPaddingDp + "dp");
216 | mainActivity.startTabsActivityIntent.putExtra(TAB_PADDING, tabPaddingDp);
217 | }
218 |
219 | @Override
220 | public void onStartTrackingTouch(SeekBar seekBar) {
221 | }
222 |
223 | @Override
224 | public void onStopTrackingTouch(SeekBar seekBar) {
225 | }
226 | });
227 |
228 | underlineHeightSeekBar.setProgress(underlineHeightDp);
229 | numberOfTabsSeekBar.setProgress(numberOfTabs);
230 | indicatorHeightSeekBar.setProgress(indicatorHeightDp);
231 | tabPaddingSeekBar.setProgress(tabPaddingDp);
232 |
233 | /** RadioGroups **/
234 |
235 | // Indicator Color
236 | indicatorColorRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
237 | @Override
238 | public void onCheckedChanged(RadioGroup group, int checkedId) {
239 | String key = INDICATOR_COLOR;
240 | switch (checkedId) {
241 | case R.id.indicatorColorButtonFireEngineRed:
242 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.fire_engine_red);
243 | break;
244 | case R.id.indicatorColorButtonGorse:
245 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.gorse);
246 | break;
247 | case R.id.indicatorColorButtonIrisBlue:
248 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.iris_blue);
249 | break;
250 | case R.id.indicatorColorButtonSafetyOrange:
251 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.safety_orange);
252 | break;
253 | case R.id.indicatorColorButtonWhite:
254 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.white);
255 | break;
256 | case R.id.indicatorColorButtonBlack:
257 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.black);
258 | break;
259 | case R.id.indicatorColorButtonMantis:
260 | default:
261 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.mantis);
262 | break;
263 | }
264 | }
265 | });
266 |
267 | // Underline Color
268 | underlineColorRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
269 | @Override
270 | public void onCheckedChanged(RadioGroup group, int checkedId) {
271 | String key = UNDERLINE_COLOR;
272 | switch (checkedId) {
273 | case R.id.underlineColorButtonFireEngineRed:
274 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.fire_engine_red);
275 | break;
276 | case R.id.underlineColorButtonGorse:
277 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.gorse);
278 | break;
279 | case R.id.underlineColorButtonIrisBlue:
280 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.iris_blue);
281 | break;
282 | case R.id.underlineColorButtonSafetyOrange:
283 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.safety_orange);
284 | break;
285 | case R.id.underlineColorButtonWhite:
286 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.white);
287 | break;
288 | case R.id.underlineColorButtonBlack:
289 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.black);
290 | break;
291 | case R.id.underlineColorButtonMantis:
292 | default:
293 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.mantis);
294 | break;
295 | }
296 | }
297 | });
298 |
299 | // Tab Background Color
300 | tabBackgroundColorRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
301 | @Override
302 | public void onCheckedChanged(RadioGroup group, int checkedId) {
303 | String key = TAB_BACKGROUND;
304 | switch (checkedId) {
305 | case R.id.tabBackgroundColorButtonFireEngineRed:
306 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.fire_engine_red);
307 | break;
308 | case R.id.tabBackgroundColorButtonGorse:
309 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.gorse);
310 | break;
311 | case R.id.tabBackgroundColorButtonIrisBlue:
312 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.iris_blue);
313 | break;
314 | case R.id.tabBackgroundColorButtonSafetyOrange:
315 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.safety_orange);
316 | break;
317 | case R.id.tabBackgroundColorButtonWhite:
318 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.white);
319 | break;
320 | case R.id.tabBackgroundColorButtonBlack:
321 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.black);
322 | break;
323 | case R.id.tabBackgroundColorButtonMantis:
324 | default:
325 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.mantis);
326 | break;
327 | }
328 | }
329 | });
330 |
331 | // Toolbar Background Color
332 | toolbarColorRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
333 | @Override
334 | public void onCheckedChanged(RadioGroup group, int checkedId) {
335 | String key = TOOLBAR_BACKGROUND;
336 | switch (checkedId) {
337 | case R.id.toolbarColorButtonFireEngineRed:
338 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.fire_engine_red);
339 | break;
340 | case R.id.toolbarColorButtonGorse:
341 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.gorse);
342 | break;
343 | case R.id.toolbarColorButtonIrisBlue:
344 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.iris_blue);
345 | break;
346 | case R.id.toolbarColorButtonSafetyOrange:
347 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.safety_orange);
348 | break;
349 | case R.id.toolbarColorButtonWhite:
350 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.white);
351 | break;
352 | case R.id.toolbarColorButtonBlack:
353 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.black);
354 | break;
355 | case R.id.toolbarColorButtonMantis:
356 | default:
357 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.mantis);
358 | break;
359 | }
360 | }
361 | });
362 |
363 | // Text Color Unselected
364 | tabTextColorRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
365 | @Override
366 | public void onCheckedChanged(RadioGroup group, int checkedId) {
367 | String key = TEXT_COLOR_UNSELECTED;
368 | switch (checkedId) {
369 | case R.id.tabTextColorButtonFireEngineRed:
370 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.fire_engine_red);
371 | break;
372 | case R.id.tabTextColorButtonGorse:
373 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.gorse);
374 | break;
375 | case R.id.tabTextColorButtonIrisBlue:
376 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.iris_blue);
377 | break;
378 | case R.id.tabTextColorButtonSafetyOrange:
379 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.safety_orange);
380 | break;
381 | case R.id.tabTextColorButtonWhite:
382 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.white);
383 | break;
384 | case R.id.tabTextColorButtonBlack:
385 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.black);
386 | break;
387 | case R.id.tabTextColorButtonMantis:
388 | default:
389 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.mantis);
390 | break;
391 | }
392 | }
393 | });
394 |
395 | // Text Color Selected
396 | tabTextSelectedColorRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
397 | @Override
398 | public void onCheckedChanged(RadioGroup group, int checkedId) {
399 | String key = TEXT_COLOR_SELECTED;
400 | switch (checkedId) {
401 | case R.id.tabTextSelectedColorButtonFireEngineRed:
402 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.fire_engine_red);
403 | break;
404 | case R.id.tabTextSelectedColorButtonGorse:
405 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.gorse);
406 | break;
407 | case R.id.tabTextSelectedColorButtonIrisBlue:
408 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.iris_blue);
409 | break;
410 | case R.id.tabTextSelectedColorButtonSafetyOrange:
411 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.safety_orange);
412 | break;
413 | case R.id.tabTextSelectedColorButtonWhite:
414 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.white);
415 | break;
416 | case R.id.tabTextSelectedColorButtonBlack:
417 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.black);
418 | break;
419 | case R.id.tabTextSelectedColorButtonMantis:
420 | default:
421 | mainActivity.startTabsActivityIntent.putExtra(key, R.color.mantis);
422 | break;
423 | }
424 | }
425 | });
426 |
427 | indicatorColorButtonWhite.setChecked(true);
428 | underlineColorButtonMantis.setChecked(true);
429 |
430 | tabTextColorButtonWhite.setChecked(true);
431 | tabTextSelectedColorButtonWhite.setChecked(true);
432 |
433 | tabBackgroundColorButtonFireEngineRed.setChecked(true);
434 | toolbarColorButtonFireEngineRed.setChecked(true);
435 |
436 | /** CheckBoxes **/
437 |
438 | // Text Style Unselected
439 | sameWeightTabsCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
440 | @Override
441 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
442 | mainActivity.startTabsActivityIntent.putExtra(SAME_WEIGHT_TABS, isChecked);
443 | }
444 | });
445 |
446 | // Text Style Unselected
447 | paddingMiddleCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
448 | @Override
449 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
450 | mainActivity.startTabsActivityIntent.putExtra(PADDING_MIDDLE, isChecked);
451 | }
452 | });
453 |
454 | // Text Style Unselected
455 | textAllCapsCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
456 | @Override
457 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
458 | mainActivity.startTabsActivityIntent.putExtra(TEXT_ALL_CAPS, isChecked);
459 | }
460 | });
461 |
462 | // Text Style Unselected
463 | showToolbarCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
464 | @Override
465 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
466 | mainActivity.startTabsActivityIntent.putExtra(SHOW_TOOLBAR, isChecked);
467 | }
468 | });
469 |
470 | sameWeightTabsCheckBox.setChecked(true);
471 | paddingMiddleCheckBox.setChecked(false);
472 | textAllCapsCheckBox.setChecked(true);
473 | showToolbarCheckBox.setChecked(true);
474 | }
475 |
476 | @OnClick(R.id.tabPaddingInfoButton)
477 | public void tabPaddingInfoButtonClicked() {
478 | new AlertDialog.Builder(getActivity()).setTitle(R.string.tab_padding).setMessage(R.string.tab_padding_details).create().show();
479 | }
480 |
481 | @OnClick(R.id.tabBackgroundColorInfoButton)
482 | public void tabBackgroundColorInfoButtonClicked() {
483 | new AlertDialog.Builder(getActivity()).setTitle(R.string.tab_background_color)
484 | .setMessage(R.string.tab_background_color_details)
485 | .create()
486 | .show();
487 | }
488 |
489 | @OnClick(R.id.tabTextColorInfoButton)
490 | public void tabTextColorInfoButtonClicked() {
491 | new AlertDialog.Builder(getActivity()).setTitle(R.string.tab_text_color).setMessage(R.string.tab_text_color_details).create().show();
492 | }
493 |
494 | @OnClick(R.id.tabTextSelectedColorInfoButton)
495 | public void tabTextSelectedColorInfoButtonClicked() {
496 | new AlertDialog.Builder(getActivity()).setTitle(R.string.tab_text_selected_color)
497 | .setMessage(R.string.tab_text_selected_color_details)
498 | .create()
499 | .show();
500 | }
501 |
502 | @OnClick(R.id.toolbarColorInfoButton)
503 | public void toolbarColorInfoButtonClicked() {
504 | new AlertDialog.Builder(getActivity()).setTitle(R.string.toolbar_color).setMessage(R.string.toolbar_color_details).create().show();
505 | }
506 |
507 | @OnClick(R.id.textAllCapsInfoButton)
508 | public void textAllCapsInfoButtonClicked() {
509 | new AlertDialog.Builder(getActivity()).setTitle(R.string.text_all_caps).setMessage(R.string.text_all_caps_details).create().show();
510 | }
511 |
512 | @OnClick(R.id.underlineColorInfoButton)
513 | public void underlineColorInfoButtonClicked() {
514 | new AlertDialog.Builder(getActivity()).setTitle(R.string.underline_color).setMessage(R.string.underline_color_details).create().show();
515 | }
516 |
517 | @OnClick(R.id.underlineHeightInfoButton)
518 | public void underlineHeightInfoButtonClicked() {
519 | new AlertDialog.Builder(getActivity()).setTitle(R.string.underline_height).setMessage(R.string.underline_height_details).create().show();
520 | }
521 |
522 | @OnClick(R.id.indicatorColorInfoButton)
523 | public void indicatorColorInfoButtonClicked() {
524 | new AlertDialog.Builder(getActivity()).setTitle(R.string.indicator_color).setMessage(R.string.indicator_color_details).create().show();
525 | }
526 |
527 | @OnClick(R.id.indicatorHeightInfoButton)
528 | public void indicatorHeightInfoButtonClicked() {
529 | new AlertDialog.Builder(getActivity()).setTitle(R.string.indicator_height).setMessage(R.string.indicator_height_details).create().show();
530 | }
531 |
532 |
533 | @OnClick(R.id.paddingMiddleInfoButton)
534 | public void paddingMiddleInfoButtonClicked() {
535 | new AlertDialog.Builder(getActivity()).setTitle(R.string.padding_middle).setMessage(R.string.padding_middle_details).create().show();
536 | }
537 |
538 | @OnClick(R.id.sameWeighTabsInfoButton)
539 | public void sameWeighTabsInfoButtonClicked() {
540 | new AlertDialog.Builder(getActivity()).setTitle(R.string.same_weight_tabs).setMessage(R.string.same_weight_tabs_details).create().show();
541 | }
542 |
543 | @OnClick(R.id.showToolbarInfoButton)
544 | public void showToolbarInfoButtonClicked() {
545 | new AlertDialog.Builder(getActivity()).setTitle(R.string.show_toolbar).setMessage(R.string.show_toolbar_details).create().show();
546 | }
547 |
548 | @OnClick(R.id.numberOfTabsInfoButton)
549 | public void numberOfTabsInfoButtonClicked() {
550 | new AlertDialog.Builder(getActivity()).setTitle(R.string.number_of_tabs).setMessage(R.string.number_of_tabs_details).create().show();
551 | }
552 | }
553 |
--------------------------------------------------------------------------------
/sample/src/io/karim/materialtabs/sample/ui/RadioButtonCenter.java:
--------------------------------------------------------------------------------
1 | package io.karim.materialtabs.sample.ui;
2 |
3 |
4 | import android.content.Context;
5 | import android.content.res.TypedArray;
6 | import android.graphics.Canvas;
7 | import android.graphics.drawable.Drawable;
8 | import android.support.annotation.NonNull;
9 | import android.util.AttributeSet;
10 | import android.view.Gravity;
11 | import android.widget.RadioButton;
12 |
13 | import io.karim.materialtabs.sample.R;
14 |
15 | public class RadioButtonCenter extends RadioButton {
16 |
17 | final Drawable buttonDrawable;
18 |
19 | public RadioButtonCenter(Context context, AttributeSet attrs) {
20 | super(context, attrs);
21 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CompoundButton, 0, 0);
22 | buttonDrawable = a.getDrawable(1);
23 | a.recycle();
24 | setButtonDrawable(android.R.color.transparent);
25 | }
26 |
27 | @Override
28 | protected void onDraw(@NonNull Canvas canvas) {
29 | super.onDraw(canvas);
30 |
31 | if (buttonDrawable != null) {
32 | buttonDrawable.setState(getDrawableState());
33 | final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
34 | final int height = buttonDrawable.getIntrinsicHeight();
35 |
36 | int y = 0;
37 |
38 | switch (verticalGravity) {
39 | case Gravity.BOTTOM:
40 | y = getHeight() - height;
41 | break;
42 | case Gravity.CENTER_VERTICAL:
43 | y = (getHeight() - height) / 2;
44 | break;
45 | }
46 |
47 | int buttonWidth = buttonDrawable.getIntrinsicWidth();
48 | int buttonLeft = (getWidth() - buttonWidth) / 2;
49 | buttonDrawable.setBounds(buttonLeft, y, buttonLeft + buttonWidth, y + height);
50 | buttonDrawable.draw(canvas);
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/sample/web_hi_res_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pizza/MaterialTabs/24c9bf922f29f0fbb201fb6b8f13d915fd87d322/sample/web_hi_res_512.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include 'library'
2 | include 'sample'
--------------------------------------------------------------------------------