Skip to content

Commit 4f6b934

Browse files
authored
Merge pull request #813 from hemantj99/feature/custom-overlay-padding
Added BalloonOverlayPadding data class for customizable overlay paddings and done some minor refactoring.
2 parents 6d3fc4b + 7a7a6ba commit 4f6b934

File tree

4 files changed

+120
-44
lines changed

4 files changed

+120
-44
lines changed

balloon/api/balloon.api

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ public final class com/skydoves/balloon/Balloon$Builder {
298298
public final fun getOnBalloonTouchListener ()Landroid/view/View$OnTouchListener;
299299
public final fun getOverlayColor ()I
300300
public final fun getOverlayGravity ()I
301-
public final fun getOverlayPadding ()F
301+
public final fun getOverlayPadding ()Lcom/skydoves/balloon/BalloonOverlayPadding;
302302
public final fun getOverlayPaddingColor ()I
303303
public final fun getOverlayPaddingShader ()Landroid/graphics/Shader;
304304
public final fun getOverlayPosition ()Landroid/graphics/Point;
@@ -531,7 +531,9 @@ public final class com/skydoves/balloon/Balloon$Builder {
531531
public final fun setOverlayGravity (I)Lcom/skydoves/balloon/Balloon$Builder;
532532
public final synthetic fun setOverlayGravity (I)V
533533
public final fun setOverlayPadding (F)Lcom/skydoves/balloon/Balloon$Builder;
534-
public final synthetic fun setOverlayPadding (F)V
534+
public final fun setOverlayPadding (FFFF)Lcom/skydoves/balloon/Balloon$Builder;
535+
public final synthetic fun setOverlayPadding (Lcom/skydoves/balloon/BalloonOverlayPadding;)V
536+
public static synthetic fun setOverlayPadding$default (Lcom/skydoves/balloon/Balloon$Builder;FFFFILjava/lang/Object;)Lcom/skydoves/balloon/Balloon$Builder;
535537
public final fun setOverlayPaddingColor (I)Lcom/skydoves/balloon/Balloon$Builder;
536538
public final synthetic fun setOverlayPaddingColor (I)V
537539
public final fun setOverlayPaddingColorResource (I)Lcom/skydoves/balloon/Balloon$Builder;
@@ -719,6 +721,25 @@ public final class com/skydoves/balloon/BalloonKt {
719721
public static final synthetic fun createBalloon (Landroid/content/Context;Lkotlin/jvm/functions/Function1;)Lcom/skydoves/balloon/Balloon;
720722
}
721723

724+
public final class com/skydoves/balloon/BalloonOverlayPadding {
725+
public fun <init> ()V
726+
public fun <init> (FFFF)V
727+
public synthetic fun <init> (FFFFILkotlin/jvm/internal/DefaultConstructorMarker;)V
728+
public final fun component1 ()F
729+
public final fun component2 ()F
730+
public final fun component3 ()F
731+
public final fun component4 ()F
732+
public final fun copy (FFFF)Lcom/skydoves/balloon/BalloonOverlayPadding;
733+
public static synthetic fun copy$default (Lcom/skydoves/balloon/BalloonOverlayPadding;FFFFILjava/lang/Object;)Lcom/skydoves/balloon/BalloonOverlayPadding;
734+
public fun equals (Ljava/lang/Object;)Z
735+
public final fun getBottom ()F
736+
public final fun getLeft ()F
737+
public final fun getRight ()F
738+
public final fun getTop ()F
739+
public fun hashCode ()I
740+
public fun toString ()Ljava/lang/String;
741+
}
742+
722743
public final class com/skydoves/balloon/BalloonPersistence {
723744
public static final field Companion Lcom/skydoves/balloon/BalloonPersistence$Companion;
724745
public final fun clearAllPreferences ()V
@@ -991,15 +1012,15 @@ public final class com/skydoves/balloon/overlay/BalloonAnchorOverlayView : andro
9911012
public final fun getAnchorViewList ()Ljava/util/List;
9921013
public final fun getBalloonOverlayShape ()Lcom/skydoves/balloon/overlay/BalloonOverlayShape;
9931014
public final fun getOverlayColor ()I
994-
public final fun getOverlayPadding ()F
1015+
public final fun getOverlayPadding ()Lcom/skydoves/balloon/BalloonOverlayPadding;
9951016
public final fun getOverlayPaddingColor ()I
9961017
public final fun getOverlayPaddingShader ()Landroid/graphics/Shader;
9971018
public final fun getOverlayPosition ()Landroid/graphics/Point;
9981019
public final fun setAnchorView (Landroid/view/View;)V
9991020
public final fun setAnchorViewList (Ljava/util/List;)V
10001021
public final fun setBalloonOverlayShape (Lcom/skydoves/balloon/overlay/BalloonOverlayShape;)V
10011022
public final fun setOverlayColor (I)V
1002-
public final fun setOverlayPadding (F)V
1023+
public final fun setOverlayPadding (Lcom/skydoves/balloon/BalloonOverlayPadding;)V
10031024
public final fun setOverlayPaddingColor (I)V
10041025
public final fun setOverlayPaddingShader (Landroid/graphics/Shader;)V
10051026
public final fun setOverlayPosition (Landroid/graphics/Point;)V

balloon/src/main/kotlin/com/skydoves/balloon/Balloon.kt

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import android.graphics.Rect
3434
import android.graphics.Shader
3535
import android.graphics.Typeface
3636
import android.graphics.drawable.BitmapDrawable
37-
import android.graphics.drawable.ColorDrawable
3837
import android.graphics.drawable.Drawable
3938
import android.graphics.drawable.GradientDrawable
4039
import android.os.Handler
@@ -64,9 +63,12 @@ import androidx.annotation.MainThread
6463
import androidx.annotation.Px
6564
import androidx.annotation.StringRes
6665
import androidx.annotation.StyleRes
66+
import androidx.core.graphics.createBitmap
67+
import androidx.core.graphics.drawable.toDrawable
6768
import androidx.core.view.ViewCompat
6869
import androidx.core.view.forEach
6970
import androidx.core.view.get
71+
import androidx.core.view.isNotEmpty
7072
import androidx.core.view.updateLayoutParams
7173
import androidx.core.widget.ImageViewCompat
7274
import androidx.lifecycle.DefaultLifecycleObserver
@@ -322,10 +324,7 @@ public class Balloon private constructor(
322324
/** Returns [BitmapDrawable] that will be used for the foreground of the arrow. */
323325
private fun ImageView.getArrowForeground(x: Float, y: Float): BitmapDrawable? {
324326
return if (builder.arrowColorMatchBalloon && isAPILevelHigherThan23()) {
325-
BitmapDrawable(
326-
resources,
327-
adjustArrowColorByMatchingCardBackground(this, x, y),
328-
)
327+
adjustArrowColorByMatchingCardBackground(this, x, y).toDrawable(resources)
329328
} else {
330329
null
331330
}
@@ -364,7 +363,7 @@ public class Balloon private constructor(
364363
val endColor = colors.second
365364

366365
val updatedBitmap =
367-
Bitmap.createBitmap(oldBitmap.width, oldBitmap.height, Bitmap.Config.ARGB_8888)
366+
createBitmap(oldBitmap.width, oldBitmap.height)
368367
val canvas = Canvas(updatedBitmap)
369368
canvas.drawBitmap(oldBitmap, 0f, 0f, null)
370369
val paint = Paint()
@@ -423,7 +422,7 @@ public class Balloon private constructor(
423422
}
424423

425424
private fun drawableToBitmap(drawable: Drawable, width: Int, height: Int): Bitmap {
426-
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
425+
val bitmap = createBitmap(width, height)
427426
val canvas = Canvas(bitmap)
428427
drawable.setBounds(0, 0, canvas.width, canvas.height)
429428
drawable.draw(canvas)
@@ -563,7 +562,7 @@ public class Balloon private constructor(
563562
with(this.bodyWindow) {
564563
isOutsideTouchable = true
565564
isFocusable = builder.isFocusable
566-
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
565+
setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
567566
elevation = builder.elevation
568567
setIsAttachedInDecor(builder.isAttachedInDecor)
569568
}
@@ -1275,7 +1274,7 @@ public class Balloon private constructor(
12751274
): Balloon = relay(
12761275
balloon,
12771276
) {
1278-
it.showAlignRight(anchor, xOff, yOff)
1277+
it.showAlignEnd(anchor, xOff, yOff)
12791278
}
12801279

12811280
/**
@@ -1376,7 +1375,7 @@ public class Balloon private constructor(
13761375
xOff: Int = 0,
13771376
yOff: Int = 0,
13781377
): Balloon =
1379-
relay(balloon) { it.showAlignLeft(anchor, xOff, yOff) }
1378+
relay(balloon) { it.showAlignStart(anchor, xOff, yOff) }
13801379

13811380
/**
13821381
* Shows the balloon on an anchor view as the start alignment with x-off and y-off
@@ -1696,7 +1695,7 @@ public class Balloon private constructor(
16961695
@InternalBalloonApi
16971696
public fun updateSizeOfBalloonCard(width: Int, height: Int) {
16981697
builder.setMeasuredWidth(width)
1699-
if (binding.balloonCard.childCount != 0) {
1698+
if (binding.balloonCard.isNotEmpty()) {
17001699
val child = binding.balloonCard[0]
17011700
child.updateLayoutParams {
17021701
this.width = width
@@ -2247,7 +2246,7 @@ public class Balloon private constructor(
22472246

22482247
@Px
22492248
@set:JvmSynthetic
2250-
public var overlayPadding: Float = 0f
2249+
public var overlayPadding: BalloonOverlayPadding = BalloonOverlayPadding()
22512250

22522251
@ColorInt
22532252
@set:JvmSynthetic
@@ -2995,12 +2994,24 @@ public class Balloon private constructor(
29952994
}
29962995

29972996
/** sets a padding value of the overlay shape internally. */
2998-
public fun setOverlayPadding(@Dp value: Float): Builder =
2999-
apply { this.overlayPadding = value.dp }
2997+
public fun setOverlayPadding(@Dp value: Float): Builder = apply {
2998+
this.overlayPadding = BalloonOverlayPadding(value.dp, value.dp, value.dp, value.dp)
2999+
}
3000+
3001+
/** sets directional padding on the overlay shape. */
3002+
public fun setOverlayPadding(
3003+
@Dp left: Float = 0f,
3004+
@Dp top: Float = 0f,
3005+
@Dp right: Float = 0f,
3006+
@Dp bottom: Float = 0f,
3007+
): Builder = apply {
3008+
this.overlayPadding = BalloonOverlayPadding(left.dp, top.dp, right.dp, bottom.dp)
3009+
}
30003010

3001-
/** sets a padding value of the overlay shape internally using dimension resource.. */
3011+
/** Sets a uniform padding for the overlay shape using a dimension resource. */
30023012
public fun setOverlayPaddingResource(@DimenRes value: Int): Builder = apply {
3003-
this.overlayPadding = context.dimen(value)
3013+
val padding = context.dimen(value)
3014+
this.overlayPadding = BalloonOverlayPadding(padding, padding, padding, padding)
30043015
}
30053016

30063017
/** sets color of the overlay padding. */
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (C) 2019 skydoves
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.skydoves.balloon
18+
19+
import com.skydoves.balloon.annotations.InternalBalloonApi
20+
21+
/**
22+
* Represents padding values to be applied around a [Balloon] overlay.
23+
*
24+
* @property left The padding on the left side in pixels.
25+
* @property top The padding on the top side in pixels.
26+
* @property right The padding on the right side in pixels.
27+
* @property bottom The padding on the bottom side in pixels.
28+
*/
29+
@InternalBalloonApi
30+
public data class BalloonOverlayPadding(
31+
val left: Float = 0f,
32+
val top: Float = 0f,
33+
val right: Float = 0f,
34+
val bottom: Float = 0f,
35+
)

balloon/src/main/kotlin/com/skydoves/balloon/overlay/BalloonAnchorOverlayView.kt

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ import android.graphics.Shader
3131
import android.util.AttributeSet
3232
import android.view.View
3333
import androidx.annotation.ColorInt
34-
import androidx.annotation.Px
34+
import androidx.core.graphics.createBitmap
35+
import com.skydoves.balloon.BalloonOverlayPadding
3536
import com.skydoves.balloon.extensions.dimen
3637
import com.skydoves.balloon.internals.viewProperty
3738

@@ -63,8 +64,7 @@ public class BalloonAnchorOverlayView @JvmOverloads constructor(
6364
public var overlayPaddingShader: Shader? by viewProperty(null)
6465

6566
/** padding value of the internal overlay shape. */
66-
@get:Px
67-
public var overlayPadding: Float by viewProperty(0f)
67+
public var overlayPadding: BalloonOverlayPadding by viewProperty(BalloonOverlayPadding())
6868

6969
/** specific position of the overlay shape. */
7070
public var overlayPosition: Point? by viewProperty(null)
@@ -114,7 +114,7 @@ public class BalloonAnchorOverlayView @JvmOverloads constructor(
114114
localBitmap.recycle()
115115
}
116116

117-
localBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
117+
localBitmap = createBitmap(width, height)
118118
bitmap = localBitmap
119119

120120
val canvas = Canvas(localBitmap)
@@ -133,7 +133,7 @@ public class BalloonAnchorOverlayView @JvmOverloads constructor(
133133
paddingColorPaint.apply {
134134
color = overlayPaddingColor
135135
style = Paint.Style.STROKE
136-
strokeWidth = overlayPadding
136+
strokeWidth = overlayPadding.top
137137
shader = overlayPaddingShader
138138
}
139139

@@ -154,21 +154,27 @@ public class BalloonAnchorOverlayView @JvmOverloads constructor(
154154
anchor.getGlobalVisibleRect(rect)
155155
val anchorRect = overlayPosition?.let { position ->
156156
RectF(
157-
position.x - overlayPadding,
158-
position.y - overlayPadding + getStatusBarHeight(),
159-
position.x + anchor.width + overlayPadding,
160-
position.y + anchor.height + overlayPadding + getStatusBarHeight(),
157+
position.x - overlayPadding.left,
158+
position.y - overlayPadding.top + getStatusBarHeight(),
159+
position.x + anchor.width + overlayPadding.right,
160+
position.y + anchor.height + overlayPadding.bottom + getStatusBarHeight(),
161161
)
162162
} ?: RectF(
163-
rect.left - overlayPadding,
164-
rect.top - overlayPadding,
165-
rect.right + overlayPadding,
166-
rect.bottom + overlayPadding,
163+
rect.left - overlayPadding.left,
164+
rect.top - overlayPadding.top,
165+
rect.right + overlayPadding.right,
166+
rect.bottom + overlayPadding.bottom,
167+
)
168+
169+
val halfOverlayPadding = BalloonOverlayPadding(
170+
top = overlayPadding.top / 2,
171+
bottom = overlayPadding.bottom / 2,
172+
left = overlayPadding.left / 2,
173+
right = overlayPadding.right / 2,
167174
)
168175

169-
val halfOfOverlayPadding = overlayPadding / 2
170176
val anchorPaddingRect = RectF(anchorRect).apply {
171-
inset(halfOfOverlayPadding, halfOfOverlayPadding)
177+
inset(halfOverlayPadding.left, halfOverlayPadding.top)
172178
}
173179

174180
when (val overlay = balloonOverlayShape) {
@@ -189,21 +195,22 @@ public class BalloonAnchorOverlayView @JvmOverloads constructor(
189195
canvas.drawCircle(
190196
anchorPaddingRect.centerX(),
191197
anchorPaddingRect.centerY(),
192-
radius - halfOfOverlayPadding,
198+
radius - overlayPadding.top / 2,
193199
paddingColorPaint,
194200
)
195201
}
196202
overlay.radiusRes?.let { radiusRes ->
203+
val resolvedRadius = context.dimen(radiusRes)
197204
canvas.drawCircle(
198205
anchorRect.centerX(),
199206
anchorRect.centerY(),
200-
context.dimen(radiusRes),
207+
resolvedRadius,
201208
paint,
202209
)
203210
canvas.drawCircle(
204211
anchorPaddingRect.centerX(),
205212
anchorPaddingRect.centerY(),
206-
context.dimen(radiusRes) - halfOfOverlayPadding,
213+
resolvedRadius - overlayPadding.top / 2,
207214
paddingColorPaint,
208215
)
209216
}
@@ -214,22 +221,24 @@ public class BalloonAnchorOverlayView @JvmOverloads constructor(
214221
canvas.drawRoundRect(anchorRect, radiusPair.first, radiusPair.second, paint)
215222
canvas.drawRoundRect(
216223
anchorPaddingRect,
217-
radiusPair.first - halfOfOverlayPadding,
218-
radiusPair.second - halfOfOverlayPadding,
224+
radiusPair.first - overlayPadding.left / 2,
225+
radiusPair.second - overlayPadding.top / 2,
219226
paddingColorPaint,
220227
)
221228
}
222229
overlay.radiusResPair?.let { radiusResPair ->
230+
val radiusX = context.dimen(radiusResPair.first)
231+
val radiusY = context.dimen(radiusResPair.second)
223232
canvas.drawRoundRect(
224233
anchorRect,
225-
context.dimen(radiusResPair.first),
226-
context.dimen(radiusResPair.second),
234+
radiusX,
235+
radiusY,
227236
paint,
228237
)
229238
canvas.drawRoundRect(
230239
anchorPaddingRect,
231-
context.dimen(radiusResPair.first) - halfOfOverlayPadding,
232-
context.dimen(radiusResPair.second) - halfOfOverlayPadding,
240+
radiusX - overlayPadding.left / 2,
241+
radiusY - overlayPadding.top / 2,
233242
paddingColorPaint,
234243
)
235244
}

0 commit comments

Comments
 (0)