From b2bc93b61eb0063487468ce65092ecbb75fd785f Mon Sep 17 00:00:00 2001 From: adwait Date: Wed, 28 Jul 2021 20:09:15 +0530 Subject: [PATCH 1/4] Added ability to change color of message box, message text, line and pointer. --- app/build.gradle | 4 +- .../eram/showcaseview/MainActivity.java | 5 + .../showcaseviewlib/GuideMessageView.java | 9 ++ .../ir/eram/showcaseviewlib/GuideView.java | 122 +++++++++++++++++- 4 files changed, 134 insertions(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index e9bb38e..9d1c29e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,8 +4,8 @@ android { compileSdkVersion 26 defaultConfig { applicationId "smartdevelop.ir.eram.showcaseview" - minSdkVersion 11 - targetSdkVersion 25 + minSdkVersion 21 + targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/ir/smartdevelop/eram/showcaseview/MainActivity.java b/app/src/main/java/ir/smartdevelop/eram/showcaseview/MainActivity.java index 222e93d..c7824f1 100644 --- a/app/src/main/java/ir/smartdevelop/eram/showcaseview/MainActivity.java +++ b/app/src/main/java/ir/smartdevelop/eram/showcaseview/MainActivity.java @@ -1,5 +1,6 @@ package ir.smartdevelop.eram.showcaseview; +import android.graphics.Color; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; @@ -40,6 +41,10 @@ protected void onCreate(Bundle savedInstanceState) { .setDismissType(DismissType.anywhere) .setPointerType(PointerType.arrow) .setTargetView(view1) + .setMessageBoxColor(Color.BLACK) + .setLineAndPointerColor(Color.WHITE) + .setMessageTitleColor(Color.WHITE) + .setMessageContentTextColor(Color.WHITE) .setGuideListener(new GuideListener() { @Override public void onDismiss(View view) { diff --git a/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideMessageView.java b/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideMessageView.java index 4005562..e3f79bb 100644 --- a/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideMessageView.java +++ b/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideMessageView.java @@ -111,6 +111,15 @@ public void setColor(int color) { invalidate(); } + public void setTitleColor(int color) { + if(color!=0) + mTitleTextView.setTextColor(color); + } + + public void setContentTextColor(int color) { + if(color!=0) + mContentTextView.setTextColor(color); + } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); diff --git a/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideView.java b/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideView.java index 33444b2..784b961 100644 --- a/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideView.java +++ b/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideView.java @@ -50,9 +50,9 @@ public class GuideView extends FrameLayout { private static final int MARGIN_INDICATOR = 15; private static final int BACKGROUND_COLOR = 0x99000000; - private static final int CIRCLE_INNER_INDICATOR_COLOR = 0xffcccccc; - private static final int CIRCLE_INDICATOR_COLOR = Color.WHITE; - private static final int LINE_INDICATOR_COLOR = Color.WHITE; + private static int CIRCLE_INNER_INDICATOR_COLOR = 0xffcccccc; + private static int CIRCLE_INDICATOR_COLOR = Color.WHITE; + private static int LINE_INDICATOR_COLOR = Color.WHITE; private final Paint selfPaint = new Paint(); private final Paint paintLine = new Paint(); @@ -80,6 +80,9 @@ public class GuideView extends FrameLayout { private float marginGuide; private float strokeCircleWidth; private float indicatorHeight; + private int messageBoxColor = Color.WHITE; + private int messageTitleColor = Color.BLACK; + private int messageContentTextColor = Color.BLACK; private boolean isPerformedAnimationSize = false; @@ -117,7 +120,7 @@ private GuideView(Context context, View view) { messageViewPadding, messageViewPadding ); - mMessageView.setColor(Color.WHITE); + mMessageView.setColor(messageBoxColor); addView( mMessageView, @@ -251,6 +254,9 @@ private boolean isLandscape() { @Override protected void onDraw(final Canvas canvas) { super.onDraw(canvas); + mMessageView.setColor(messageBoxColor); + mMessageView.setTitleColor(messageTitleColor); + mMessageView.setContentTextColor(messageContentTextColor); if (target != null) { selfPaint.setColor(BACKGROUND_COLOR); @@ -486,6 +492,13 @@ public static class Builder { private float circleIndicatorSize; private float circleInnerIndicatorSize; private float strokeCircleWidth; + private int messageBoxColor; + private int messageBoxAndLineAndPointerColor; + private int lineAndPointerColor; + private int pointerColor; + private int lineColor; + private int messageTitleColor; + private int messageContentTextColor; public Builder(Context context) { this.context = context; @@ -657,6 +670,80 @@ public Builder setPointerType(PointerType pointerType) { this.pointerType = pointerType; return this; } + + /** + * the defined messageBoxColor overrides any defined messageBoxColor in the default or provided style + * + * @param messageBoxColor color of messageBox + * @return builder + */ + public Builder setMessageBoxColor(int messageBoxColor) { + this.messageBoxColor = messageBoxColor; + return this; + } + + + /** + * the defined messageBoxAndLineAndPointerColor overrides any defined messageBoxAndLineAndPointerColor in the default or provided style + * + * @param messageBoxAndLineAndPointerColor color of messageBox + * @return builder + */ + public Builder setColorOfMessageBoxAndLineAndPointer(int messageBoxAndLineAndPointerColor) { + this.messageBoxAndLineAndPointerColor = messageBoxAndLineAndPointerColor; + return this; + } + /** + * the defined LineAndPointerColor overrides any defined messageBoxAndLineAndPointerColor in the default or provided style + * + * @param lineAndPointerColor color of messageBox + * @return builder + */ + public Builder setLineAndPointerColor(int lineAndPointerColor) { + this.lineAndPointerColor = lineAndPointerColor; + return this; + } + /** + * the defined LineColor overrides any defined messageBoxAndLineAndPointerColor in the default or provided style + * + * @param lineColor color of messageBox + * @return builder + */ + public Builder setLineColor(int lineColor) { + this.lineColor = lineColor; + return this; + } + /** + * the defined PointerColor overrides any defined messageBoxAndLineAndPointerColor in the default or provided style + * + * @param pointerColor color of messageBox + * @return builder + */ + public Builder setPointerColor(int pointerColor) { + this.pointerColor = pointerColor; + return this; + } + /** + * the defined PointerColor overrides any defined messageBoxAndLineAndPointerColor in the default or provided style + * + * @param messageTitleColor color of messageBox + * @return builder + */ + public Builder setMessageTitleColor(int messageTitleColor) { + this.messageTitleColor = messageTitleColor; + return this; + } + /** + * the defined PointerColor overrides any defined messageBoxAndLineAndPointerColor in the default or provided style + * + * @param messageContentTextColor color of messageBox + * @return builder + */ + public Builder setMessageContentTextColor(int messageContentTextColor) { + this.messageContentTextColor = messageContentTextColor; + return this; + } + public GuideView build() { GuideView guideView = new GuideView(context, targetView); guideView.mGravity = gravity != null ? gravity : Gravity.auto; @@ -701,6 +788,33 @@ public GuideView build() { if (strokeCircleWidth != 0) { guideView.strokeCircleWidth = strokeCircleWidth * density; } + if (messageBoxColor != 0) { + guideView.messageBoxColor = messageBoxColor; + } + if (messageBoxAndLineAndPointerColor != 0) { + guideView.LINE_INDICATOR_COLOR = messageBoxAndLineAndPointerColor; + guideView.CIRCLE_INDICATOR_COLOR = messageBoxAndLineAndPointerColor; + guideView.CIRCLE_INNER_INDICATOR_COLOR = messageBoxAndLineAndPointerColor; + guideView.messageBoxColor = messageBoxAndLineAndPointerColor; + } + if (lineAndPointerColor != 0) { + guideView.LINE_INDICATOR_COLOR = lineAndPointerColor; + guideView.CIRCLE_INDICATOR_COLOR = lineAndPointerColor; + guideView.CIRCLE_INNER_INDICATOR_COLOR = lineAndPointerColor; + } + if (lineColor != 0) { + guideView.LINE_INDICATOR_COLOR = lineColor; + } + if (pointerColor != 0) { + guideView.CIRCLE_INDICATOR_COLOR = pointerColor; + guideView.CIRCLE_INNER_INDICATOR_COLOR = pointerColor; + } + if (messageTitleColor != 0) { + guideView.messageTitleColor = messageTitleColor; + } + if (messageContentTextColor != 0) { + guideView.messageContentTextColor = messageContentTextColor; + } return guideView; } From 0da9aa08274410e26bebf4a6103c7c5c1e81a489 Mon Sep 17 00:00:00 2001 From: adwait Date: Fri, 30 Jul 2021 16:50:51 +0530 Subject: [PATCH 2/4] Added skip button for a sequence show case --- .../eram/showcaseview/MainActivity.java | 1 + .../ir/eram/showcaseviewlib/GuideView.java | 76 +++++++++++++++---- 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/ir/smartdevelop/eram/showcaseview/MainActivity.java b/app/src/main/java/ir/smartdevelop/eram/showcaseview/MainActivity.java index c7824f1..7eb9c40 100644 --- a/app/src/main/java/ir/smartdevelop/eram/showcaseview/MainActivity.java +++ b/app/src/main/java/ir/smartdevelop/eram/showcaseview/MainActivity.java @@ -45,6 +45,7 @@ protected void onCreate(Bundle savedInstanceState) { .setLineAndPointerColor(Color.WHITE) .setMessageTitleColor(Color.WHITE) .setMessageContentTextColor(Color.WHITE) + .setSkip(true,view6) .setGuideListener(new GuideListener() { @Override public void onDismiss(View view) { diff --git a/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideView.java b/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideView.java index 784b961..1f1d2f7 100644 --- a/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideView.java +++ b/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideView.java @@ -26,6 +26,7 @@ import android.view.ViewTreeObserver; import android.view.animation.AlphaAnimation; import android.widget.FrameLayout; +import android.widget.TextView; import smartdevelop.ir.eram.showcaseviewlib.config.DismissType; import smartdevelop.ir.eram.showcaseviewlib.config.Gravity; @@ -91,6 +92,11 @@ public class GuideView extends FrameLayout { private DismissType dismissType; private PointerType pointerType; private final GuideMessageView mMessageView; + private final TextView skipButton; + private View lastTargetView; + //Skip button is false by default + private boolean setSkip =false; + FrameLayout.LayoutParams skipParams; private GuideView(Context context, View view) { super(context); @@ -114,6 +120,21 @@ private GuideView(Context context, View view) { } mMessageView = new GuideMessageView(getContext()); + skipButton = new TextView(context); + skipButton.setText("SKIP"); + skipButton.setTextColor(Color.WHITE); + skipButton.setGravity(android.view.Gravity.CENTER); + skipButton.setPadding( + messageViewPadding, + messageViewPadding, + messageViewPadding, + messageViewPadding + ); + skipParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); + ((LayoutParams)skipParams).setMargins(0,0,10,140); + ((LayoutParams)skipParams).gravity = android.view.Gravity.RIGHT | android.view.Gravity.BOTTOM; + skipButton.setLayoutParams(skipParams); + mMessageView.setPadding( messageViewPadding, messageViewPadding, @@ -129,7 +150,16 @@ private GuideView(Context context, View view) { ViewGroup.LayoutParams.WRAP_CONTENT ) ); - + skipButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + if(setSkip && lastTargetView!=null) + dismiss(lastTargetView); + } + }); + if(setSkip) { + addView(skipButton, skipParams); + } setMessageLocation(resolveMessageViewLocation()); ViewTreeObserver.OnGlobalLayoutListener layoutListener = new ViewTreeObserver.OnGlobalLayoutListener() { @@ -327,11 +357,11 @@ public boolean isShowing() { return mIsShowing; } - public void dismiss() { + public void dismiss(View view) { ((ViewGroup) ((Activity) getContext()).getWindow().getDecorView()).removeView(this); mIsShowing = false; if (mGuideListener != null) { - mGuideListener.onDismiss(target); + mGuideListener.onDismiss(view); } } @@ -346,24 +376,24 @@ public boolean onTouchEvent(MotionEvent event) { case outside: if (!isViewContains(mMessageView, x, y)) { - dismiss(); + dismiss(target); } break; case anywhere: - dismiss(); + dismiss(target); break; case targetView: if (targetRect.contains(x, y)) { target.performClick(); - dismiss(); + dismiss(target); } break; case selfView: if (isViewContains(mMessageView, x, y)) { - dismiss(); + dismiss(target); } break; } @@ -444,6 +474,9 @@ public void show() { startAnimation.setFillAfter(true); this.startAnimation(startAnimation); mIsShowing = true; + if(setSkip) { + addView(skipButton, skipParams); + } } public void setTitle(String str) { @@ -497,6 +530,8 @@ public static class Builder { private int lineAndPointerColor; private int pointerColor; private int lineColor; + private boolean setSkip; + private View lastTargetView; private int messageTitleColor; private int messageContentTextColor; @@ -694,7 +729,7 @@ public Builder setColorOfMessageBoxAndLineAndPointer(int messageBoxAndLineAndPoi return this; } /** - * the defined LineAndPointerColor overrides any defined messageBoxAndLineAndPointerColor in the default or provided style + * the defined LineAndPointerColor overrides any defined lineAndPointerColor in the default or provided style * * @param lineAndPointerColor color of messageBox * @return builder @@ -704,7 +739,7 @@ public Builder setLineAndPointerColor(int lineAndPointerColor) { return this; } /** - * the defined LineColor overrides any defined messageBoxAndLineAndPointerColor in the default or provided style + * the defined LineColor overrides any defined lineColor in the default or provided style * * @param lineColor color of messageBox * @return builder @@ -714,7 +749,7 @@ public Builder setLineColor(int lineColor) { return this; } /** - * the defined PointerColor overrides any defined messageBoxAndLineAndPointerColor in the default or provided style + * the defined setPointerColor overrides any defined pointerColor in the default or provided style * * @param pointerColor color of messageBox * @return builder @@ -724,7 +759,7 @@ public Builder setPointerColor(int pointerColor) { return this; } /** - * the defined PointerColor overrides any defined messageBoxAndLineAndPointerColor in the default or provided style + * the defined setMessageTitleColor overrides any defined messageTitleColor in the default or provided style * * @param messageTitleColor color of messageBox * @return builder @@ -734,7 +769,7 @@ public Builder setMessageTitleColor(int messageTitleColor) { return this; } /** - * the defined PointerColor overrides any defined messageBoxAndLineAndPointerColor in the default or provided style + * the defined setMessageContentTextColor overrides any defined messageContentTextColor in the default or provided style * * @param messageContentTextColor color of messageBox * @return builder @@ -743,6 +778,18 @@ public Builder setMessageContentTextColor(int messageContentTextColor) { this.messageContentTextColor = messageContentTextColor; return this; } + /** + * the defined setSkip overrides any defined setSkip in the default + * + * @param setSkip true if to show Skip button + * @param lastTargetView Last target view + * @return builder + */ + public Builder setSkip(boolean setSkip,View lastTargetView) { + this.setSkip = setSkip; + this.lastTargetView = lastTargetView; + return this; + } public GuideView build() { GuideView guideView = new GuideView(context, targetView); @@ -750,7 +797,7 @@ public GuideView build() { guideView.dismissType = dismissType != null ? dismissType : DismissType.targetView; guideView.pointerType = pointerType != null ? pointerType : PointerType.circle; float density = context.getResources().getDisplayMetrics().density; - + guideView.setSkip = setSkip; guideView.setTitle(title); if (contentText != null) { guideView.setContentText(contentText); @@ -815,6 +862,9 @@ public GuideView build() { if (messageContentTextColor != 0) { guideView.messageContentTextColor = messageContentTextColor; } + if (setSkip) { + guideView.lastTargetView = lastTargetView; + } return guideView; } From e22ec89206ab9974c2a5f1ea885ee04b70e0ab17 Mon Sep 17 00:00:00 2001 From: Adwait Samant <50566871+Adw41t@users.noreply.github.com> Date: Sun, 1 Aug 2021 23:23:44 +0530 Subject: [PATCH 3/4] Update README.md Added changes related to color change of MessageBox, Title, ContentText and addition of Skip button. --- README.md | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dfe8b09..48fd091 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,36 @@ new GuideView.Builder(this) .setDismissType(DismissType.outSide) //optional - default dismissible by TargetView .build() .show(); -``` +``` + +## Change title and Content text color + +```java +new GuideView.Builder(this) + .setTitle("Guide Title Text") + .setContentText("Guide Description Text\n .....Guide Description Text\n .....Guide Description Text .....") + .setTargetView(view) + .setMessageTitleColor(Color.BLACK)//optional - default is BLACK + .setMessageContentTextColor(Color.BLACK)//optional - default is BLACK + .setDismissType(DismissType.outSide) //optional - default dismissible by TargetView + .build() + .show(); +``` + +## Change MessageBox color and color of Line and Pointer + +```java +new GuideView.Builder(this) + .setTitle("Guide Title Text") + .setContentText("Guide Description Text\n .....Guide Description Text\n .....Guide Description Text .....") + .setTargetView(view) + .setMessageBoxColor(Color.WHITE) //optional - default is WHITE + .setLineAndPointerColor(Color.WHITE) //optional - default is WHITE + .setDismissType(DismissType.outSide) //optional - default dismissible by TargetView + .build() + .show(); +``` + ## Change Gravity ```java @@ -112,6 +141,17 @@ new GuideView.Builder(this) .build() .show(); ``` + +## use Skip for Sequence of ShowCase +```java +new GuideView.Builder(this) + .setTitle("Guide Title Text") + .setTargetView(view) + .setSkip(true,view6) // view6 is supposed to be the last target view of the sequence. + .setDismissType(DismissType.outSide) //optional - default dismissible by TargetView + .build() + .show(); +``` ## Set Listener ```java From b81d2b8693cd080e23abd0513f49c6b81ad1102b Mon Sep 17 00:00:00 2001 From: adwait Date: Sat, 14 Aug 2021 12:08:19 +0530 Subject: [PATCH 4/4] Fixed misalignment of GuideView and Skip on orientation change --- .../eram/showcaseview/CircleView.java | 3 +- .../ir/eram/showcaseviewlib/GuideView.java | 38 ++++++++++++++++--- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/ir/smartdevelop/eram/showcaseview/CircleView.java b/app/src/main/java/ir/smartdevelop/eram/showcaseview/CircleView.java index ca9bfa9..d13dd89 100644 --- a/app/src/main/java/ir/smartdevelop/eram/showcaseview/CircleView.java +++ b/app/src/main/java/ir/smartdevelop/eram/showcaseview/CircleView.java @@ -87,8 +87,7 @@ protected void onDraw(Canvas canvas) _paint.setColor(_circleColor); canvas.drawCircle(cx, cy, radius, _paint); - - getLocationOnScreen(locationTarget); + getLocationInWindow(locationTarget); int centerX = pl + halfUsableWidth + locationTarget[0]; int centerY = pt + halfUsableHeight + locationTarget[1]; _guidePath.reset(); diff --git a/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideView.java b/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideView.java index 1f1d2f7..a6baab7 100644 --- a/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideView.java +++ b/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/GuideView.java @@ -20,10 +20,13 @@ import android.graphics.Xfermode; import android.os.Build; import android.text.Spannable; +import android.view.Display; import android.view.MotionEvent; +import android.view.Surface; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; +import android.view.WindowManager; import android.view.animation.AlphaAnimation; import android.widget.FrameLayout; import android.widget.TextView; @@ -133,7 +136,6 @@ private GuideView(Context context, View view) { skipParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); ((LayoutParams)skipParams).setMargins(0,0,10,140); ((LayoutParams)skipParams).gravity = android.view.Gravity.RIGHT | android.view.Gravity.BOTTOM; - skipButton.setLayoutParams(skipParams); mMessageView.setPadding( messageViewPadding, @@ -157,9 +159,6 @@ public void onClick(View view) { dismiss(lastTargetView); } }); - if(setSkip) { - addView(skipButton, skipParams); - } setMessageLocation(resolveMessageViewLocation()); ViewTreeObserver.OnGlobalLayoutListener layoutListener = new ViewTreeObserver.OnGlobalLayoutListener() { @@ -177,7 +176,7 @@ public void onGlobalLayout() { targetRect = ((Targetable) target).boundingRect(); } else { int[] locationTarget = new int[2]; - target.getLocationOnScreen(locationTarget); + target.getLocationInWindow(locationTarget); targetRect = new RectF( locationTarget[0], locationTarget[1], @@ -281,6 +280,17 @@ private boolean isLandscape() { return display_mode != Configuration.ORIENTATION_PORTRAIT; } + private int checkOrientation(){ + try{ + Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); + int rotation = display.getRotation(); + return rotation; + } + catch (Exception e){ + return Surface.ROTATION_0; + } + } + @Override protected void onDraw(final Canvas canvas) { super.onDraw(canvas); @@ -475,6 +485,24 @@ public void show() { this.startAnimation(startAnimation); mIsShowing = true; if(setSkip) { + + switch(checkOrientation()){ + case Surface.ROTATION_0: + ((LayoutParams)skipParams).setMargins(0,0,10,140); + ((LayoutParams)skipParams).gravity = android.view.Gravity.RIGHT | android.view.Gravity.BOTTOM; + break; + + case Surface.ROTATION_90: + ((LayoutParams)skipParams).setMargins(10,0,0,0); + ((LayoutParams)skipParams).gravity = android.view.Gravity.LEFT | android.view.Gravity.BOTTOM; + break; + + case Surface.ROTATION_270: + ((LayoutParams)skipParams).setMargins(0,0,10,0); + ((LayoutParams)skipParams).gravity = android.view.Gravity.RIGHT | android.view.Gravity.BOTTOM; + break; + } + addView(skipButton, skipParams); } }