diff --git a/app/build.gradle b/app/build.gradle index d0a7ca7..24d6e73 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,10 +5,10 @@ android { defaultConfig { applicationId "smartdevelop.ir.eram.showcaseview" minSdkVersion 14 - targetSdkVersion 30 + targetSdkVersion 33 versionCode 1 versionName "1.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } buildTypes { release { @@ -20,7 +20,7 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.android.support:appcompat-v7:26.1.0' + implementation 'androidx.appcompat:appcompat:1.0.0' implementation project(':showcaseviewlib') } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a78346c..893e3e4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -13,6 +13,7 @@ android:theme="@style/AppTheme"> 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 144875b..565bf03 100644 --- a/app/src/main/java/ir/smartdevelop/eram/showcaseview/MainActivity.java +++ b/app/src/main/java/ir/smartdevelop/eram/showcaseview/MainActivity.java @@ -1,7 +1,7 @@ package ir.smartdevelop.eram.showcaseview; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatActivity; import android.view.View; import smartdevelop.ir.eram.showcaseviewlib.GuideView; @@ -43,19 +43,19 @@ protected void onCreate(Bundle savedInstanceState) { .setGuideListener(view -> { switch (view.getId()) { case R.id.view1: - builder.setTargetView(view2).build(); + builder.setGravity(Gravity.sideauto).setTargetView(view2).build(); break; case R.id.view2: - builder.setTargetView(view3).build(); + builder.setGravity(Gravity.auto).setTargetView(view3).build(); break; case R.id.view3: - builder.setTargetView(view4).build(); + builder.setGravity(Gravity.auto).setTargetView(view4).build(); break; case R.id.view4: - builder.setTargetView(view5).build(); + builder.setGravity(Gravity.auto).setTargetView(view5).build(); break; case R.id.view5: - builder.setTargetView(view6).build(); + builder.setGravity(Gravity.sidecenter).setTargetView(view6).build(); break; case R.id.view6: return; diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index a76eadb..c3c7d3b 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -20,7 +20,7 @@ getHeight() / 2f); - marginGuide = (int) (isTop ? marginGuide : -marginGuide); setMessageLocation(resolveMessageViewLocation()); - startYLineAndCircle = (isTop ? targetRect.bottom : targetRect.top) + marginGuide; - stopY = yMessageView + indicatorHeight + (isTop ? -marginGuide : marginGuide); + if(mGravity == Gravity.sideauto || mGravity == Gravity.sidecenter) { + marginGuide = (int) (isLeft ? -marginGuide : marginGuide); + startYLineAndCircle = (isLeft ? targetRect.left : targetRect.right) + marginGuide; + stopY = xMessageView + indicatorWidth; + } else { + marginGuide = (int) (isTop ? marginGuide : -marginGuide); + startYLineAndCircle = (isTop ? targetRect.bottom : targetRect.top) + marginGuide; + stopY = yMessageView + indicatorHeight; + } startAnimationSize(); } }; @@ -216,6 +226,7 @@ private void init() { lineIndicatorWidthSize = LINE_INDICATOR_WIDTH_SIZE * density; marginGuide = MARGIN_INDICATOR * density; indicatorHeight = INDICATOR_HEIGHT * density; + indicatorWidth = INDICATOR_HEIGHT * density; messageViewPadding = (int) (MESSAGE_VIEW_PADDING * density); strokeCircleWidth = STROKE_CIRCLE_INDICATOR_SIZE * density; circleIndicatorSizeFinal = CIRCLE_INDICATOR_SIZE * density; @@ -269,30 +280,52 @@ protected void onDraw(final Canvas canvas) { paintCircleInner.setColor(CIRCLE_INNER_INDICATOR_COLOR); paintCircleInner.setAntiAlias(true); - final float x = (targetRect.left / 2 + targetRect.right / 2); + float xOfCalloutLine = 0.0f; + if (mGravity == Gravity.sideauto || mGravity == Gravity.sidecenter) { + xOfCalloutLine = (targetRect.top / 2 + targetRect.bottom / 2); + } else { + xOfCalloutLine = (targetRect.left / 2 + targetRect.right / 2); + } + switch (pointerType) { case circle: - canvas.drawLine(x, startYLineAndCircle, x, stopY, paintLine); - canvas.drawCircle(x, startYLineAndCircle, circleIndicatorSize, paintCircle); - canvas.drawCircle( - x, - startYLineAndCircle, - circleInnerIndicatorSize, - paintCircleInner - ); + if (mGravity == Gravity.sideauto || mGravity == Gravity.sidecenter) { + canvas.drawLine(startYLineAndCircle, xOfCalloutLine, stopY, xOfCalloutLine, paintLine); + canvas.drawCircle(startYLineAndCircle, xOfCalloutLine, circleIndicatorSize, paintCircle); + canvas.drawCircle(startYLineAndCircle, xOfCalloutLine, circleInnerIndicatorSize, paintCircleInner); + } + else { + canvas.drawLine(xOfCalloutLine, startYLineAndCircle, xOfCalloutLine, stopY, paintLine); + canvas.drawCircle(xOfCalloutLine, startYLineAndCircle, circleIndicatorSize, paintCircle); + canvas.drawCircle(xOfCalloutLine, startYLineAndCircle, circleInnerIndicatorSize, paintCircleInner); + } + break; case arrow: - canvas.drawLine(x, startYLineAndCircle, x, stopY, paintLine); arrowPath.reset(); - if (isTop) { - arrowPath.moveTo(x, startYLineAndCircle - (circleIndicatorSize * 2)); + if (mGravity == Gravity.sideauto || mGravity == Gravity.sidecenter) { + canvas.drawLine(startYLineAndCircle, xOfCalloutLine, stopY, xOfCalloutLine, paintLine); + if (isLeft) { + arrowPath.moveTo(startYLineAndCircle + (circleIndicatorSize * 2), xOfCalloutLine); + } else { + arrowPath.moveTo(startYLineAndCircle - (circleIndicatorSize * 2), xOfCalloutLine); + } + arrowPath.lineTo(startYLineAndCircle, xOfCalloutLine + circleIndicatorSize); + arrowPath.lineTo(startYLineAndCircle, xOfCalloutLine - circleIndicatorSize); + arrowPath.close(); + } else { - arrowPath.moveTo(x, startYLineAndCircle + (circleIndicatorSize * 2)); + canvas.drawLine(xOfCalloutLine, startYLineAndCircle, xOfCalloutLine, stopY, paintLine); + if (isTop) { + arrowPath.moveTo(xOfCalloutLine, startYLineAndCircle - (circleIndicatorSize * 2)); + } else { + arrowPath.moveTo(xOfCalloutLine, startYLineAndCircle + (circleIndicatorSize * 2)); + } + arrowPath.lineTo(xOfCalloutLine + circleIndicatorSize, startYLineAndCircle); + arrowPath.lineTo(xOfCalloutLine - circleIndicatorSize, startYLineAndCircle); + arrowPath.close(); } - arrowPath.lineTo(x + circleIndicatorSize, startYLineAndCircle); - arrowPath.lineTo(x - circleIndicatorSize, startYLineAndCircle); - arrowPath.close(); canvas.drawPath(arrowPath, paintCircle); break; case none: @@ -392,39 +425,70 @@ public void updateGuideViewLocation() { private Point resolveMessageViewLocation() { - int xMessageView; - if (mGravity == Gravity.center) { - xMessageView = (int) (targetRect.left - mMessageView.getWidth() / 2 + target.getWidth() / 2); - } else { - xMessageView = (int) (targetRect.right) - mMessageView.getWidth(); + if(mGravity == Gravity.sideauto || mGravity == Gravity.sidecenter) + { + if (mGravity == Gravity.sidecenter) { + yMessageView = (int) (targetRect.top + target.getHeight() / 2 - mMessageView.getHeight() / 2); + } else { + yMessageView = (int) (targetRect.top); + } + + if (yMessageView + mMessageView.getHeight() > getHeight()) { + yMessageView = getHeight() - mMessageView.getHeight(); + } + if (yMessageView < 0) { + yMessageView = 0; + } + + //set message view bottom + if ((targetRect.left - (indicatorWidth)) < getWidth() / 2f) { + isLeft = false; + xMessageView = (int) (targetRect.right + indicatorWidth); + } + //set message view top + else { + isLeft = true; + xMessageView = (int) (targetRect.left - mMessageView.getWidth() - indicatorWidth); + } + + if (xMessageView < 0) { + xMessageView = 0; + } + } + else { + if (mGravity == Gravity.center) { + xMessageView = (int) (targetRect.left - mMessageView.getWidth() / 2 + target.getWidth() / 2); + } else { + xMessageView = (int) (targetRect.right) - mMessageView.getWidth(); + } if (isLandscape() && (xMessageView + mMessageView.getWidth()) > backgroundRect.right) { xMessageView -= getNavigationBarSize(); } - if (xMessageView + mMessageView.getWidth() > getWidth()) { - xMessageView = getWidth() - mMessageView.getWidth(); - } - if (xMessageView < 0) { - xMessageView = 0; - } + if (xMessageView + mMessageView.getWidth() > getWidth()) { + xMessageView = getWidth() - mMessageView.getWidth(); + } + if (xMessageView < 0) { + xMessageView = 0; + } - //set message view bottom - if ((targetRect.top + (indicatorHeight)) > getHeight() / 2f) { - isTop = false; - yMessageView = (int) (targetRect.top - mMessageView.getHeight() - indicatorHeight); - } - //set message view top - else { - isTop = true; - yMessageView = (int) (targetRect.top + target.getHeight() + indicatorHeight); - } + //set message view bottom + if ((targetRect.top + (indicatorHeight)) > getHeight() / 2f) { + isTop = false; + yMessageView = (int) (targetRect.top - mMessageView.getHeight() - indicatorHeight); + } + //set message view top + else { + isTop = true; + yMessageView = (int) (targetRect.top + target.getHeight() + indicatorHeight); + } - if (yMessageView < 0) { - yMessageView = 0; + if (yMessageView < 0) { + yMessageView = 0; + } } - return new Point(xMessageView, yMessageView); } diff --git a/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/config/Gravity.java b/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/config/Gravity.java index 7077004..f10be89 100644 --- a/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/config/Gravity.java +++ b/showcaseviewlib/src/main/java/smartdevelop/ir/eram/showcaseviewlib/config/Gravity.java @@ -4,6 +4,6 @@ * Created by Mohammad Reza Eram (https://github.com/mreram) on 27,November,2018 */ public enum Gravity { - auto, center + auto, center, sideauto, sidecenter }