/
ExampleCardPopup.kt
83 lines (73 loc) · 3.28 KB
/
ExampleCardPopup.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package com.labo.kaji.relativepopupwindow.example
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.graphics.Rect
import android.graphics.drawable.ColorDrawable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.material.circularreveal.CircularRevealCompat
import com.google.android.material.circularreveal.cardview.CircularRevealCardView
import com.labo.kaji.relativepopupwindow.RelativePopupWindow
import kotlin.math.hypot
import kotlin.math.max
class ExampleCardPopup(context: Context) : RelativePopupWindow(context) {
init {
@SuppressLint("InflateParams")
contentView = LayoutInflater.from(context).inflate(R.layout.popup_card, null)
width = ViewGroup.LayoutParams.WRAP_CONTENT
height = ViewGroup.LayoutParams.WRAP_CONTENT
isFocusable = true
isOutsideTouchable = true
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
// Disable default animation for circular reveal
animationStyle = 0
}
override fun showOnAnchor(anchor: View, vertPos: Int, horizPos: Int, x: Int, y: Int, fitInScreen: Boolean) {
super.showOnAnchor(anchor, vertPos, horizPos, x, y, fitInScreen)
circularReveal(anchor)
}
private fun circularReveal(anchor: View) {
(contentView as CircularRevealCardView).run {
post {
val myLocation = IntArray(2).apply { getLocationOnScreen(this) }
val anchorLocation = IntArray(2).apply { anchor.getLocationOnScreen(this) }
val cx = anchorLocation[0] - myLocation[0] + anchor.width/2
val cy = anchorLocation[1] - myLocation[1] + anchor.height/2
val windowRect = Rect().apply { getWindowVisibleDisplayFrame(this) }
measure(
makeDropDownMeasureSpec(this@ExampleCardPopup.width, windowRect.width()),
makeDropDownMeasureSpec(this@ExampleCardPopup.height, windowRect.height())
)
val dx = max(cx, measuredWidth - cx)
val dy = max(cy, measuredHeight - cy)
val finalRadius = hypot(dx.toFloat(), dy.toFloat())
CircularRevealCompat.createCircularReveal(this, cx.toFloat(), cy.toFloat(), 0f, finalRadius).run {
duration = 500
start()
}
}
}
}
companion object {
private fun makeDropDownMeasureSpec(measureSpec: Int, maxSize: Int): Int {
return View.MeasureSpec.makeMeasureSpec(
getDropDownMeasureSpecSize(measureSpec, maxSize),
getDropDownMeasureSpecMode(measureSpec)
)
}
private fun getDropDownMeasureSpecSize(measureSpec: Int, maxSize: Int): Int {
return when (measureSpec) {
ViewGroup.LayoutParams.MATCH_PARENT -> maxSize
else -> View.MeasureSpec.getSize(measureSpec)
}
}
private fun getDropDownMeasureSpecMode(measureSpec: Int): Int {
return when (measureSpec) {
ViewGroup.LayoutParams.WRAP_CONTENT -> View.MeasureSpec.UNSPECIFIED
else -> View.MeasureSpec.EXACTLY
}
}
}
}