├── .gitignore
├── README.md
├── art
└── square_blue_light.png
├── build.gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── library
├── .gitignore
├── build.gradle
├── gradle.properties
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── ryanharter
│ │ └── android
│ │ └── tooltips
│ │ └── ApplicationTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── ryanharter
│ │ └── android
│ │ └── tooltips
│ │ ├── ToolTip.java
│ │ ├── ToolTipLayout.java
│ │ └── ToolTipPointerView.java
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ └── values
│ └── strings.xml
├── sample
├── .gitignore
├── build.gradle
├── gradle.properties
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── ryanharter
│ │ └── android
│ │ └── tooltips
│ │ └── ApplicationTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── ryanharter
│ │ └── android
│ │ └── tooltips
│ │ └── sample
│ │ └── MyActivity.java
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ ├── bg_tooltip_blue.xml
│ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ ├── layout
│ └── activity_my.xml
│ ├── menu
│ └── my.xml
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | /local.properties
3 | /.idea
4 | .DS_Store
5 | /gradle
6 | /build
7 | *.iml
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Android ToolTips [Play Store Demo](https://play.google.com/store/apps/details?id=com.ryanharter.android.tooltips.sample)
2 |
3 | ToolTips is an Open Source Android library that allows developers to easily display tooltips for views.
4 |
5 | ## Getting It
6 |
7 | Android ToolTips is available on Maven Central, so you can use the normal methods to acquire the library.
8 |
9 | Gradle
10 |
11 | ```
12 | compile 'com.ryanharter.android.tooltips:library:0.0.3'
13 | ```
14 |
15 | Maven
16 |
17 | ```
18 |
19 | com.ryanharter.android.tooltips
20 | library
21 | 0.0.3
22 |
23 | ```
24 |
25 | ## Usage
26 |
27 | 1. Add a `com.ryanharter.android.tooltips.ToolTipLayout` view to your layout such that it fills the view view and overlays everything else.
28 | 1. Create `ToolTip` instances using the `Builder` class.
29 | 1. Add the `ToolTip`s to your view.
30 |
31 | ## Example
32 |
33 | ### layout.xml
34 |
35 | ```xml
36 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
51 |
52 |
53 | ```
54 |
55 | ### Activity.java (or Fragment.java)
56 |
57 | ```java
58 | // Get the tooltip layout
59 | ToolTipLayout tipContainer = (ToolTipLayout) findViewById(R.id.tooltip_container);
60 |
61 | // Create a content view however you'd like
62 | // ...
63 |
64 | // Create a ToolTip using the Builder class
65 | ToolTip t = new Builder(myContext)
66 | .anchor(myAnchorView) // The view to which the ToolTip should be anchored
67 | .gravity(Gravity.TOP) // The location of the view in relation to the anchor (LEFT, RIGHT, TOP, BOTTOM)
68 | .color(Color.RED) // The color of the pointer arrow
69 | .pointerSize(POINTER_SIZE) // The size of the pointer
70 | .contentView(contentView) // The actual contents of the ToolTip
71 | .build();
72 |
73 | // Add the ToolTip to the view, using the default animations
74 | tipContainer.addTooltip(t);
75 | ```
76 |
77 | ## Developed By
78 |
79 | * Ryan Harter
80 |
81 | ## License
82 |
83 | ```
84 | Copyright 2013 Ryan Harter
85 |
86 | Licensed under the Apache License, Version 2.0 (the "License");
87 | you may not use this file except in compliance with the License.
88 | You may obtain a copy of the License at
89 |
90 | http://www.apache.org/licenses/LICENSE-2.0
91 |
92 | Unless required by applicable law or agreed to in writing, software
93 | distributed under the License is distributed on an "AS IS" BASIS,
94 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95 | See the License for the specific language governing permissions and
96 | limitations under the License.
97 | ```
--------------------------------------------------------------------------------
/art/square_blue_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rharter/android-tooltips/5b67e600a5dc8e36792b6cd5ff68bc9160eac385/art/square_blue_light.png
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:0.12.+'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | VERSION_NAME=0.0.4
2 | VERSION_CODE=1
3 | GROUP=com.ryanharter.android.tooltips
4 |
5 | POM_DESCRIPTION=An easy to use library for displaying tooltips in Android.
6 | POM_URL=https://github.com/rharter/android-tooltips
7 | POM_SCM_URL=https://github.com/rharter/android-tooltips
8 | POM_SCM_CONNECTION=scm:git@github.com:rharter/android-tooltips.git
9 | POM_SCM_DEV_CONNECTION=scm:git@github.com:rharter/android-tooltips.git
10 | POM_LICENCE_NAME=The Apache Software License, Version 2.0
11 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
12 | POM_LICENCE_DIST=repo
13 | POM_DEVELOPER_ID=rharter
14 | POM_DEVELOPER_NAME=Ryan Harter
--------------------------------------------------------------------------------
/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/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | // TODO Change this back to the main script once the PR is merged.
3 | apply from: 'https://raw.githubusercontent.com/jpardogo/gradle-mvn-push/master/gradle-mvn-push.gradle'
4 |
5 | android {
6 | compileSdkVersion 20
7 | buildToolsVersion "20.0.0"
8 |
9 | defaultConfig {
10 | applicationId "com.ryanharter.android.tooltips"
11 | minSdkVersion 15
12 | targetSdkVersion 20
13 | versionCode 1
14 | versionName "1.0"
15 | }
16 |
17 | compileOptions {
18 | sourceCompatibility JavaVersion.VERSION_1_7
19 | targetCompatibility JavaVersion.VERSION_1_7
20 | }
21 | buildTypes {
22 | release {
23 | runProguard false
24 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
25 | }
26 | }
27 | }
28 |
29 | dependencies {
30 | compile fileTree(dir: 'libs', include: ['*.jar'])
31 | }
32 |
--------------------------------------------------------------------------------
/library/gradle.properties:
--------------------------------------------------------------------------------
1 | POM_NAME=Android ToolTips Library
2 | POM_ARTIFACT_ID=library
3 | POM_PACKAGING=aar
--------------------------------------------------------------------------------
/library/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/library/src/androidTest/java/com/ryanharter/android/tooltips/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.ryanharter.android.tooltips;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/library/src/main/java/com/ryanharter/android/tooltips/ToolTip.java:
--------------------------------------------------------------------------------
1 | package com.ryanharter.android.tooltips;
2 |
3 | import android.content.Context;
4 | import android.view.Gravity;
5 | import android.view.View;
6 | import android.view.ViewGroup.LayoutParams;
7 | import android.widget.LinearLayout;
8 |
9 | import java.lang.ref.WeakReference;
10 |
11 | /**
12 | * Created by rharter on 7/24/14.
13 | */
14 | public class ToolTip {
15 |
16 | private WeakReference mAnchorView;
17 | private WeakReference mContentView;
18 | private ToolTipPointerView mPointerView;
19 | private int mGravity;
20 | private int mColor;
21 | private int mPointerSize;
22 | private boolean mDismissOnTouch;
23 |
24 | private View mView;
25 |
26 | public View getView() {
27 | return mView;
28 | }
29 |
30 | public void setView(View view) {
31 | mView = view;
32 | }
33 |
34 | public View getAnchorView() {
35 | return mAnchorView != null ? mAnchorView.get() : null;
36 | }
37 |
38 | public void setAnchorView(View anchorView) {
39 | mAnchorView = new WeakReference<>(anchorView);
40 | }
41 |
42 | public View getContentView() {
43 | return mContentView != null ? mContentView.get() : null;
44 | }
45 |
46 | public void setContentView(View view) {
47 | mContentView = new WeakReference(view);
48 | }
49 |
50 | public ToolTipPointerView getPointerView() {
51 | return mPointerView;
52 | }
53 |
54 | public void setPointerView(ToolTipPointerView pointerView) {
55 | mPointerView = pointerView;
56 | }
57 |
58 | public int getGravity() {
59 | return mGravity;
60 | }
61 |
62 | public void setGravity(int gravity) {
63 | mGravity = gravity;
64 | }
65 |
66 | public int getColor() {
67 | return mColor;
68 | }
69 |
70 | public void setColor(int color) {
71 | mColor = color;
72 | }
73 |
74 | public int getPointerSize() {
75 | return mPointerSize;
76 | }
77 |
78 | public void setPointerSize(int pointerSize) {
79 | mPointerSize = pointerSize;
80 | }
81 |
82 | public boolean isDismissOnTouch() {
83 | return mDismissOnTouch;
84 | }
85 |
86 | public void setDismissOnTouch(boolean dismissOnTouch) {
87 | mDismissOnTouch = dismissOnTouch;
88 | }
89 |
90 | /**
91 | * Builds the tooltip view for display. The callout arrow is
92 | * defined by gravity
, but defaults to alignment
93 | * at 0, it's up to the caller to position it appropriately
94 | * @param context The context used to build the view.
95 | * @return The constructed view, with added arrow.
96 | */
97 | public View makeView(Context context) {
98 | LinearLayout layout = new LinearLayout(context);
99 |
100 | // If the tooltip is above or below, we make is fill the view.
101 | if (Gravity.isVertical(mGravity)) {
102 | layout.setLayoutParams(new LayoutParams(
103 | LayoutParams.MATCH_PARENT,
104 | LayoutParams.WRAP_CONTENT));
105 | }
106 |
107 | mPointerView = new ToolTipPointerView(context, mColor, mGravity);
108 |
109 | if (Gravity.isHorizontal(mGravity)) {
110 | mPointerView.setLayoutParams(new LayoutParams(mPointerSize, mPointerSize * 2));
111 | layout.setOrientation(LinearLayout.HORIZONTAL);
112 | } else {
113 | mPointerView.setLayoutParams(new LayoutParams(mPointerSize * 2, mPointerSize));
114 | layout.setOrientation(LinearLayout.VERTICAL);
115 | }
116 |
117 | // For right and bottom alignment, the arrow goes at the beginning
118 | if ((mGravity & Gravity.RIGHT) == Gravity.RIGHT
119 | || (mGravity & Gravity.BOTTOM) == Gravity.BOTTOM) {
120 | layout.addView(mPointerView);
121 | }
122 |
123 | layout.addView(mContentView.get());
124 |
125 | // For left or top alignment, the arrow goes at the end
126 | if ((mGravity & Gravity.LEFT) == Gravity.LEFT || (mGravity & Gravity.TOP) == Gravity.TOP) {
127 | layout.addView(mPointerView);
128 | }
129 |
130 | return layout;
131 | }
132 |
133 | public static class Builder {
134 | private Context context;
135 | private View contentView;
136 | private View anchor;
137 | private int gravity;
138 | private int color;
139 | private int pointerSize;
140 | private boolean dismissOnTouch;
141 |
142 | public Builder(Context context) {
143 | this.context = context;
144 | }
145 |
146 | public Builder contentView(View v) {
147 | contentView = v;
148 | return this;
149 | }
150 |
151 | public Builder gravity(int gravity) {
152 | this.gravity = gravity;
153 | return this;
154 | }
155 |
156 | public Builder color(int color) {
157 | this.color = color;
158 | return this;
159 | }
160 |
161 | public Builder pointerSize(int size) {
162 | this.pointerSize = size;
163 | return this;
164 | }
165 |
166 | public Builder anchor(View anchor) {
167 | this.anchor = anchor;
168 | return this;
169 | }
170 |
171 | public Builder dismissOnTouch(boolean dismiss) {
172 | this.dismissOnTouch = dismiss;
173 | return this;
174 | }
175 |
176 | public ToolTip build() {
177 | return new ToolTip(this);
178 | }
179 | }
180 |
181 | private ToolTip(Builder builder) {
182 | setContentView(builder.contentView);
183 | setGravity(builder.gravity);
184 | setColor(builder.color);
185 | setPointerSize(builder.pointerSize);
186 | setAnchorView(builder.anchor);
187 | setView(makeView(builder.context));
188 | setDismissOnTouch(builder.dismissOnTouch);
189 | }
190 |
191 | }
192 |
--------------------------------------------------------------------------------
/library/src/main/java/com/ryanharter/android/tooltips/ToolTipLayout.java:
--------------------------------------------------------------------------------
1 | package com.ryanharter.android.tooltips;
2 |
3 | import android.animation.Animator;
4 | import android.animation.Animator.AnimatorListener;
5 | import android.animation.AnimatorSet;
6 | import android.animation.ObjectAnimator;
7 | import android.content.Context;
8 | import android.util.AttributeSet;
9 | import android.view.Gravity;
10 | import android.view.MotionEvent;
11 | import android.view.View;
12 | import android.view.ViewTreeObserver.OnPreDrawListener;
13 | import android.widget.RelativeLayout;
14 |
15 | import java.lang.ref.WeakReference;
16 | import java.util.ArrayList;
17 | import java.util.HashMap;
18 | import java.util.List;
19 | import java.util.Map;
20 |
21 | /**
22 | * Created by rharter on 7/24/14.
23 | */
24 | public class ToolTipLayout extends RelativeLayout {
25 |
26 | private ToolTip mToolTip;
27 | private View mToolTipView;
28 |
29 | private List mToolTips = new ArrayList<>();
30 |
31 | private boolean mDimensionsKnown;
32 |
33 | private int mTargetX;
34 | private int mTargetY;
35 | private WeakReference mAnchorView;
36 |
37 | public ToolTipLayout(Context context) {
38 | this(context, null);
39 | }
40 |
41 | public ToolTipLayout(Context context, AttributeSet attrs) {
42 | this(context, attrs, 0);
43 | }
44 |
45 | public ToolTipLayout(Context context, AttributeSet attrs, int defStyle) {
46 | super(context, attrs, defStyle);
47 | }
48 |
49 | /**
50 | * Dismisses all tooltips currently being displayed using
51 | * the default animation.
52 | */
53 | public void dismiss() {
54 | dismiss(true);
55 | }
56 |
57 | /**
58 | * Dismisses all tooltips currently being displayed.
59 | *
60 | * @param animate True to animate the transition.
61 | */
62 | public void dismiss(boolean animate) {
63 | mToolTips.clear();
64 |
65 | if (animate) {
66 |
67 | final List viewsToRemove = new ArrayList<>();
68 | List a = new ArrayList<>();
69 | for (int i = 0; i < getChildCount(); i++) {
70 | a.add(ObjectAnimator.ofFloat(getChildAt(i), View.ALPHA, 0));
71 | viewsToRemove.add(getChildAt(i));
72 | }
73 |
74 | AnimatorSet s = new AnimatorSet();
75 | s.playTogether(a);
76 | s.addListener(new AnimatorListener() {
77 | @Override public void onAnimationStart(Animator animation) {
78 | }
79 |
80 | @Override public void onAnimationEnd(Animator animation) {
81 | for (View v : viewsToRemove) {
82 | removeView(v);
83 | }
84 | }
85 |
86 | @Override public void onAnimationCancel(Animator animation) {
87 | }
88 |
89 | @Override public void onAnimationRepeat(Animator animation) {
90 | }
91 | });
92 | s.start();
93 | } else {
94 | removeAllViews();
95 | }
96 | }
97 |
98 | public void addTooltip(ToolTip tooltip) {
99 | addTooltip(tooltip, true);
100 | }
101 |
102 | private Map mFinalPositions = new HashMap<>();
103 | private boolean mShouldRemoveObserver;
104 |
105 | public void addTooltip(ToolTip tooltip, boolean animate) {
106 | mToolTips.add(tooltip);
107 | View v = tooltip.getView();
108 | if (tooltip.isDismissOnTouch()) {
109 | v.setOnClickListener(new OnClickListener() {
110 | @Override public void onClick(View v) {
111 | dismiss();
112 | }
113 | });
114 | }
115 | addView(v);
116 | requestLayout();
117 |
118 | if (animate) {
119 | // We use a two pass preDrawListener so we can get the post animation
120 | // position of the item and then animate it.
121 | getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
122 | @Override public boolean onPreDraw() {
123 |
124 | if (!mShouldRemoveObserver) {
125 | mShouldRemoveObserver = true;
126 |
127 | mFinalPositions.clear();
128 |
129 | for (ToolTip t : mToolTips) {
130 | float position = 0;
131 | if (Gravity.isVertical(t.getGravity())) {
132 | position = t.getView().getY();
133 | } else {
134 | position = t.getView().getX();
135 | }
136 |
137 | mFinalPositions.put(t, position);
138 | }
139 |
140 | return false;
141 | }
142 |
143 | mShouldRemoveObserver = false;
144 | getViewTreeObserver().removeOnPreDrawListener(this);
145 |
146 | List animators = new ArrayList<>();
147 |
148 | for (ToolTip t : mToolTips) {
149 | t.getView().setAlpha(0);
150 | animators.add(ObjectAnimator.ofFloat(t.getView(), View.ALPHA, 0, 1));
151 |
152 | // TODO Restore this once I can fix the flicker
153 | // final float finalPosition = mFinalPositions.get(t);
154 | // if ((Gravity.VERTICAL_GRAVITY_MASK & t.getGravity()) == Gravity.TOP) {
155 | // float start = finalPosition - t.getView().getHeight() / 2;
156 | // t.getView().setY(start);
157 | //
158 | // animators.add(ObjectAnimator
159 | // .ofFloat(t.getView(), View.TRANSLATION_Y,
160 | // start,
161 | // finalPosition));
162 | // } else if ((Gravity.VERTICAL_GRAVITY_MASK & t.getGravity())
163 | // == Gravity.BOTTOM) {
164 | // float start = finalPosition + t.getView().getHeight() / 2;
165 | // t.getView().setY(start);
166 | //
167 | // animators.add(ObjectAnimator
168 | // .ofFloat(t.getView(), View.TRANSLATION_Y,
169 | // start,
170 | // finalPosition));
171 | // } else if ((Gravity.HORIZONTAL_GRAVITY_MASK & t.getGravity())
172 | // == Gravity.LEFT) {
173 | // float start = finalPosition - t.getView().getWidth() / 2;
174 | // t.getView().setX(start);
175 | //
176 | // animators.add(ObjectAnimator
177 | // .ofFloat(t.getView(), View.TRANSLATION_X,
178 | // start,
179 | // finalPosition));
180 | // } else if ((Gravity.HORIZONTAL_GRAVITY_MASK & t.getGravity())
181 | // == Gravity.RIGHT) {
182 | // float start = finalPosition + t.getView().getWidth() / 2;
183 | // t.getView().setX(start);
184 | //
185 | // animators.add(ObjectAnimator
186 | // .ofFloat(t.getView(), View.TRANSLATION_X,
187 | // start,
188 | // finalPosition));
189 | // }
190 | }
191 |
192 | AnimatorSet s = new AnimatorSet();
193 | s.playTogether(animators);
194 | s.start();
195 |
196 | return true;
197 | }
198 | });
199 | }
200 | }
201 |
202 | @Override protected void onLayout(boolean changed, int l, int t, int r, int b) {
203 | super.onLayout(changed, l, t, r, b);
204 |
205 | int[] containerLocation = new int[2];
206 | getLocationOnScreen(containerLocation);
207 |
208 | for (ToolTip tip : mToolTips) {
209 | int[] anchorLocation = new int[2];
210 | if (tip.getAnchorView() != null) {
211 | tip.getAnchorView().getLocationOnScreen(anchorLocation);
212 | } else {
213 | // Default to a centered view
214 | anchorLocation[0] = containerLocation[0] / 2;
215 | anchorLocation[1] = containerLocation[1] / 2;
216 | }
217 |
218 | int x = anchorLocation[0] - containerLocation[0];
219 | int y = anchorLocation[1] - containerLocation[1];
220 |
221 | if ((tip.getGravity() & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.TOP) {
222 | y -= tip.getView().getHeight();
223 | } else if ((tip.getGravity() & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
224 | if (tip.getAnchorView() != null) {
225 | y += tip.getAnchorView().getHeight();
226 | }
227 | } else if ((tip.getGravity() & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.LEFT) {
228 | x -= tip.getView().getWidth();
229 | } else if ((tip.getGravity() & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.RIGHT) {
230 | if (tip.getAnchorView() != null) {
231 | x += tip.getAnchorView().getWidth();
232 | }
233 | }
234 |
235 | // The tooltip is above or below the anchor view, so
236 | // center the location on the X axis, otherwise center
237 | // on the Y axis.
238 | ToolTipPointerView pointer = tip.getPointerView();
239 | if (Gravity.isVertical(tip.getGravity())) {
240 | x += tip.getAnchorView().getWidth() / 2;
241 | pointer.setX(x - containerLocation[0] - pointer.getWidth() / 2);
242 | tip.getView().setY(y);
243 | } else {
244 | y += tip.getAnchorView().getHeight() / 2 - tip.getView().getHeight() / 2;
245 | tip.getView().setY(y);
246 | tip.getView().setX(x);
247 | tip.getPointerView().setY(tip.getView().getHeight() / 2 - tip.getPointerView().getHeight() / 2);
248 | }
249 | }
250 | }
251 |
252 | @Override public boolean onTouchEvent(MotionEvent event) {
253 | return super.onTouchEvent(event);
254 | }
255 |
256 | public void alignPointer(View pointer, int position, int gravity) {
257 | View parent = (View) pointer.getParent();
258 | int[] parentLocation = new int[2];
259 | parent.getLocationOnScreen(parentLocation);
260 |
261 | if (Gravity.isVertical(gravity)) {
262 | pointer.setX(position - parentLocation[0] - pointer.getWidth() / 2);
263 | } else {
264 | pointer.setY(position - parentLocation[1] - pointer.getHeight() / 2);
265 | }
266 | }
267 | }
268 |
--------------------------------------------------------------------------------
/library/src/main/java/com/ryanharter/android/tooltips/ToolTipPointerView.java:
--------------------------------------------------------------------------------
1 | package com.ryanharter.android.tooltips;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.graphics.Paint.Style;
7 | import android.graphics.Path;
8 | import android.view.Gravity;
9 | import android.view.View;
10 |
11 | /**
12 | * Created by rharter on 7/24/14.
13 | */
14 | public class ToolTipPointerView extends View {
15 |
16 | private Paint mPaint;
17 | private int mGravity;
18 |
19 | public ToolTipPointerView(Context context, int color, int gravity) {
20 | super(context);
21 | mGravity = gravity;
22 |
23 | mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
24 | mPaint.setColor(color);
25 | mPaint.setStyle(Style.FILL);
26 | }
27 |
28 | @Override protected void onDraw(Canvas canvas) {
29 | super.onDraw(canvas);
30 |
31 | Path p = new Path();
32 | if ((Gravity.VERTICAL_GRAVITY_MASK & mGravity) == Gravity.TOP) {
33 | // Top
34 | p.moveTo(0, 0);
35 | p.lineTo(getWidth() / 2, getHeight());
36 | p.lineTo(getWidth(), 0);
37 | p.lineTo(0, 0);
38 | } else if ((Gravity.VERTICAL_GRAVITY_MASK & mGravity) == Gravity.BOTTOM) {
39 | // Bottom
40 | p.moveTo(0, getHeight());
41 | p.lineTo(getWidth() / 2, 0);
42 | p.lineTo(getWidth(), getHeight());
43 | p.lineTo(0, getHeight());
44 | } else if ((Gravity.LEFT & mGravity) == Gravity.LEFT) {
45 | // Left
46 | p.moveTo(0, 0);
47 | p.lineTo(getWidth(), getHeight() / 2);
48 | p.lineTo(0, getHeight());
49 | p.lineTo(0, 0);
50 | } else if ((Gravity.RIGHT & mGravity) == Gravity.RIGHT) {
51 | // Right
52 | p.moveTo(getWidth(), 0);
53 | p.lineTo(0, getHeight() / 2);
54 | p.lineTo(getWidth(), getHeight());
55 | p.lineTo(getWidth(), 0);
56 | }
57 | canvas.drawPath(p, mPaint);
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rharter/android-tooltips/5b67e600a5dc8e36792b6cd5ff68bc9160eac385/library/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rharter/android-tooltips/5b67e600a5dc8e36792b6cd5ff68bc9160eac385/library/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rharter/android-tooltips/5b67e600a5dc8e36792b6cd5ff68bc9160eac385/library/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rharter/android-tooltips/5b67e600a5dc8e36792b6cd5ff68bc9160eac385/library/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ToolTips Library
3 |
4 |
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | // TODO Change this back to the main script once the PR is merged.
3 | apply from: 'https://raw.githubusercontent.com/jpardogo/gradle-mvn-push/master/gradle-mvn-push.gradle'
4 |
5 | android {
6 | compileSdkVersion 20
7 | buildToolsVersion "20.0.0"
8 |
9 | defaultConfig {
10 | applicationId "com.ryanharter.android.tooltips.sample"
11 | minSdkVersion 15
12 | targetSdkVersion 20
13 | versionCode 2
14 | versionName "1.0.1"
15 | }
16 | buildTypes {
17 | release {
18 | runProguard false
19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 | }
21 | }
22 | }
23 |
24 | dependencies {
25 | compile fileTree(dir: 'libs', include: ['*.jar'])
26 | compile project(':library')
27 | }
28 |
--------------------------------------------------------------------------------
/sample/gradle.properties:
--------------------------------------------------------------------------------
1 | POM_NAME=Android ToolTips Sample
2 | POM_ARTIFACT_ID=sample
3 | POM_PACKAGING=apk
--------------------------------------------------------------------------------
/sample/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/sample/src/androidTest/java/com/ryanharter/android/tooltips/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.ryanharter.android.tooltips;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/ryanharter/android/tooltips/sample/MyActivity.java:
--------------------------------------------------------------------------------
1 | package com.ryanharter.android.tooltips.sample;
2 |
3 | import com.ryanharter.android.tooltips.ToolTip;
4 | import com.ryanharter.android.tooltips.ToolTip.Builder;
5 | import com.ryanharter.android.tooltips.ToolTipLayout;
6 |
7 | import org.w3c.dom.Text;
8 |
9 | import android.app.Activity;
10 | import android.graphics.Color;
11 | import android.os.Bundle;
12 | import android.view.Gravity;
13 | import android.view.Menu;
14 | import android.view.MenuItem;
15 | import android.view.View;
16 | import android.view.View.OnClickListener;
17 | import android.view.ViewGroup.LayoutParams;
18 | import android.widget.Button;
19 | import android.widget.TextView;
20 |
21 | public class MyActivity extends Activity {
22 |
23 | private static final int POINTER_SIZE = 15;
24 |
25 | private ToolTipLayout mToolTipLayout;
26 |
27 | @Override
28 | protected void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_my);
31 |
32 | mToolTipLayout = (ToolTipLayout) findViewById(R.id.tooltip_container);
33 |
34 | final Button below = (Button) findViewById(R.id.tip_below);
35 | below.setOnClickListener(new OnClickListener() {
36 | @Override public void onClick(View v) {
37 | View contentView = createToolTipView("Tooltip below the button",
38 | Color.WHITE, getResources().getColor(android.R.color.holo_red_light));
39 | contentView.setLayoutParams(new LayoutParams(
40 | LayoutParams.MATCH_PARENT,
41 | LayoutParams.WRAP_CONTENT
42 | ));
43 |
44 | ToolTip t = new Builder(MyActivity.this)
45 | .anchor(below)
46 | .color(getResources().getColor(android.R.color.holo_red_light))
47 | .gravity(Gravity.BOTTOM)
48 | .pointerSize(POINTER_SIZE)
49 | .contentView(contentView)
50 | .build();
51 | mToolTipLayout.addTooltip(t);
52 | }
53 | });
54 |
55 | final Button left = (Button) findViewById(R.id.tip_left);
56 | left.setOnClickListener(new OnClickListener() {
57 | @Override public void onClick(View v) {
58 | View contentView = createToolTipView("Tooltip left of the button",
59 | Color.WHITE, getResources().getColor(android.R.color.holo_blue_light));
60 | contentView.setLayoutParams(new LayoutParams(
61 | LayoutParams.WRAP_CONTENT,
62 | LayoutParams.WRAP_CONTENT
63 | ));
64 |
65 | // This one has a custom background on the tooltip that
66 | // adds rounded corners
67 | contentView.setBackgroundResource(R.drawable.bg_tooltip_blue);
68 |
69 | ToolTip t = new Builder(MyActivity.this)
70 | .anchor(left)
71 | .color(getResources().getColor(android.R.color.holo_blue_light))
72 | .gravity(Gravity.LEFT)
73 | .pointerSize(POINTER_SIZE)
74 | .contentView(contentView)
75 | .build();
76 | mToolTipLayout.addTooltip(t);
77 | }
78 | });
79 |
80 | final Button above = (Button) findViewById(R.id.tip_above);
81 | above.setOnClickListener(new OnClickListener() {
82 | @Override public void onClick(View v) {
83 | View contentView = createToolTipView("Tooltip above the button",
84 | Color.BLACK, getResources().getColor(android.R.color.holo_green_light));
85 | contentView.setLayoutParams(new LayoutParams(
86 | LayoutParams.MATCH_PARENT,
87 | LayoutParams.WRAP_CONTENT
88 | ));
89 |
90 | ToolTip t = new Builder(MyActivity.this)
91 | .anchor(above)
92 | .color(getResources().getColor(android.R.color.holo_green_light))
93 | .gravity(Gravity.TOP)
94 | .pointerSize(POINTER_SIZE)
95 | .contentView(contentView)
96 | .build();
97 | mToolTipLayout.addTooltip(t);
98 | }
99 | });
100 |
101 | final Button right = (Button) findViewById(R.id.tip_right);
102 | right.setOnClickListener(new OnClickListener() {
103 | @Override public void onClick(View v) {
104 | View contentView = createToolTipView("Tooltip right of the button",
105 | Color.WHITE, getResources().getColor(R.color.trans_black));
106 | contentView.setLayoutParams(new LayoutParams(
107 | LayoutParams.WRAP_CONTENT,
108 | LayoutParams.WRAP_CONTENT
109 | ));
110 |
111 | ToolTip t = new Builder(MyActivity.this)
112 | .anchor(right)
113 | .color(getResources().getColor(R.color.trans_black))
114 | .gravity(Gravity.RIGHT)
115 | .pointerSize(POINTER_SIZE)
116 | .contentView(contentView)
117 | .build();
118 | mToolTipLayout.addTooltip(t);
119 | }
120 | });
121 | }
122 |
123 | public View createToolTipView(String text, int textColor, int bgColor) {
124 | float density = getResources().getDisplayMetrics().density;
125 | int padding = (int) (8 * density);
126 |
127 | TextView contentView = new TextView(MyActivity.this);
128 | contentView.setPadding(padding, padding, padding, padding);
129 | contentView.setText(text);
130 | contentView.setTextColor(textColor);
131 | contentView.setBackgroundColor(bgColor);
132 | return contentView;
133 | }
134 |
135 | @Override
136 | public boolean onCreateOptionsMenu(Menu menu) {
137 | // Inflate the menu; this adds items to the action bar if it is present.
138 | getMenuInflater().inflate(R.menu.my, menu);
139 | return true;
140 | }
141 |
142 | @Override
143 | public boolean onOptionsItemSelected(MenuItem item) {
144 | // Handle action bar item clicks here. The action bar will
145 | // automatically handle clicks on the Home/Up button, so long
146 | // as you specify a parent activity in AndroidManifest.xml.
147 | int id = item.getItemId();
148 | if (id == R.id.action_settings) {
149 | return true;
150 | }
151 | return super.onOptionsItemSelected(item);
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rharter/android-tooltips/5b67e600a5dc8e36792b6cd5ff68bc9160eac385/sample/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rharter/android-tooltips/5b67e600a5dc8e36792b6cd5ff68bc9160eac385/sample/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/bg_tooltip_blue.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rharter/android-tooltips/5b67e600a5dc8e36792b6cd5ff68bc9160eac385/sample/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rharter/android-tooltips/5b67e600a5dc8e36792b6cd5ff68bc9160eac385/sample/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_my.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
14 |
15 |
20 |
21 |
27 |
28 |
34 |
35 |
42 |
43 |
44 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/sample/src/main/res/menu/my.xml:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/sample/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #99000000
4 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ToolTips
5 | Settings
6 |
7 |
8 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':library', ':sample'
2 |
--------------------------------------------------------------------------------