Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate the Target and realize the use of the square view on the basis of the circle #404

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Prev Previous commit
-Putting more attributes in TapTargetShapeType can customize the sett…
…ings, and in order to prevent conflicts between each TapTargetView, it will not be used as a singleton, and a new object will be used for each use to prevent data confusion.

-In the RectangleType mode, the text may be incompletely displayed or blocked by the targetView. Repairs have been made, and the method of obtaining textBounds is migrated to TapTargetShapeType. The author does not modify the original one, but modifies the RectAngleShapeType to obtain the correct display coordinates. .
  • Loading branch information
huaweikai committed Aug 9, 2023
commit 84c5a09fe98adac1a0ad27ead4c4c963f09301d9
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,10 @@ class MainActivity : AppCompatActivity() {
}
})

val ed = findViewById<EditText>(R.id.ed)
val ed = findViewById<View>(R.id.ed)
ed.setOnClickListener {
showGuideView(
ed.createTarget("Please Input Some Thing")
ed.createTarget("Please Input Some Thing", "Hello Some One")
.outerCircleColor(R.color.colorAccent)
.targetIconColor(android.R.color.holo_blue_dark)
.transparentTarget(true)
Expand All @@ -159,7 +159,7 @@ class MainActivity : AppCompatActivity() {
override fun onTargetClick(view: TapTargetView) {
Toast.makeText(
view.context,
"You clicked the target!",
"You clicked the target! yes!!!!!",
Toast.LENGTH_SHORT
).show()
super.onTargetClick(view)
Expand Down
9 changes: 4 additions & 5 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,13 @@
android:layout_height="wrap_content"
android:padding="16dp"/>

<EditText
<View
android:id="@+id/ed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="32dp"
android:layout_width="200dp"
android:layout_height="102dp"
android:padding="16dp"
android:layout_gravity="bottom|start"
android:background="@color/colorPrimary"
style="@style/ThemeOverlay.Material3.TextInputEditText"
android:hint="Please input some thing"/>

</LinearLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -304,12 +304,12 @@ public TapTargetView(final Context context,
this.title = target.getTitle();
this.description = target.getDescription();

TARGET_PADDING = UiUtils.getDp( 20);
CIRCLE_PADDING = UiUtils.getDp( 40);
TEXT_PADDING = UiUtils.getDp( 40);
TEXT_SPACING = UiUtils.getDp( 8);
TEXT_MAX_WIDTH = UiUtils.getDp( 360);
TEXT_POSITIONING_BIAS = UiUtils.getDp( 20);
TARGET_PADDING = getTapType().getTargetPadding();
CIRCLE_PADDING = getTapType().getCirclePadding();
TEXT_PADDING = getTapType().getTextPadding();
TEXT_SPACING = getTapType().getTextSpacing();
TEXT_MAX_WIDTH = getTapType().getTextMaxWidth();
TEXT_POSITIONING_BIAS = getTapType().getTextPositionBias();
GUTTER_DIM = UiUtils.getDp( 88);
SHADOW_DIM = UiUtils.getDp( 8);
SHADOW_JITTER_DIM = UiUtils.getDp( 1);
Expand Down Expand Up @@ -845,23 +845,9 @@ int getOuterCircleRadius(int centerX, int centerY, Rect textBounds, Rect targetB
}

Rect getTextBounds() {
int targetLength = getTapType().getEdgeLength();
final int totalTextHeight = getTotalTextHeight();
final int totalTextWidth = getTotalTextWidth();

final int possibleTop = targetBounds.centerY() - targetLength - TARGET_PADDING - totalTextHeight;
final int top;
if (possibleTop > topBoundary) {
top = possibleTop;
} else {
top = targetBounds.centerY() + targetLength + TARGET_PADDING;
}

final int relativeCenterDistance = (getWidth() / 2) - targetBounds.centerX();
final int bias = relativeCenterDistance < 0 ? -TEXT_POSITIONING_BIAS : TEXT_POSITIONING_BIAS;
final int left = Math.max(TEXT_PADDING, targetBounds.centerX() - bias - totalTextWidth);
final int right = Math.min(getWidth() - TEXT_PADDING, left + totalTextWidth);
return new Rect(left, top, right, top + totalTextHeight);
return getTapType().getTextBounds(totalTextHeight, totalTextWidth, targetBounds, topBoundary, getWidth());
}

int[] getOuterCircleCenterPoint() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import com.getkeepsafe.taptargetview.halfwayLerp
import kotlin.math.pow
import kotlin.math.roundToInt

object CircleShapeTapTarget: TapTargetShapeType {
class CircleShapeTapTarget: TapTargetShapeType() {

private var targetRadius = 44

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.getkeepsafe.taptargetview.dp
import com.getkeepsafe.taptargetview.getDelayLerp
import com.getkeepsafe.taptargetview.halfwayLerp

object RectAngleShapeType : TapTargetShapeType {
class RectAngleShapeType : TapTargetShapeType() {

private var width = 0

Expand Down Expand Up @@ -106,6 +106,20 @@ object RectAngleShapeType : TapTargetShapeType {
)
}

override fun getTextVertical(
targetBounds: Rect,
totalTextHeight: Int,
topBoundary: Int
): Pair<Int, Int> {
val possibleTop = targetBounds.top - edgeLength - totalTextHeight - textPadding
val top = if (possibleTop > topBoundary) {
possibleTop
} else {
targetBounds.centerY() + edgeLength + targetPadding
}
return top to top + totalTextHeight
}

override fun clickInTarget(targetBounds: Rect, lastTouchX: Int, lastTouchY: Int): Boolean {
return targetBounds.contains(lastTouchX, lastTouchY)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ open class TapTarget {
private var bounds: Rect?
var icon: Drawable? = null

internal var tapTargetType: TapTargetShapeType = CircleShapeTapTarget
internal var tapTargetType: TapTargetShapeType = TapTargetShapeType.Circle

@JvmOverloads
constructor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,51 +5,111 @@ import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import com.getkeepsafe.taptargetview.dp

abstract class TapTargetShapeType {

var textPadding = 40.dp

var circlePadding = 40.dp

var textSpacing = 8.dp

var textMaxWidth = 360.dp

var targetPadding = 20.dp

var textPositionBias = 20.dp

interface TapTargetShapeType {

companion object {

val Circle = CircleShapeTapTarget
val Circle = CircleShapeTapTarget()

val RectAngle = RectAngleShapeType
val RectAngle = RectAngleShapeType()

fun RectAngle(roundRadius: Int): RectAngleShapeType {
RectAngleShapeType.roundRadius = roundRadius
return RectAngleShapeType
val rectangleType = RectAngleShapeType()
rectangleType.roundRadius = roundRadius
return rectangleType
}

}


val edgeLength: Int
abstract val edgeLength: Int

fun initResource(context: Context) {}
open fun initResource(context: Context) {}

fun expandContractChange(lerpTime: Float, isExpanding: Boolean)
abstract fun expandContractChange(lerpTime: Float, isExpanding: Boolean)

fun pulseAnimation(lerpTime: Float) {}
open fun pulseAnimation(lerpTime: Float) {}

fun dismissConfirmAnimation(lerpTime: Float)
abstract fun dismissConfirmAnimation(lerpTime: Float)

fun drawTarget(
abstract fun drawTarget(
canvas: Canvas,
targetBounds: Rect,
paint: Paint
)

fun drawPulse(
open fun drawPulse(
canvas: Canvas,
targetPulseAlpha: Float,
targetBounds: Rect,
paint: Paint
) {}

fun drawInformation(canvas: Canvas, targetBounds: Rect, paint: Paint) {}
open fun drawInformation(canvas: Canvas, targetBounds: Rect, paint: Paint) {}

fun clickInTarget(targetBounds: Rect, lastTouchX: Int, lastTouchY: Int): Boolean
abstract fun clickInTarget(targetBounds: Rect, lastTouchX: Int, lastTouchY: Int): Boolean

fun onReadyTarget(bounds: Rect?) {}
open fun onReadyTarget(bounds: Rect?) {}

open fun getTextBounds(
totalTextHeight: Int,
totalTextWidth: Int,
targetBounds: Rect,
topBoundary: Int,
viewWidth: Int
): Rect {
val verticalLocation = getTextVertical(targetBounds, totalTextHeight, topBoundary)
val horizontalLocation = getTextHorizontal(targetBounds, totalTextWidth, viewWidth, viewWidth)
return Rect(
horizontalLocation.first,
verticalLocation.first,
horizontalLocation.second,
verticalLocation.second
)
}

open fun getTextVertical(
targetBounds: Rect,
totalTextHeight: Int,
topBoundary: Int
): Pair<Int, Int> {
val possibleTop = targetBounds.centerY() - edgeLength - targetPadding - totalTextHeight
val top = if (possibleTop > topBoundary) {
possibleTop
} else {
targetBounds.centerY() + edgeLength + targetPadding
}
return top to top + totalTextHeight
}

open fun getTextHorizontal(
targetBounds: Rect,
totalTextWidth: Int,
leftBoundary: Int,
viewWidth: Int
): Pair<Int, Int> {
val relativeCenterDistance: Int = viewWidth / 2 - targetBounds.centerX()
val bias: Int =
if (relativeCenterDistance < 0) -textPositionBias else textPositionBias
val left: Int = textPadding.coerceAtLeast(targetBounds.centerX() - bias - totalTextWidth)
val right = (viewWidth - textPadding).coerceAtMost(left + totalTextWidth)
return left to right
}

}