diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3a26a623..1af19183 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -26,10 +26,10 @@ android:supportsRtl="true" android:theme="@style/AppTheme" tools:ignore="GoogleAppIndexingWarning"> - + diff --git a/app/src/main/kotlin/com/skydoves/balloondemo/ComposeActivity.kt b/app/src/main/kotlin/com/skydoves/balloondemo/ComposeActivity.kt index f533add0..44dd18e9 100644 --- a/app/src/main/kotlin/com/skydoves/balloondemo/ComposeActivity.kt +++ b/app/src/main/kotlin/com/skydoves/balloondemo/ComposeActivity.kt @@ -28,6 +28,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material.Button import androidx.compose.material.Text +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -87,12 +88,6 @@ class ComposeActivity : ComponentActivity() { .padding(20.dp) .align(Alignment.Center), builder = builder, - onComposedAnchor = { - balloonWindow1?.showAlignTop() - }, - onBalloonWindowInitialized = { - balloonWindow1 = it - }, balloonContent = { Text( text = "Now you can edit your profile1 profile2 profile3 profile4", @@ -100,7 +95,11 @@ class ComposeActivity : ComponentActivity() { color = Color.White, ) }, - ) { + ) { balloonWindow -> + LaunchedEffect(key1 = Unit) { + balloonWindow1 = balloonWindow + } + Button( modifier = Modifier.size(160.dp, 60.dp), onClick = { balloonWindow1?.showAlignTop() }, @@ -114,9 +113,6 @@ class ComposeActivity : ComponentActivity() { .padding(20.dp) .align(Alignment.TopStart), builder = builder, - onBalloonWindowInitialized = { - balloonWindow2 = it - }, balloonContent = { Text( text = "Now you can edit your profile!", @@ -124,10 +120,14 @@ class ComposeActivity : ComponentActivity() { color = Color.White, ) }, - ) { + ) { balloonWindow -> + LaunchedEffect(key1 = Unit) { + balloonWindow2 = balloonWindow + } + Button( modifier = Modifier.size(160.dp, 60.dp), - onClick = { balloonWindow2?.showAlignBottom() }, + onClick = { balloonWindow2?.showAlignTop() }, ) { Text(text = "wrap balloon") } @@ -138,9 +138,6 @@ class ComposeActivity : ComponentActivity() { .padding(20.dp) .align(Alignment.TopEnd), builder = builder, - onBalloonWindowInitialized = { - balloonWindow3 = it - }, balloonContent = { Box(modifier = Modifier.fillMaxWidth()) { Box( @@ -164,7 +161,11 @@ class ComposeActivity : ComponentActivity() { ) } }, - ) { + ) { balloonWindow -> + LaunchedEffect(key1 = Unit) { + balloonWindow3 = balloonWindow + } + Button( modifier = Modifier.size(160.dp, 60.dp), onClick = { balloonWindow3?.showAlignBottom() }, diff --git a/balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/Balloon.kt b/balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/Balloon.kt index 03c605ac..2e4bfe7c 100644 --- a/balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/Balloon.kt +++ b/balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/Balloon.kt @@ -51,6 +51,7 @@ import androidx.lifecycle.setViewTreeViewModelStoreOwner import androidx.savedstate.findViewTreeSavedStateRegistryOwner import androidx.savedstate.setViewTreeSavedStateRegistryOwner import com.skydoves.balloon.Balloon +import com.skydoves.balloon.BalloonAlign import java.lang.Integer.max import java.util.UUID @@ -156,12 +157,20 @@ public fun Balloon( } Box( - modifier = modifier.onSizeChanged { - anchorView.updateLayoutParams { - width = it.width - height = it.height + modifier = modifier + .onGloballyPositioned { + balloonComposeView.updateAlign( + align = balloonComposeView.balloon.currentAlign ?: BalloonAlign.BOTTOM, + xOff = 0, + yOff = 0, + ) } - }, + .onSizeChanged { + anchorView.updateLayoutParams { + width = it.width + height = it.height + } + }, ) { AndroidView( modifier = Modifier.matchParentSize(), diff --git a/balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonComposeView.kt b/balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonComposeView.kt index 63306996..d58c89a7 100644 --- a/balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonComposeView.kt +++ b/balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonComposeView.kt @@ -242,10 +242,6 @@ internal class BalloonComposeView( balloon.updateAlign(align, anchorView, xOff, yOff) } - @Deprecated( - "Use updateAlign instead.", - replaceWith = ReplaceWith("updateAlign(BalloonAlign.Top, xOff, yOff)"), - ) override fun update(xOff: Int, yOff: Int): Unit = balloon.update(anchorView, xOff, yOff) override fun showAlign( diff --git a/balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonWindow.kt b/balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonWindow.kt index 5fdb41c8..241aa22f 100644 --- a/balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonWindow.kt +++ b/balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonWindow.kt @@ -450,10 +450,6 @@ public interface BalloonWindow { * @param xOff A horizontal offset from the anchor in pixels. * @param yOff A vertical offset from the anchor in pixels. */ - @Deprecated( - "Use updateAlign instead.", - replaceWith = ReplaceWith("updateAlign(BalloonAlign.Top, xOff, yOff)"), - ) public fun update(xOff: Int = 0, yOff: Int = 0) /** updates the size of the balloon card. */ diff --git a/balloon/api/balloon.api b/balloon/api/balloon.api index bc213556..14edceb3 100644 --- a/balloon/api/balloon.api +++ b/balloon/api/balloon.api @@ -90,6 +90,7 @@ public final class com/skydoves/balloon/Balloon : androidx/lifecycle/DefaultLife public final fun getBalloonArrowView ()Landroid/view/View; public final fun getBodyWindow ()Landroid/widget/PopupWindow; public final fun getContentView ()Landroid/view/ViewGroup; + public final fun getCurrentAlign ()Lcom/skydoves/balloon/BalloonAlign; public final fun getMeasuredHeight ()I public final fun getMeasuredWidth ()I public final fun getOverlayWindow ()Landroid/widget/PopupWindow; @@ -186,8 +187,6 @@ public final class com/skydoves/balloon/Balloon : androidx/lifecycle/DefaultLife public final fun showAtCenter (Landroid/view/View;II)V public final fun showAtCenter (Landroid/view/View;IILcom/skydoves/balloon/BalloonCenterAlign;)V public static synthetic fun showAtCenter$default (Lcom/skydoves/balloon/Balloon;Landroid/view/View;IILcom/skydoves/balloon/BalloonCenterAlign;ILjava/lang/Object;)V - public final fun update (Landroid/view/View;)V - public final fun update (Landroid/view/View;I)V public final fun update (Landroid/view/View;II)V public static synthetic fun update$default (Lcom/skydoves/balloon/Balloon;Landroid/view/View;IIILjava/lang/Object;)V public final fun updateAlign (Lcom/skydoves/balloon/BalloonAlign;Landroid/view/View;)V diff --git a/balloon/src/main/kotlin/com/skydoves/balloon/Balloon.kt b/balloon/src/main/kotlin/com/skydoves/balloon/Balloon.kt index 6dd6529b..a21b08c3 100644 --- a/balloon/src/main/kotlin/com/skydoves/balloon/Balloon.kt +++ b/balloon/src/main/kotlin/com/skydoves/balloon/Balloon.kt @@ -177,6 +177,10 @@ public class Balloon private constructor( ViewGroup.LayoutParams.MATCH_PARENT, ) + /** Denotes the align of the currently displaying balloon. */ + public var currentAlign: BalloonAlign? = null + private set + /** Denotes the popup is showing or not. */ public var isShowing: Boolean = false private set @@ -269,41 +273,48 @@ public class Balloon private constructor( adjustArrowOrientationByRules(anchor) - when (builder.arrowOrientation.getRTLSupportOrientation(builder.isRtlLayout)) { - ArrowOrientation.BOTTOM -> { - rotation = 180f - x = getArrowConstraintPositionX(anchor) - y = binding.balloonCard.y + binding.balloonCard.height - SIZE_ARROW_BOUNDARY - ViewCompat.setElevation(this, builder.arrowElevation) - runOnAfterSDK23 { - foreground = getArrowForeground(x, binding.balloonCard.height.toFloat()) - } - } + updateArrow(anchor) - ArrowOrientation.TOP -> { - rotation = 0f - x = getArrowConstraintPositionX(anchor) - y = binding.balloonCard.y - builder.arrowSize + SIZE_ARROW_BOUNDARY - runOnAfterSDK23 { foreground = getArrowForeground(x, 0f) } - } + visible(builder.isVisibleArrow) + } + } + } - ArrowOrientation.START -> { - rotation = -90f - x = binding.balloonCard.x - builder.arrowSize + SIZE_ARROW_BOUNDARY - y = getArrowConstraintPositionY(anchor) - runOnAfterSDK23 { foreground = getArrowForeground(0f, y) } + private fun updateArrow(anchor: View) { + with(binding.balloonArrow) { + when (builder.arrowOrientation.getRTLSupportOrientation(builder.isRtlLayout)) { + ArrowOrientation.BOTTOM -> { + rotation = 180f + x = getArrowConstraintPositionX(anchor) + y = binding.balloonCard.y + binding.balloonCard.height - SIZE_ARROW_BOUNDARY + ViewCompat.setElevation(this, builder.arrowElevation) + runOnAfterSDK23 { + foreground = getArrowForeground(x, binding.balloonCard.height.toFloat()) } + } - ArrowOrientation.END -> { - rotation = 90f - x = binding.balloonCard.x + binding.balloonCard.width - SIZE_ARROW_BOUNDARY - y = getArrowConstraintPositionY(anchor) - runOnAfterSDK23 { - foreground = getArrowForeground(binding.balloonCard.width.toFloat(), y) - } + ArrowOrientation.TOP -> { + rotation = 0f + x = getArrowConstraintPositionX(anchor) + y = binding.balloonCard.y - builder.arrowSize + SIZE_ARROW_BOUNDARY + runOnAfterSDK23 { foreground = getArrowForeground(x, 0f) } + } + + ArrowOrientation.START -> { + rotation = -90f + x = binding.balloonCard.x - builder.arrowSize + SIZE_ARROW_BOUNDARY + y = getArrowConstraintPositionY(anchor) + runOnAfterSDK23 { foreground = getArrowForeground(0f, y) } + } + + ArrowOrientation.END -> { + rotation = 90f + x = binding.balloonCard.x + binding.balloonCard.width - SIZE_ARROW_BOUNDARY + y = getArrowConstraintPositionY(anchor) + runOnAfterSDK23 { + foreground = getArrowForeground(binding.balloonCard.width.toFloat(), y) } } - visible(builder.isVisibleArrow) } } } @@ -794,6 +805,7 @@ public class Balloon private constructor( } this.isShowing = true + this.currentAlign = placement.align val dismissDelay = this.builder.autoDismissDuration if (dismissDelay != NO_LONG_VALUE) { @@ -1531,7 +1543,7 @@ public class Balloon private constructor( @MainThread private fun update(placement: BalloonPlacement) { if (isShowing) { - initializeArrow(placement.anchor) + updateArrow(placement.anchor) val (xOff, yOff) = calculateOffset(placement) this.bodyWindow.update( @@ -1555,13 +1567,15 @@ public class Balloon private constructor( * @param xOff A horizontal offset from the anchor in pixels. * @param yOff A vertical offset from the anchor in pixels. */ - @JvmOverloads - @Deprecated( - "Use updateAlign instead.", - replaceWith = ReplaceWith("updateAlign(BalloonAlign.Top, anchor, xOff, yOff)"), - ) public fun update(anchor: View, xOff: Int = 0, yOff: Int = 0) { - update(placement = BalloonPlacement(anchor = anchor, xOff = xOff, yOff = yOff)) + update( + placement = BalloonPlacement( + anchor = anchor, + xOff = xOff, + yOff = yOff, + type = PlacementType.CENTER, + ), + ) } /** dismiss the popup menu. */ @@ -1569,6 +1583,7 @@ public class Balloon private constructor( if (this.isShowing) { val dismissWindow: () -> Unit = { this.isShowing = false + this.currentAlign = null this.bodyWindow.dismiss() this.overlayWindow.dismiss() this.handler.removeCallbacks(autoDismissRunnable)