diff --git a/README.md b/README.md
index 15df7da..db8899a 100644
--- a/README.md
+++ b/README.md
@@ -4,13 +4,18 @@
-With **Showcase**, you can easily show tooltips. **Showcase** will highlight the view and show tooltip on it. You can
-customize title and description text fields, backgrounds and arrow positions. You can also find out how the user closed
-the showcase and in multi focus situations you can find out which view was clicked.
+With **Showcase**, you can easily show tooltips. **Showcase** will highlight the view and show
+tooltip on it. You can
+customize title and description text fields, backgrounds and arrow positions. You can also find out
+how the user closed
+the showcase and in multi focus situations you can find out which view was clicked. The library
+supports both system fonts
+and custom fonts for tooltip text, allowing you to maintain brand consistency across your app.
## Installation
-- To implement **Showcase** to your Android project via Gradle, you need to add Jitpack repository to your
+- To implement **Showcase** to your Android project via Gradle, you need to add Jitpack repository
+ to your
root `build.gradle`.
```
@@ -22,11 +27,12 @@ allprojects {
}
```
-- After adding Jitpack repository, you can add **Showcase** dependency to your app level `build.gradle`.
+- After adding Jitpack repository, you can add **Showcase** dependency to your app level
+ `build.gradle`.
```
dependencies {
- implementation "com.github.trendyol::showcase:2.0.0"
+ implementation "com.github.trendyol::showcase:2.0.2"
}
```
@@ -40,7 +46,8 @@ val showcaseManager = ShowcaseManager.Builder()
.titleText("Title about myView")
.titleTextSize(22F)
.titleTextColor(ContextCompat.getColor(this, R.color.blue))
- .titleTextFontFamily("sans-serif-medium")
+ .titleTextFontFamily("sans-serif-medium") // Using system font
+ .titleTextFontFamilyResId(R.font.custom_font) // Using custom font
.titleTextStyle(Typeface.BOLD)
.descriptionText("Little bit info for my lovely myView")
.windowBackgroundAlpha(127)
@@ -66,53 +73,58 @@ showcaseManager.show(context) // or showcaseManager.show(context, REQUEST_CODE_S
### Builder Configuration
-| Usage | Description | Optional | Default Value | StyleRes |
-|:--------------------------------------------------------|:---------------------------------------------------------|:---------|:-----------------------------|:---------|
-| `builder.focus(View)` | view to be focused on | no | null | no |
-| `builder.focus(Array)` | view array to be focused on | no | null | no |
-| `builder.resId(Int)` | Showcase.Theme style | yes | null | yes |
-| `builder.titleText(String)` | text to be showed on top of the tooltip | yes | "" | no |
-| `builder.descriptionText(String)` | description text will be displayed on tooltip | yes | "" | no |
-| `builder.titleTextColor(Int)` | titleText's color | yes | Color.BLACK | yes |
-| `builder.descriptionTextColor(Int)` | descriptionText's color | yes | Color.BLACK | yes |
-| `builder.titleTextSize(Int)` | titleText's text size in SP | yes | 18 SP | no |
-| `builder.descriptionTextSize(Int)` | descriptionText's text size in SP | yes | 14 SP | no |
-| `builder.titleTextFontFamily(String)` | titleText's fontFamily | yes | sans-serif | yes |
-| `builder.descriptionTextFontFamily(String)` | descriptionText's fontFamily | yes | sans-serif | yes |
-| `builder.titleTextStyle(Int)` | titleText's textStyle | yes | Typeface.NORMAL | yes |
-| `builder.descriptionTextStyle(Int)` | descriptionText's textStyle | yes | Typeface.NORMAL | yes |
-| `builder.backgroundColor(Int)` | background color of tooltip | yes | Color.WHITE | yes |
-| `builder.closeButtonColor(Int)` | closeButton's color | yes | Color.BLACK | yes |
-| `builder.showCloseButton(Boolean)` | show close button on tooltip | yes | true | yes |
-| `builder.arrowResource(Int)` | custom icon resource for arrow. | yes | ic_arrow_down or ic_arrow_up | no |
-| `builder.arrowPosition(ArrowPosition)` | arrow can be placed under or over the tooltip | yes | ArrowPosition.AUTO | no |
-| `builder.arrowPercentage(Int)` | arrow position percentage can be decided | yes | null | no |
-| `builder.highlightType(HighlightType)` | view can be highlighted with a circle shape or rectangle | yes | HighlightType.RECTANGLE | no |
-| `builder.cancelListener(CancelListener)` | will be called after user quit from tooltip | yes | null | no |
-| `builder.windowBackgroundColor(Int)` | background of the window's color can be decided | yes | Color.BLACK | yes |
-| `builder.windowBackgroundTint(Int)` | alpha value of window's background color | yes | 204 | no |
-| `builder.titleTextSize(Int)` | titleText's text size in SP | yes | 18 | no |
-| `builder.cancellableFromOutsideTouch(Boolean)` | outside touch from tooltip will act as close click | yes | false | yes |
-| `builder.showcaseViewClickable(Boolean)` | makes the showcase view clickable or not | yes | false | yes |
-| `builder.isDebugMode(Boolean)` | tooltip won't be presented | yes | false | no |
-| `builder.attachOnParentLifecycle(Boolean)` | observe parent lifecycle and dismiss showcase | yes | false | no |
-| `builder.textPosition(TextPosition)` | text can be positioning center, end and start | yes | TextPosition.START | no |
-| `builder.imageUrl(String)` | show image on tooltip | yes | null | no |
-| `builder.customContent(Int)` | show given layout | yes | null | no |
-| `builder.statusBarVisible(Boolean)` | statusBar visibility of window | yes | true | no |
-| `builder.toolTipVisible(Boolean)` | tooltip visibility | yes | true | no |
-| `builder.highlightRadius(Float, Float, Float, Float)` | tooltip visibility | yes | 0f, 0f, 0f, 0f | no |
-| `builder.setSlidableContentList(List)` | show slidable content | yes | null | no |
-| `builder.showDurationMillis(Long)` | duration of the tooltip visibility | yes | 2000L | no |
-| `builder.showcaseViewVisibleIndefinitely(Boolean)` | controls tooltip visibility condition | yes | true | no |
-| `builder.build()` | will return ShowcaseManager instance | no | | |
-| `showcaseManager.show(Context)` | show the tooltip with set attributes on | no | | |
+| Usage | Description | Optional | Default Value | StyleRes |
+|:--------------------------------------------------------|:--------------------------------------------------------------------------------|:---------|:------------------------|:---------|
+| `builder.focus(View)` | view to be focused on | no | null | no |
+| `builder.focus(Array)` | view array to be focused on | no | null | no |
+| `builder.resId(Int)` | Showcase.Theme style | yes | null | yes |
+| `builder.titleText(String)` | text to be showed on top of the tooltip | yes | "" | no |
+| `builder.descriptionText(String)` | description text will be displayed on tooltip | yes | "" | no |
+| `builder.titleTextColor(Int)` | titleText's color | yes | Color.BLACK | yes |
+| `builder.descriptionTextColor(Int)` | descriptionText's color | yes | Color.BLACK | yes |
+| `builder.titleTextSize(Int)` | titleText's text size in SP | yes | 18 SP | no |
+| `builder.descriptionTextSize(Int)` | descriptionText's text size in SP | yes | 14 SP | no |
+| `builder.titleTextFontFamily(String)` | titleText's fontFamily (system fonts) | yes | sans-serif | yes |
+| `builder.titleTextFontFamilyResId(Int)` | titleText's custom font resource ID | yes | null | yes |
+| `builder.descriptionTextFontFamily(String)` | descriptionText's fontFamily (system fonts) | yes | sans-serif | yes |
+| `builder.descriptionTextFontFamilyResId(Int)` | descriptionText's custom font resource ID | yes | null | yes |
+| `builder.titleTextStyle(Int)` | titleText's textStyle | yes | Typeface.NORMAL | yes |
+| `builder.descriptionTextStyle(Int)` | descriptionText's textStyle | yes | Typeface.NORMAL | yes |
+| `builder.backgroundColor(Int)` | background color of tooltip | yes | Color.WHITE | yes |
+| `builder.closeButtonColor(Int)` | closeButton's color | yes | Color.BLACK | yes |
+| `builder.showCloseButton(Boolean)` | show close button on tooltip | yes | true | yes |
+| `builder.setArrowVisibility(Boolean)` | controls whether arrow icon should be shown or not | yes | true | no |
+| `builder.arrowResource(Int)` | custom icon resource for the arrow rotates 180° if the arrow position is bottom | yes | ic_arrow_up | no |
+| `builder.arrowPosition(ArrowPosition)` | arrow can be placed under or over the tooltip | yes | ArrowPosition.AUTO | no |
+| `builder.arrowPercentage(Int)` | arrow position percentage can be decided | yes | null | no |
+| `builder.highlightType(HighlightType)` | view can be highlighted with a circle shape or rectangle | yes | HighlightType.RECTANGLE | no |
+| `builder.cancelListener(CancelListener)` | will be called after user quit from tooltip | yes | null | no |
+| `builder.windowBackgroundColor(Int)` | background of the window's color can be decided | yes | Color.BLACK | yes |
+| `builder.windowBackgroundTint(Int)` | alpha value of window's background color | yes | 204 | no |
+| `builder.titleTextSize(Int)` | titleText's text size in SP | yes | 18 | no |
+| `builder.cancellableFromOutsideTouch(Boolean)` | outside touch from tooltip will act as close click | yes | false | yes |
+| `builder.cancellableFromScroll(Boolean)` | screen scroll will act as close click | yes | false | yes |
+| `builder.showcaseViewClickable(Boolean)` | makes the showcase view clickable or not | yes | false | yes |
+| `builder.isDebugMode(Boolean)` | tooltip won't be presented | yes | false | no |
+| `builder.attachOnParentLifecycle(Boolean)` | observe parent lifecycle and dismiss showcase | yes | false | no |
+| `builder.textPosition(TextPosition)` | text can be positioning center, end and start | yes | TextPosition.START | no |
+| `builder.imageUrl(String)` | show image on tooltip | yes | null | no |
+| `builder.customContent(Int)` | show given layout | yes | null | no |
+| `builder.statusBarVisible(Boolean)` | statusBar visibility of window | yes | true | no |
+| `builder.toolTipVisible(Boolean)` | tooltip visibility | yes | true | no |
+| `builder.highlightRadius(Float, Float, Float, Float)` | tooltip visibility | yes | 0f, 0f, 0f, 0f | no |
+| `builder.setSlidableContentList(List)` | show slidable content | yes | null | no |
+| `builder.showDurationMillis(Long)` | duration of the tooltip visibility | yes | 2000L | no |
+| `builder.showcaseViewVisibleIndefinitely(Boolean)` | controls tooltip visibility condition | yes | true | no |
+| `builder.build()` | will return ShowcaseManager instance | no | | |
+| `showcaseManager.show(Context)` | show the tooltip with set attributes on | no | | |
### Action Result
By overriding `onActivityResult` you can get feedback based on the types in the ActionType class.
-If the actionType is `HIGHLIGHT_CLICKED`, the `KEY_SELECTED_VIEW_INDEX` parameter returns the index of the clicked view.
+If the actionType is `HIGHLIGHT_CLICKED`, the `KEY_SELECTED_VIEW_INDEX` parameter returns the index
+of the clicked view.
If no view is clicked, the index will be -1.
```
diff --git a/build.gradle b/build.gradle
index 031cd98..1c5068c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.4.2'
+ classpath 'com.android.tools.build:gradle:8.10.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
}
diff --git a/gradle.properties b/gradle.properties
index 57b7980..214516e 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -6,6 +6,9 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
+android.defaults.buildfeatures.buildconfig=true
+android.nonFinalResIds=false
+android.nonTransitiveRClass=false
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index e708b1c..a4b76b9 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 774fae8..cea7a79 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 4f906e0..f3b75f3 100755
--- a/gradlew
+++ b/gradlew
@@ -1,7 +1,7 @@
-#!/usr/bin/env sh
+#!/bin/sh
#
-# Copyright 2015 the original author or authors.
+# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,69 +15,103 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+# SPDX-License-Identifier: Apache-2.0
+#
##############################################################################
-##
-## Gradle start up script for UN*X
-##
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
##############################################################################
# Attempt to set APP_HOME
+
# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
+MAX_FD=maximum
warn () {
echo "$*"
-}
+} >&2
die () {
echo
echo "$*"
echo
exit 1
-}
+} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
+ JAVACMD=$JAVA_HOME/jre/sh/java
else
- JAVACMD="$JAVA_HOME/bin/java"
+ JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -98,88 +132,120 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
+ fi
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
fi
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
# Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
fi
- i=`expr $i + 1`
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
done
- case $i in
- 0) set -- ;;
- 1) set -- "$args0" ;;
- 2) set -- "$args0" "$args1" ;;
- 3) set -- "$args0" "$args1" "$args2" ;;
- 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
fi
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=`save "$@"`
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index 107acd3..9d21a21 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -13,8 +13,10 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
-@if "%DEBUG%" == "" @echo off
+@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +27,8 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto execute
+if %ERRORLEVEL% equ 0 goto execute
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
goto fail
@@ -56,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
goto fail
@@ -75,13 +78,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
+if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
diff --git a/library/build.gradle b/library/build.gradle
index 5a7d0c5..9c6b4f0 100644
--- a/library/build.gradle
+++ b/library/build.gradle
@@ -10,11 +10,11 @@ ext {
}
android {
- compileSdkVersion 33
+ compileSdkVersion 35
defaultConfig {
minSdkVersion 17
- targetSdkVersion 33
+ targetSdkVersion 35
vectorDrawables.useSupportLibrary = true
}
diff --git a/library/src/main/java/com/trendyol/showcase/showcase/ShowcaseManager.kt b/library/src/main/java/com/trendyol/showcase/showcase/ShowcaseManager.kt
index 234c7a9..3050004 100644
--- a/library/src/main/java/com/trendyol/showcase/showcase/ShowcaseManager.kt
+++ b/library/src/main/java/com/trendyol/showcase/showcase/ShowcaseManager.kt
@@ -102,9 +102,13 @@ class ShowcaseManager private constructor(
showcaseModel.isShowcaseViewClickable
),
titleTextFontFamily = typedArray.getString(R.styleable.Showcase_Theme_titleTextFontFamily) ?: showcaseModel.titleTextFontFamily,
+ titleTextFontFamilyResId = typedArray.getResourceId(R.styleable.Showcase_Theme_titleTextFontFamilyResId, 0)
+ .takeIf { it != 0 } ?: showcaseModel.titleTextFontFamilyResId,
titleTextStyle = typedArray.getInteger(R.styleable.Showcase_Theme_titleStyle, showcaseModel.titleTextStyle),
descriptionTextFontFamily = typedArray.getString(R.styleable.Showcase_Theme_descriptionTextFontFamily)
?: showcaseModel.descriptionTextFontFamily,
+ descriptionTextFontFamilyResId = typedArray.getResourceId(R.styleable.Showcase_Theme_descriptionTextFontFamilyResId, 0)
+ .takeIf { it != 0 } ?: showcaseModel.descriptionTextFontFamilyResId,
descriptionTextStyle = typedArray.getInteger(R.styleable.Showcase_Theme_descriptionTextStyle, showcaseModel.descriptionTextStyle)
).also {
typedArray.recycle()
@@ -115,8 +119,9 @@ class ShowcaseManager private constructor(
private var focusViews: Array? = null
private var titleText: String = Constants.DEFAULT_TEXT
- private var descriptionText: String = Constants.DEFAULT_TEXT
+ private var descriptionText: CharSequence = Constants.DEFAULT_TEXT
private var isShowcaseViewVisibleIndefinitely: Boolean = Constants.DEFAULT_SHOW_FOREVER
+ private var isArrowVisible: Boolean = Constants.DEFAULT_ARROW_VISIBILITY
private var showDuration: Long = Constants.DEFAULT_SHOW_DURATION
@ColorInt
private var titleTextColor: Int = Constants.DEFAULT_TEXT_COLOR
@@ -142,9 +147,11 @@ class ShowcaseManager private constructor(
private var windowBackgroundAlpha: Int = Constants.DEFAULT_BACKGROUND_ALPHA
private var titleTextSize: Float = Constants.DEFAULT_TITLE_TEXT_SIZE
private var titleTextFontFamily: String = Constants.DEFAULT_TITLE_TEXT_FONT_FAMILY
+ private var titleTextFontFamilyResId: Int? = null
private var titleTextStyle: Int = Constants.DEFAULT_TITLE_TEXT_STYLE
private var descriptionTextSize: Float = Constants.DEFAULT_DESCRIPTION_TEXT_SIZE
private var descriptionTextFontFamily: String = Constants.DEFAULT_DESCRIPTION_TEXT_FONT_FAMILY
+ private var descriptionTextFontFamilyResId: Int? = null
private var descriptionTextStyle: Int = Constants.DEFAULT_DESCRIPTION_TEXT_STYLE
private var highlightPadding: Float = Constants.DEFAULT_HIGHLIGHT_PADDING_EXTRA
@@ -152,6 +159,7 @@ class ShowcaseManager private constructor(
private var resId: Int? = null
private var cancellableFromOutsideTouch: Boolean =
Constants.DEFAULT_CANCELLABLE_FROM_OUTSIDE_TOUCH
+ private var cancellableFromScroll: Boolean = Constants.DEFAULT_CANCELLABLE_FROM_SCROLL
private var isShowcaseViewClickable: Boolean = Constants.DEFAULT_SHOWCASE_VIEW_CLICKABLE
private var isDebugMode: Boolean = false
private var textPosition: TextPosition = Constants.DEFAULT_TEXT_POSITION
@@ -184,6 +192,13 @@ class ShowcaseManager private constructor(
*/
fun titleTextFontFamily(fontFamily: String) = apply { titleTextFontFamily = fontFamily }
+ /**
+ * Sets the title font family using a font resource ID
+ *
+ * @param resId font resId
+ */
+ fun titleTextFontFamilyResId(@FontRes resId: Int) = apply { titleTextFontFamilyResId = resId }
+
/**
* Controls whether showcase should be shown indefinitely or not. By default it is true.
*
@@ -192,6 +207,13 @@ class ShowcaseManager private constructor(
fun showcaseViewVisibleIndefinitely(isVisibleIndefinitely: Boolean) =
apply { isShowcaseViewVisibleIndefinitely = isVisibleIndefinitely }
+ /**
+ * Controls whether arrow icon should be shown or not. By default it is true.
+ *
+ * @param isVisible assigns boolean value to isArrowVisible.
+ */
+ fun setArrowVisibility(isVisible: Boolean) = apply { isArrowVisible = isVisible }
+
/**
* Assign duration value to showDuration. By default it is 2000L.
* To see the effect, set [showcaseViewVisibleIndefinitely] to false.
@@ -209,7 +231,7 @@ class ShowcaseManager private constructor(
fun titleTextStyle(@IntRange(from = Typeface.NORMAL.toLong(), to = Typeface.BOLD_ITALIC.toLong()) textStyle: Int) =
apply { titleTextStyle = textStyle }
- fun descriptionText(description: String) = apply { descriptionText = description }
+ fun descriptionText(description: CharSequence) = apply { descriptionText = description }
fun descriptionTextColor(@ColorInt color: Int) = apply { descriptionTextColor = color }
@@ -221,6 +243,15 @@ class ShowcaseManager private constructor(
fun descriptionTextFontFamily(fontFamily: String) =
apply { descriptionTextFontFamily = fontFamily }
+ /**
+ * Sets the description font family using a font resource ID
+ *
+ * @param resId font resId
+ */
+ fun descriptionTextFontFamilyResId(@FontRes resId: Int) = apply {
+ descriptionTextFontFamilyResId = resId
+ }
+
/**
* Assign textStyle to descriptionText
*
@@ -277,6 +308,8 @@ class ShowcaseManager private constructor(
fun cancellableFromOutsideTouch(cancellable: Boolean) = apply { cancellableFromOutsideTouch = cancellable }
+ fun cancellableFromScroll(cancellable: Boolean) = apply { cancellableFromScroll = cancellable }
+
/**
* Makes the showcase view clickable or not.
*
@@ -363,12 +396,15 @@ class ShowcaseManager private constructor(
windowBackgroundAlpha = windowBackgroundAlpha,
titleTextSize = titleTextSize,
titleTextFontFamily = titleTextFontFamily,
+ titleTextFontFamilyResId = titleTextFontFamilyResId,
titleTextStyle = titleTextStyle,
descriptionTextSize = descriptionTextSize,
descriptionTextFontFamily = descriptionTextFontFamily,
+ descriptionTextFontFamilyResId = descriptionTextFontFamilyResId,
descriptionTextStyle = descriptionTextStyle,
highlightPadding = highlightPadding,
cancellableFromOutsideTouch = cancellableFromOutsideTouch,
+ cancellableFromScroll = cancellableFromScroll,
isShowcaseViewClickable = isShowcaseViewClickable,
isDebugMode = isDebugMode,
textPosition = textPosition,
@@ -382,7 +418,8 @@ class ShowcaseManager private constructor(
radiusBottomStart = radiusBottomStart,
isToolTipVisible = isToolTipVisible,
showDuration = showDuration,
- isShowcaseViewVisibleIndefinitely = isShowcaseViewVisibleIndefinitely
+ isShowcaseViewVisibleIndefinitely = isShowcaseViewVisibleIndefinitely,
+ isArrowVisible = isArrowVisible,
)
return ShowcaseManager(showcaseModel = showcaseModel, resId = resId)
diff --git a/library/src/main/java/com/trendyol/showcase/showcase/ShowcaseModel.kt b/library/src/main/java/com/trendyol/showcase/showcase/ShowcaseModel.kt
index c28796b..ebd8f0b 100644
--- a/library/src/main/java/com/trendyol/showcase/showcase/ShowcaseModel.kt
+++ b/library/src/main/java/com/trendyol/showcase/showcase/ShowcaseModel.kt
@@ -4,6 +4,7 @@ import android.graphics.RectF
import android.os.Parcelable
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
+import androidx.annotation.FontRes
import androidx.annotation.LayoutRes
import com.trendyol.showcase.ui.slidablecontent.SlidableContent
import com.trendyol.showcase.ui.showcase.HighlightType
@@ -17,7 +18,7 @@ data class ShowcaseModel(
val highlightedViewsRectFList: List,
val radius: Float,
val titleText: String,
- val descriptionText: String,
+ val descriptionText: CharSequence,
@ColorInt val titleTextColor: Int,
@ColorInt val descriptionTextColor: Int,
@ColorInt val popupBackgroundColor: Int,
@@ -31,12 +32,15 @@ data class ShowcaseModel(
val windowBackgroundAlpha: Int,
val titleTextSize: Float,
val titleTextFontFamily: String,
+ @FontRes val titleTextFontFamilyResId: Int?,
val titleTextStyle: Int,
val descriptionTextSize: Float,
val descriptionTextFontFamily: String,
+ @FontRes val descriptionTextFontFamilyResId: Int?,
val descriptionTextStyle: Int,
val highlightPadding: Float,
val cancellableFromOutsideTouch: Boolean,
+ val cancellableFromScroll: Boolean,
val isShowcaseViewClickable: Boolean,
val isDebugMode: Boolean,
val textPosition: TextPosition,
@@ -51,6 +55,7 @@ data class ShowcaseModel(
val isToolTipVisible: Boolean,
val showDuration: Long,
val isShowcaseViewVisibleIndefinitely: Boolean,
+ val isArrowVisible: Boolean,
) : Parcelable {
fun horizontalCenter() = rectF.left + ((rectF.right - rectF.left) / 2)
diff --git a/library/src/main/java/com/trendyol/showcase/ui/showcase/ShowcaseActivity.kt b/library/src/main/java/com/trendyol/showcase/ui/showcase/ShowcaseActivity.kt
index 9ec9284..7079129 100644
--- a/library/src/main/java/com/trendyol/showcase/ui/showcase/ShowcaseActivity.kt
+++ b/library/src/main/java/com/trendyol/showcase/ui/showcase/ShowcaseActivity.kt
@@ -56,7 +56,7 @@ class ShowcaseActivity : AppCompatActivity() {
}
private fun updateStatusBar(isStatusBarVisible: Boolean) {
- WindowCompat.setDecorFitsSystemWindows(window, true)
+ WindowCompat.setDecorFitsSystemWindows(window, false)
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
if (isStatusBarVisible) {
windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_TOUCH
diff --git a/library/src/main/java/com/trendyol/showcase/ui/showcase/ShowcaseView.kt b/library/src/main/java/com/trendyol/showcase/ui/showcase/ShowcaseView.kt
index 63d67ef..6ad2897 100644
--- a/library/src/main/java/com/trendyol/showcase/ui/showcase/ShowcaseView.kt
+++ b/library/src/main/java/com/trendyol/showcase/ui/showcase/ShowcaseView.kt
@@ -6,7 +6,10 @@ import android.graphics.RectF
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
+import androidx.core.view.updatePadding
import com.trendyol.showcase.databinding.LayoutShowcaseBinding
import com.trendyol.showcase.showcase.ShowcaseModel
import com.trendyol.showcase.ui.placeTooltip
@@ -16,8 +19,9 @@ import com.trendyol.showcase.ui.tooltip.TooltipViewState
import com.trendyol.showcase.util.ActionType
import com.trendyol.showcase.util.OnTouchClickListener
import com.trendyol.showcase.util.TooltipFieldUtil
-import com.trendyol.showcase.util.getDensity
import com.trendyol.showcase.util.getHeightInPixels
+import com.trendyol.showcase.util.isRTL
+import com.trendyol.showcase.util.screenWidth
import com.trendyol.showcase.util.shape.CircleShape
import com.trendyol.showcase.util.shape.RectangleShape
import com.trendyol.showcase.util.statusBarHeight
@@ -30,6 +34,28 @@ class ShowcaseView @JvmOverloads constructor(
private val binding = LayoutShowcaseBinding.inflate(LayoutInflater.from(context), this, true)
private var showcaseModel: ShowcaseModel? = null
private var clickListener: ((ActionType, Int) -> (Unit))? = null
+ private var insetTop: Int = 0
+ private var insetBottom: Int = 0
+
+ init {
+ ViewCompat.setOnApplyWindowInsetsListener(this) { view, insets ->
+ val systemBars =
+ insets.getInsets(WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout())
+
+ // Always apply the same padding regardless of API level
+ view.updatePadding(
+ top = systemBars.top,
+ bottom = systemBars.bottom,
+ left = systemBars.left,
+ right = systemBars.right
+ )
+ insetTop = systemBars.top
+ insetBottom = systemBars.bottom
+
+ //post { bind() }
+ insets
+ }
+ }
override fun dispatchDraw(canvas: Canvas) {
val showcaseModel = this.showcaseModel ?: return super.dispatchDraw(canvas)
@@ -38,7 +64,6 @@ class ShowcaseView @JvmOverloads constructor(
val shape = when (model.highlightType) {
HighlightType.CIRCLE -> {
CircleShape(
- statusBarDiff = statusBarHeight(model.isStatusBarVisible),
screenWidth = width,
screenHeight = height,
x = model.horizontalCenter(),
@@ -48,7 +73,6 @@ class ShowcaseView @JvmOverloads constructor(
}
HighlightType.RECTANGLE -> {
RectangleShape(
- statusBarDiff = statusBarHeight(model.isStatusBarVisible),
screenWidth = width,
screenHeight = height,
left = model.rectF.left - (model.highlightPadding / 2),
@@ -88,16 +112,17 @@ class ShowcaseView @JvmOverloads constructor(
listenClickEvents()
val arrowPosition = TooltipFieldUtil.decideArrowPosition(showcaseModel, resources.getHeightInPixels())
- val arrowMargin = TooltipFieldUtil.calculateArrowMargin(
- horizontalCenter = showcaseModel.horizontalCenter(),
- density = resources.getDensity()
- )
+ val arrowStartMargin = if (context.isRTL()) {
+ context.screenWidth() - showcaseModel.horizontalCenter().toInt()
+ } else {
+ showcaseModel.horizontalCenter().toInt()
+ }
val marginFromBottom = getMarginFromBottom(showcaseModel, arrowPosition)
val showcaseViewState = ShowcaseViewState(margin = marginFromBottom)
val tooltipViewState = TooltipViewState(
showcaseModel = showcaseModel,
arrowPosition = arrowPosition,
- arrowMargin = arrowMargin
+ arrowMargin = arrowStartMargin
)
setCustomContent()
@@ -108,7 +133,10 @@ class ShowcaseView @JvmOverloads constructor(
}
}
- private fun getMarginFromBottom(showcaseModel: ShowcaseModel, arrowPosition: AbsoluteArrowPosition): Int {
+ private fun getMarginFromBottom(
+ showcaseModel: ShowcaseModel,
+ arrowPosition: AbsoluteArrowPosition
+ ): Int {
return when (showcaseModel.highlightType) {
HighlightType.CIRCLE -> TooltipFieldUtil.calculateMarginForCircle(
top = showcaseModel.topOfCircle(),
@@ -139,6 +167,11 @@ class ShowcaseView @JvmOverloads constructor(
sendActionType(ActionType.EXIT)
}
}
+ scrollListener = { view, startX, startY, endX, endY ->
+ if (showcaseModel?.cancellableFromScroll == true) {
+ sendActionType(ActionType.EXIT)
+ }
+ }
}.also {
setOnTouchListener(it)
}
@@ -156,14 +189,16 @@ class ShowcaseView @JvmOverloads constructor(
HighlightType.CIRCLE -> {
newRectF.left = (it.horizontalCenter() - it.radius - it.highlightPadding)
newRectF.right = (it.horizontalCenter() + it.radius + it.highlightPadding)
- newRectF.top = (it.verticalCenter() - it.radius - it.highlightPadding + statusBarHeight())
- newRectF.bottom = (it.verticalCenter() + it.radius + it.highlightPadding - statusBarHeight())
+ newRectF.top =
+ (it.verticalCenter() - it.radius - it.highlightPadding)
+ newRectF.bottom =
+ (it.verticalCenter() + it.radius + it.highlightPadding)
}
HighlightType.RECTANGLE -> {
newRectF.left -= (it.highlightPadding / 2)
newRectF.right += (it.highlightPadding / 2)
- newRectF.top -= (it.highlightPadding / 2 - statusBarHeight())
- newRectF.bottom += (it.highlightPadding / 2 - statusBarHeight())
+ newRectF.top -= (it.highlightPadding / 2)
+ newRectF.bottom += (it.highlightPadding / 2)
}
}
newRectF.contains(x, y)
@@ -172,8 +207,8 @@ class ShowcaseView @JvmOverloads constructor(
private fun getClickedViewIndex(x: Float, y: Float): Int {
val list = showcaseModel?.highlightedViewsRectFList
-
- return list?.indexOfFirst { it.contains(x, y - statusBarHeight()) } ?: CONST_VIEW_NOT_FOUND
+ return list?.indexOfFirst { it.contains(x, y) }
+ ?: CONST_VIEW_NOT_FOUND
}
private fun setCustomContent() {
diff --git a/library/src/main/java/com/trendyol/showcase/ui/slidablecontent/SlidableContent.kt b/library/src/main/java/com/trendyol/showcase/ui/slidablecontent/SlidableContent.kt
index 2bce8c6..91bf2f4 100644
--- a/library/src/main/java/com/trendyol/showcase/ui/slidablecontent/SlidableContent.kt
+++ b/library/src/main/java/com/trendyol/showcase/ui/slidablecontent/SlidableContent.kt
@@ -2,6 +2,7 @@ package com.trendyol.showcase.ui.slidablecontent
import android.os.Parcelable
import androidx.annotation.ColorInt
+import androidx.annotation.FontRes
import com.trendyol.showcase.ui.tooltip.TextPosition
import kotlinx.parcelize.Parcelize
@@ -12,11 +13,13 @@ data class SlidableContent(
@ColorInt var titleTextColor: Int,
var titleTextSize: Float,
var titleTextFontFamily: String,
+ @FontRes var titleTextFontFamilyResId: Int?,
var titleTextStyle: Int,
var description: String?,
@ColorInt var descriptionTextColor: Int,
var descriptionTextSize: Float,
var descriptionTextFontFamily: String,
+ @FontRes var descriptionTextFontFamilyResId: Int?,
var descriptionTextStyle: Int,
var textPosition: TextPosition,
) : Parcelable
diff --git a/library/src/main/java/com/trendyol/showcase/ui/slidablecontent/SlidableContentAdapter.kt b/library/src/main/java/com/trendyol/showcase/ui/slidablecontent/SlidableContentAdapter.kt
index 40d4fcf..c44eecf 100644
--- a/library/src/main/java/com/trendyol/showcase/ui/slidablecontent/SlidableContentAdapter.kt
+++ b/library/src/main/java/com/trendyol/showcase/ui/slidablecontent/SlidableContentAdapter.kt
@@ -1,6 +1,5 @@
package com.trendyol.showcase.ui.slidablecontent
-import android.graphics.Typeface
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.isVisible
@@ -8,6 +7,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.trendyol.showcase.databinding.ItemSlidableContentBinding
import com.trendyol.showcase.ui.loadImage
import com.trendyol.showcase.ui.setTextSizeInSp
+import com.trendyol.showcase.util.getHeightInPixels
internal class SlidableContentAdapter(private val slidableContentList: List) :
RecyclerView.Adapter() {
@@ -36,10 +36,7 @@ internal class SlidableContentAdapter(private val slidableContentList: List Unit): SlidableContent {
titleTextColor = DEFAULT_TEXT_COLOR,
titleTextSize = DEFAULT_TITLE_TEXT_SIZE,
titleTextFontFamily = DEFAULT_TITLE_TEXT_FONT_FAMILY,
+ titleTextFontFamilyResId = null,
titleTextStyle = DEFAULT_TITLE_TEXT_STYLE,
description = null,
descriptionTextColor = DEFAULT_TEXT_COLOR,
descriptionTextSize = DEFAULT_DESCRIPTION_TEXT_SIZE,
descriptionTextFontFamily = DEFAULT_DESCRIPTION_TEXT_FONT_FAMILY,
+ descriptionTextFontFamilyResId = null,
descriptionTextStyle = DEFAULT_DESCRIPTION_TEXT_STYLE,
textPosition = DEFAULT_TEXT_POSITION
)
diff --git a/library/src/main/java/com/trendyol/showcase/ui/slidablecontent/SlidableContentViewState.kt b/library/src/main/java/com/trendyol/showcase/ui/slidablecontent/SlidableContentViewState.kt
index 314ace1..c7b261a 100644
--- a/library/src/main/java/com/trendyol/showcase/ui/slidablecontent/SlidableContentViewState.kt
+++ b/library/src/main/java/com/trendyol/showcase/ui/slidablecontent/SlidableContentViewState.kt
@@ -1,5 +1,8 @@
package com.trendyol.showcase.ui.slidablecontent
+import android.content.Context
+import android.graphics.Typeface
+import androidx.core.content.res.ResourcesCompat
import com.trendyol.showcase.ui.tooltip.TextPosition
internal class SlidableContentViewState(val slidableContent: SlidableContent) {
@@ -15,4 +18,16 @@ internal class SlidableContentViewState(val slidableContent: SlidableContent) {
else -> 2
}
}
+
+ fun getTitleTypeface(context: Context): Typeface? {
+ return slidableContent.titleTextFontFamilyResId?.let { resId ->
+ ResourcesCompat.getFont(context, resId)
+ } ?: Typeface.create(slidableContent.titleTextFontFamily, slidableContent.titleTextStyle)
+ }
+
+ fun getDescriptionTypeface(context: Context): Typeface? {
+ return slidableContent.descriptionTextFontFamilyResId?.let { resId ->
+ ResourcesCompat.getFont(context, resId)
+ } ?: Typeface.create(slidableContent.descriptionTextFontFamily, slidableContent.descriptionTextStyle)
+ }
}
\ No newline at end of file
diff --git a/library/src/main/java/com/trendyol/showcase/ui/tooltip/TooltipView.kt b/library/src/main/java/com/trendyol/showcase/ui/tooltip/TooltipView.kt
index dc8b6ab..316b577 100644
--- a/library/src/main/java/com/trendyol/showcase/ui/tooltip/TooltipView.kt
+++ b/library/src/main/java/com/trendyol/showcase/ui/tooltip/TooltipView.kt
@@ -1,8 +1,8 @@
package com.trendyol.showcase.ui.tooltip
import android.content.Context
-import android.graphics.Typeface
import android.graphics.drawable.ColorDrawable
+import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.ViewGroup
@@ -21,13 +21,15 @@ import com.trendyol.showcase.ui.setTint
import com.trendyol.showcase.ui.slidablecontent.SlidableContent
import com.trendyol.showcase.ui.slidablecontent.SlidableContentAdapter
import com.trendyol.showcase.util.ActionType
+import com.trendyol.showcase.util.TooltipFieldUtil.calculateStartMarginForArrow
class TooltipView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
) : ConstraintLayout(context, attrs) {
- private val binding = LayoutTooltipBinding.inflate(LayoutInflater.from(context), rootView as ViewGroup)
+ private val binding =
+ LayoutTooltipBinding.inflate(LayoutInflater.from(context), rootView as ViewGroup)
private var clickListener: ((ActionType, Int) -> (Unit))? = null
init {
@@ -45,10 +47,7 @@ class TooltipView @JvmOverloads constructor(
internal fun bind(tooltipViewState: TooltipViewState) {
with(binding) {
with(textViewTooltipTitle) {
- typeface = Typeface.create(
- tooltipViewState.getTitleTextFontFamily(),
- tooltipViewState.getTitleTextStyle()
- )
+ typeface = tooltipViewState.getTitleTypeface(context)
text = tooltipViewState.getTitle()
textAlignment = tooltipViewState.getTextPosition()
setTextColor(tooltipViewState.getTitleTextColor())
@@ -56,10 +55,7 @@ class TooltipView @JvmOverloads constructor(
setTextSizeInSp(tooltipViewState.getTitleTextSize())
}
with(textViewTooltipDescription) {
- typeface = Typeface.create(
- tooltipViewState.getDescriptionTextFontFamily(),
- tooltipViewState.getDescriptionTextStyle()
- )
+ typeface = tooltipViewState.getDescriptionTypeface(context)
text = tooltipViewState.getDescription()
textAlignment = tooltipViewState.getTextPosition()
setTextColor(tooltipViewState.getDescriptionTextColor())
@@ -72,8 +68,19 @@ class TooltipView @JvmOverloads constructor(
with(imageViewTopArrow) {
visibility = tooltipViewState.getTopArrowVisibility()
setTint(tooltipViewState.getBackgroundColor())
- layoutMarginStart(tooltipViewState.arrowMargin, tooltipViewState.getArrowPercentage())
- setImageDrawable(ContextCompat.getDrawable(context, tooltipViewState.getTopArrowResource()))
+
+ val drawable: Drawable = requireNotNull(
+ ContextCompat.getDrawable(
+ context,
+ tooltipViewState.getArrowResource()
+ )
+ )
+ val imageStartMargin = calculateStartMarginForArrow(
+ tooltipViewState.arrowMargin,
+ drawable
+ )
+ layoutMarginStart(imageStartMargin, tooltipViewState.getArrowPercentage())
+ setImageDrawable(drawable)
}
layoutContents.isClickable = tooltipViewState.isShowcaseViewClickable()
cardContent.visibility = tooltipViewState.getContentVisibility()
@@ -91,8 +98,19 @@ class TooltipView @JvmOverloads constructor(
with(imageViewBottomArrow) {
visibility = tooltipViewState.getBottomArrowVisibility()
setTint(tooltipViewState.getBackgroundColor())
- layoutMarginStart(tooltipViewState.arrowMargin, tooltipViewState.getArrowPercentage())
- setImageDrawable(ContextCompat.getDrawable(context, tooltipViewState.getBottomArrowResource()))
+ val drawable: Drawable = requireNotNull(
+ ContextCompat.getDrawable(
+ context,
+ tooltipViewState.getArrowResource()
+ )
+ )
+ rotation = 180F
+ val imageStartMargin = calculateStartMarginForArrow(
+ tooltipViewState.arrowMargin,
+ drawable
+ )
+ layoutMarginStart(imageStartMargin, tooltipViewState.getArrowPercentage())
+ setImageDrawable(drawable)
}
}
}
diff --git a/library/src/main/java/com/trendyol/showcase/ui/tooltip/TooltipViewState.kt b/library/src/main/java/com/trendyol/showcase/ui/tooltip/TooltipViewState.kt
index 7cec3a5..8c80a23 100644
--- a/library/src/main/java/com/trendyol/showcase/ui/tooltip/TooltipViewState.kt
+++ b/library/src/main/java/com/trendyol/showcase/ui/tooltip/TooltipViewState.kt
@@ -1,6 +1,9 @@
package com.trendyol.showcase.ui.tooltip
+import android.content.Context
+import android.graphics.Typeface
import android.view.View
+import androidx.core.content.res.ResourcesCompat
import com.trendyol.showcase.R
import com.trendyol.showcase.showcase.ShowcaseModel
import com.trendyol.showcase.util.Constants
@@ -50,15 +53,32 @@ internal data class TooltipViewState(
fun getArrowPercentage() = showcaseModel.arrowPercentage
- fun getTopArrowResource() =
+ fun getArrowResource() =
if (showcaseModel.arrowResource == Constants.DEFAULT_ARROW_RESOURCE) R.drawable.ic_showcase_arrow_up else showcaseModel.arrowResource
- fun getTopArrowVisibility() = if (arrowPosition == AbsoluteArrowPosition.UP) View.VISIBLE else View.GONE
+ fun getTopArrowVisibility(): Int {
+ if (showcaseModel.isArrowVisible.not()) {
+ return View.GONE
+ }
- fun getBottomArrowResource() =
- if (showcaseModel.arrowResource == Constants.DEFAULT_ARROW_RESOURCE) R.drawable.ic_showcase_arrow_down else showcaseModel.arrowResource
+ return if (arrowPosition == AbsoluteArrowPosition.UP) {
+ View.VISIBLE
+ } else {
+ View.GONE
+ }
+ }
- fun getBottomArrowVisibility() = if (arrowPosition == AbsoluteArrowPosition.DOWN) View.VISIBLE else View.GONE
+ fun getBottomArrowVisibility(): Int {
+ if (showcaseModel.isArrowVisible.not()) {
+ return View.GONE
+ }
+
+ return if (arrowPosition == AbsoluteArrowPosition.DOWN) {
+ View.VISIBLE
+ } else {
+ View.GONE
+ }
+ }
fun getCloseButtonColor() = showcaseModel.closeButtonColor
@@ -71,4 +91,16 @@ internal data class TooltipViewState(
fun isSlidableContentVisible() = showcaseModel.slidableContentList.isNullOrEmpty().not()
fun isToolTipVisible() = showcaseModel.isToolTipVisible
+
+ fun getTitleTypeface(context: Context): Typeface? {
+ return showcaseModel.titleTextFontFamilyResId?.let { resId ->
+ ResourcesCompat.getFont(context, resId)
+ } ?: Typeface.create(showcaseModel.titleTextFontFamily, showcaseModel.titleTextStyle)
+ }
+
+ fun getDescriptionTypeface(context: Context): Typeface? {
+ return showcaseModel.descriptionTextFontFamilyResId?.let { resId ->
+ ResourcesCompat.getFont(context, resId)
+ } ?: Typeface.create(showcaseModel.descriptionTextFontFamily, showcaseModel.descriptionTextStyle)
+ }
}
diff --git a/library/src/main/java/com/trendyol/showcase/util/CommonExtensions.kt b/library/src/main/java/com/trendyol/showcase/util/CommonExtensions.kt
index 482e503..abf681b 100644
--- a/library/src/main/java/com/trendyol/showcase/util/CommonExtensions.kt
+++ b/library/src/main/java/com/trendyol/showcase/util/CommonExtensions.kt
@@ -1,11 +1,23 @@
package com.trendyol.showcase.util
+import android.content.Context
import android.content.res.Resources
import android.graphics.Rect
import android.graphics.RectF
+import android.util.DisplayMetrics
+import android.view.View
+import android.view.WindowManager
internal fun Rect.toRectF() = RectF(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat())
internal fun Resources.getHeightInPixels() = displayMetrics.heightPixels
internal fun Resources.getDensity() = displayMetrics.density
+
+internal fun Context.isRTL() = resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL
+
+internal fun Context.screenWidth(): Int {
+ val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
+ val displayMetrics = DisplayMetrics().also { windowManager.defaultDisplay.getMetrics(it) }
+ return displayMetrics.widthPixels
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/trendyol/showcase/util/Constants.kt b/library/src/main/java/com/trendyol/showcase/util/Constants.kt
index 2a9a998..3c698cd 100644
--- a/library/src/main/java/com/trendyol/showcase/util/Constants.kt
+++ b/library/src/main/java/com/trendyol/showcase/util/Constants.kt
@@ -23,11 +23,13 @@ object Constants {
const val DEFAULT_TEXT = ""
const val DEFAULT_SHOW_DURATION = 2000L
const val DEFAULT_SHOW_FOREVER = true
+ const val DEFAULT_ARROW_VISIBILITY = true
const val DEFAULT_ARROW_RESOURCE = -1
val DEFAULT_ARROW_POSITION = ArrowPosition.AUTO
val DEFAULT_HIGHLIGHT_TYPE = HighlightType.RECTANGLE
val DEFAULT_TEXT_POSITION = TextPosition.START
const val DEFAULT_CANCELLABLE_FROM_OUTSIDE_TOUCH = false
+ const val DEFAULT_CANCELLABLE_FROM_SCROLL = false
const val DEFAULT_SHOWCASE_VIEW_CLICKABLE = false
const val DEFAULT_HIGHLIGHT_RADIUS = 0f
}
diff --git a/library/src/main/java/com/trendyol/showcase/util/OnTouchClickListener.kt b/library/src/main/java/com/trendyol/showcase/util/OnTouchClickListener.kt
index bf7558d..6880228 100644
--- a/library/src/main/java/com/trendyol/showcase/util/OnTouchClickListener.kt
+++ b/library/src/main/java/com/trendyol/showcase/util/OnTouchClickListener.kt
@@ -14,6 +14,7 @@ class OnTouchClickListener(private val minMove: Int = 10) : View.OnTouchListener
private var startY: Float = 0f
var clickListener: ((v: View, x: Float, y: Float) -> Unit)? = null
+ var scrollListener: ((v: View, startX: Float, startY: Float, endX: Float, endY: Float) -> Unit)? = null
private fun isAClick(startX: Float, endX: Float, startY: Float, endY: Float): Boolean {
val differenceX = abs(startX - endX)
@@ -33,8 +34,10 @@ class OnTouchClickListener(private val minMove: Int = 10) : View.OnTouchListener
val endY = event.y
if (isAClick(startX, endX, startY, endY)) {
clickListener?.invoke(v, event.x, event.y)
- return true
+ } else {
+ scrollListener?.invoke(v, startX, startY, endX, endY)
}
+ return true
}
}
return false
diff --git a/library/src/main/java/com/trendyol/showcase/util/TooltipFieldUtil.kt b/library/src/main/java/com/trendyol/showcase/util/TooltipFieldUtil.kt
index 65a1b29..e3f3c8a 100644
--- a/library/src/main/java/com/trendyol/showcase/util/TooltipFieldUtil.kt
+++ b/library/src/main/java/com/trendyol/showcase/util/TooltipFieldUtil.kt
@@ -1,6 +1,7 @@
package com.trendyol.showcase.util
import android.graphics.Rect
+import android.graphics.drawable.Drawable
import com.trendyol.showcase.showcase.ShowcaseModel
import com.trendyol.showcase.ui.tooltip.AbsoluteArrowPosition
import com.trendyol.showcase.ui.tooltip.ArrowPosition
@@ -9,14 +10,23 @@ import kotlin.math.sqrt
internal object TooltipFieldUtil {
- fun decideArrowPosition(showcaseModel: ShowcaseModel, screenHeight: Int): AbsoluteArrowPosition =
+ fun decideArrowPosition(
+ showcaseModel: ShowcaseModel,
+ screenHeight: Int
+ ): AbsoluteArrowPosition =
when (showcaseModel.arrowPosition) {
ArrowPosition.UP -> AbsoluteArrowPosition.UP
ArrowPosition.DOWN -> AbsoluteArrowPosition.DOWN
- ArrowPosition.AUTO -> calculateArrowPosition(showcaseModel.verticalCenter(), screenHeight)
+ ArrowPosition.AUTO -> calculateArrowPosition(
+ showcaseModel.verticalCenter(),
+ screenHeight
+ )
}
- private fun calculateArrowPosition(verticalCenter: Float, screenHeight: Int): AbsoluteArrowPosition =
+ private fun calculateArrowPosition(
+ verticalCenter: Float,
+ screenHeight: Int
+ ): AbsoluteArrowPosition =
if (screenHeight / 2 > verticalCenter) {
AbsoluteArrowPosition.UP
} else {
@@ -40,8 +50,12 @@ internal object TooltipFieldUtil {
): Int = when (arrowPosition) {
AbsoluteArrowPosition.UP -> bottom.toInt() + if (isStatusBarVisible) statusBarHeight else 0
AbsoluteArrowPosition.DOWN -> {
- val diff = if (isStatusBarVisible) -statusBarHeight else 0
- (screenHeight - top + diff).toInt()
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM) {
+ (screenHeight - top).toInt()
+ } else {
+ val diff = if (isStatusBarVisible) -statusBarHeight else 0
+ (screenHeight - top + diff).toInt()
+ }
}
}
@@ -55,14 +69,16 @@ internal object TooltipFieldUtil {
): Int = when (arrowPosition) {
AbsoluteArrowPosition.UP -> bottom.toInt() + if (isStatusBarVisible) statusBarHeight else 0
AbsoluteArrowPosition.DOWN -> {
- val diff = if (isStatusBarVisible) -statusBarHeight else 0
- (screenHeight - top + diff).toInt()
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM) {
+ (screenHeight - top).toInt()
+ } else {
+ val diff = if (isStatusBarVisible) -statusBarHeight else 0
+ (screenHeight - top + diff).toInt()
+ }
}
}
- fun calculateArrowMargin(horizontalCenter: Float, density: Float): Int {
- val arrowHalfWidth = (15 * density)
-
- return (horizontalCenter - arrowHalfWidth).toInt()
+ fun calculateStartMarginForArrow(arrowMargin: Int, resource: Drawable): Int {
+ return arrowMargin - (resource.intrinsicWidth) / 2
}
}
diff --git a/library/src/main/java/com/trendyol/showcase/util/shape/CircleShape.kt b/library/src/main/java/com/trendyol/showcase/util/shape/CircleShape.kt
index a5db548..979ec9f 100644
--- a/library/src/main/java/com/trendyol/showcase/util/shape/CircleShape.kt
+++ b/library/src/main/java/com/trendyol/showcase/util/shape/CircleShape.kt
@@ -3,7 +3,6 @@ package com.trendyol.showcase.util.shape
import android.graphics.Canvas
class CircleShape(
- private val statusBarDiff: Int,
screenWidth: Int,
screenHeight: Int,
private val x: Float,
@@ -13,6 +12,6 @@ class CircleShape(
override fun draw(windowBackgroundColor: Int, windowBackgroundAlpha: Int, canvas: Canvas) {
super.draw(windowBackgroundColor, windowBackgroundAlpha, canvas)
- canvas.drawCircle(x, y + statusBarDiff, radius, paint)
+ canvas.drawCircle(x, y, radius, paint)
}
}
diff --git a/library/src/main/java/com/trendyol/showcase/util/shape/RectangleShape.kt b/library/src/main/java/com/trendyol/showcase/util/shape/RectangleShape.kt
index 9ed8337..c4c1c27 100644
--- a/library/src/main/java/com/trendyol/showcase/util/shape/RectangleShape.kt
+++ b/library/src/main/java/com/trendyol/showcase/util/shape/RectangleShape.kt
@@ -5,7 +5,6 @@ import android.graphics.Path
import android.graphics.RectF
class RectangleShape(
- private val statusBarDiff: Int,
screenWidth: Int,
screenHeight: Int,
private val left: Float,
@@ -32,7 +31,7 @@ class RectangleShape(
override fun draw(windowBackgroundColor: Int, windowBackgroundAlpha: Int, canvas: Canvas) {
super.draw(windowBackgroundColor, windowBackgroundAlpha, canvas)
- val rectF = RectF(left, top + statusBarDiff, right, bottom + statusBarDiff)
+ val rectF = RectF(left, top, right, bottom)
path.addRoundRect(rectF, corners, Path.Direction.CW)
canvas.drawPath(path, paint)
}
diff --git a/library/src/main/java/com/trendyol/showcase/util/shape/Shape.kt b/library/src/main/java/com/trendyol/showcase/util/shape/Shape.kt
index ffe1646..2a010b0 100644
--- a/library/src/main/java/com/trendyol/showcase/util/shape/Shape.kt
+++ b/library/src/main/java/com/trendyol/showcase/util/shape/Shape.kt
@@ -8,7 +8,7 @@ import android.graphics.Rect
open class Shape(screenWidth: Int, screenHeight: Int) {
- private val rect = Rect(0, 0, screenWidth, screenHeight)
+ val rect = Rect(0, 0, screenWidth, screenHeight)
protected lateinit var paint: Paint
diff --git a/library/src/main/res/drawable/ic_showcase_arrow_down.xml b/library/src/main/res/drawable/ic_showcase_arrow_down.xml
deleted file mode 100644
index e27ca5e..0000000
--- a/library/src/main/res/drawable/ic_showcase_arrow_down.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/library/src/main/res/layout/item_slidable_content.xml b/library/src/main/res/layout/item_slidable_content.xml
index 24405e5..5bae532 100644
--- a/library/src/main/res/layout/item_slidable_content.xml
+++ b/library/src/main/res/layout/item_slidable_content.xml
@@ -8,8 +8,9 @@
diff --git a/library/src/main/res/layout/layout_tooltip.xml b/library/src/main/res/layout/layout_tooltip.xml
index 85c0463..eb4568f 100644
--- a/library/src/main/res/layout/layout_tooltip.xml
+++ b/library/src/main/res/layout/layout_tooltip.xml
@@ -132,5 +132,6 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/layoutContents"
- tools:srcCompat="@drawable/ic_showcase_arrow_down" />
+ tools:srcCompat="@drawable/ic_showcase_arrow_up"
+ tools:visibility="visible" />
diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml
index f1957fd..2b48431 100644
--- a/library/src/main/res/values/attrs.xml
+++ b/library/src/main/res/values/attrs.xml
@@ -4,8 +4,10 @@
+
+
diff --git a/library/src/test/java/com/trendyol/showcase/ui/tooltip/TooltipViewStateFactory.kt b/library/src/test/java/com/trendyol/showcase/ui/tooltip/TooltipViewStateFactory.kt
index 8018677..b99b7d3 100644
--- a/library/src/test/java/com/trendyol/showcase/ui/tooltip/TooltipViewStateFactory.kt
+++ b/library/src/test/java/com/trendyol/showcase/ui/tooltip/TooltipViewStateFactory.kt
@@ -17,7 +17,7 @@ internal object TooltipViewStateFactory {
backgroundColor: Int = Color.WHITE,
closeButtonColor: Int = Color.BLACK,
showCloseButton: Boolean = true,
- arrowResource: Int = R.drawable.ic_showcase_arrow_down,
+ arrowResource: Int = R.drawable.ic_showcase_arrow_up,
arrowPosition: ArrowPosition = ArrowPosition.DOWN,
absoluteArrowPosition: AbsoluteArrowPosition = AbsoluteArrowPosition.DOWN,
arrowPercentage: Int = 50,
@@ -27,7 +27,8 @@ internal object TooltipViewStateFactory {
imageUrl: String = "",
customContent: Int? = null,
isStatusBarVisible: Boolean = false,
- arrowMargin: Int = 0
+ arrowMargin: Int = 0,
+ isArrowVisible: Boolean = true
): TooltipViewState {
val showcaseModel = ShowcaseModel(
rectF = RectF(),
@@ -61,13 +62,16 @@ internal object TooltipViewStateFactory {
radiusBottomStart = 0F,
radiusTopEnd = 0F,
descriptionTextFontFamily = "sans-serif",
+ descriptionTextFontFamilyResId = null,
isToolTipVisible = true,
slidableContentList = listOf(),
titleTextStyle = Typeface.BOLD,
descriptionTextStyle = Typeface.NORMAL,
titleTextFontFamily = "sans-serif",
+ titleTextFontFamilyResId = null,
showDuration = 2000L,
- isShowcaseViewVisibleIndefinitely = true
+ isShowcaseViewVisibleIndefinitely = true,
+ isArrowVisible = isArrowVisible
)
return provideTooltipViewState(showcaseModel, absoluteArrowPosition, arrowMargin)
}
diff --git a/library/src/test/java/com/trendyol/showcase/ui/tooltip/TooltipViewStateTest.kt b/library/src/test/java/com/trendyol/showcase/ui/tooltip/TooltipViewStateTest.kt
index 58bcb23..2479c2a 100644
--- a/library/src/test/java/com/trendyol/showcase/ui/tooltip/TooltipViewStateTest.kt
+++ b/library/src/test/java/com/trendyol/showcase/ui/tooltip/TooltipViewStateTest.kt
@@ -125,7 +125,7 @@ class TooltipViewStateTest {
//then
val expectedResult = R.drawable.ic_showcase_arrow_up
- val actualResult = tooltipViewState.getTopArrowResource()
+ val actualResult = tooltipViewState.getArrowResource()
actualResult `should be` expectedResult
}
@@ -137,7 +137,7 @@ class TooltipViewStateTest {
val tooltipViewState = TooltipViewStateFactory.provideTooltipViewState(arrowResource = givenArrowResource)
//then
- val actualResult = tooltipViewState.getTopArrowResource()
+ val actualResult = tooltipViewState.getArrowResource()
actualResult `should be` givenArrowResource
}
@@ -167,50 +167,54 @@ class TooltipViewStateTest {
}
@Test
- fun `when arrowResource is DEFAULT_ARROW_RESOURCE then getBottomArrowResource() returns ic_arrow_down`() {
+ fun `when arrowPosition is DOWN then getBottomArrowVisibility() returns VISIBLE`() {
//when
- val tooltipViewState = TooltipViewStateFactory.provideTooltipViewState(arrowResource = DEFAULT_ARROW_RESOURCE)
+ val tooltipViewState = TooltipViewStateFactory.provideTooltipViewState(absoluteArrowPosition = AbsoluteArrowPosition.DOWN)
//then
- val expectedResult = R.drawable.ic_showcase_arrow_down
- val actualResult = tooltipViewState.getBottomArrowResource()
+ val expectedResult = View.VISIBLE
+ val actualResult = tooltipViewState.getBottomArrowVisibility()
actualResult `should be` expectedResult
}
@Test
- fun `when arrowResource is not DEFAULT_ARROW_RESOURCE then getBottomArrowResource() returns arrowResource`() {
+ fun `when arrowPosition is not DOWN then getBottomArrowVisibility() returns GONE`() {
//when
- val givenArrowResource = android.R.drawable.arrow_down_float
- val tooltipViewState = TooltipViewStateFactory.provideTooltipViewState(arrowResource = givenArrowResource)
+ val tooltipViewState = TooltipViewStateFactory.provideTooltipViewState(absoluteArrowPosition = AbsoluteArrowPosition.UP)
//then
- val actualResult = tooltipViewState.getBottomArrowResource()
+ val expectedResult = View.GONE
+ val actualResult = tooltipViewState.getBottomArrowVisibility()
- actualResult `should be` givenArrowResource
+ actualResult `should be` expectedResult
}
@Test
- fun `when arrowPosition is DOWN then getBottomArrowVisibility() returns VISIBLE`() {
- //when
- val tooltipViewState = TooltipViewStateFactory.provideTooltipViewState(absoluteArrowPosition = AbsoluteArrowPosition.DOWN)
+ fun `Given isArrowVisible false, When getTopArrowVisibility called, Then it should return GONE`() {
+ // Given
+ val isArrowVisible = false
+ val expectedResult = View.GONE
+ val tooltipViewState = TooltipViewStateFactory.provideTooltipViewState(isArrowVisible = isArrowVisible)
- //then
- val expectedResult = View.VISIBLE
- val actualResult = tooltipViewState.getBottomArrowVisibility()
+ // When
+ val actualResult = tooltipViewState.getTopArrowVisibility()
+ // Then
actualResult `should be` expectedResult
}
@Test
- fun `when arrowPosition is not DOWN then getBottomArrowVisibility() returns GONE`() {
- //when
- val tooltipViewState = TooltipViewStateFactory.provideTooltipViewState(absoluteArrowPosition = AbsoluteArrowPosition.UP)
-
- //then
+ fun `Given isArrowVisible false, When getBottomArrowVisibility called, Then it should return GONE`() {
+ // Given
+ val isArrowVisible = false
val expectedResult = View.GONE
+ val tooltipViewState = TooltipViewStateFactory.provideTooltipViewState(isArrowVisible = isArrowVisible)
+
+ // When
val actualResult = tooltipViewState.getBottomArrowVisibility()
+ // Then
actualResult `should be` expectedResult
}
@@ -261,4 +265,4 @@ class TooltipViewStateTest {
actualResult `should be` expectedResult
}
-}
\ No newline at end of file
+}
diff --git a/sample/build.gradle b/sample/build.gradle
index 1587fb6..64432c7 100644
--- a/sample/build.gradle
+++ b/sample/build.gradle
@@ -2,12 +2,12 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
android {
- compileSdkVersion 33
+ compileSdkVersion 35
defaultConfig {
applicationId "com.trendyol.showcase"
minSdkVersion 17
- targetSdkVersion 33
+ targetSdkVersion 35
versionCode 1
versionName "1.0"
}
diff --git a/sample/src/main/java/com/trendyol/sample/SampleFragment.kt b/sample/src/main/java/com/trendyol/sample/SampleFragment.kt
index 8214eb6..72ea27a 100644
--- a/sample/src/main/java/com/trendyol/sample/SampleFragment.kt
+++ b/sample/src/main/java/com/trendyol/sample/SampleFragment.kt
@@ -4,12 +4,14 @@ import android.app.Activity
import android.content.Intent
import android.graphics.Typeface
import android.os.Bundle
+import android.text.SpannableStringBuilder
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
+import androidx.core.text.color
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
@@ -110,6 +112,7 @@ class SampleFragment : Fragment() {
)
.showCloseButton(true)
.cancellableFromOutsideTouch(true)
+ .cancellableFromScroll(true)
.arrowPosition(ArrowPosition.AUTO)
.highlightType(HighlightType.RECTANGLE)
.textPosition(TextPosition.START)
@@ -129,12 +132,21 @@ class SampleFragment : Fragment() {
}
}
+ val descriptionText = SpannableStringBuilder()
+ .color(ContextCompat.getColor(requireContext(), R.color.colorAccent)) {
+ append("Center")
+ }
+ .append(" is ")
+ .color(ContextCompat.getColor(requireContext(), R.color.colorPrimary)) {
+ append("here.")
+ }
+
buttonCenter.setOnClickListener {
val context = requireContext()
ShowcaseManager.Builder()
.focus(buttonCenter)
.titleText("Title For Center!")
- .descriptionText("Center is here.")
+ .descriptionText(descriptionText)
.titleTextColor(ContextCompat.getColor(context, R.color.white))
.titleTextStyle(Typeface.BOLD)
.backgroundColor(ContextCompat.getColor(context, R.color.colorPrimaryDark))
@@ -176,6 +188,7 @@ class SampleFragment : Fragment() {
bottomStartRadius = 16f
)
.cancellableFromOutsideTouch(true)
+ .cancellableFromScroll(true)
.toolTipVisible(false)
.statusBarVisible(isStatusBarVisible)
.build()
@@ -235,7 +248,8 @@ class SampleFragment : Fragment() {
private fun buildSlidableContentList(): List {
val context = requireContext()
val baseSlidableContent = slidableContent {
- imageUrl = "https://upload.wikimedia.org/wikipedia/commons/7/7c/Aspect_ratio_16_9_example.jpg"
+ imageUrl =
+ "https://upload.wikimedia.org/wikipedia/commons/7/7c/Aspect_ratio_16_9_example.jpg"
titleTextColor = ContextCompat.getColor(context, R.color.black)
titleTextSize = 16f
titleTextFontFamily = "sans-serif"
@@ -283,7 +297,8 @@ class SampleFragment : Fragment() {
WindowCompat.setDecorFitsSystemWindows(window, true)
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
if (isStatusBarVisible) {
- windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_TOUCH
+ windowInsetsController.systemBarsBehavior =
+ WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_TOUCH
windowInsetsController.show(WindowInsetsCompat.Type.statusBars())
} else {
windowInsetsController.systemBarsBehavior =
diff --git a/sample/src/main/res/values-v35/styles.xml b/sample/src/main/res/values-v35/styles.xml
new file mode 100644
index 0000000..b529868
--- /dev/null
+++ b/sample/src/main/res/values-v35/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file