@momo-kits/calculator-keyboard 0.150.2-beta.2 → 0.150.2-beta.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/calculatorkeyboard/CustomKeyboardView.kt +99 -40
- package/android/src/main/java/com/calculatorkeyboard/KeyboardOverplayHost.kt +232 -0
- package/android/src/main/java/com/calculatorkeyboard/RCTInputCalculator.kt +112 -94
- package/ios/CalculatorKeyboardView.swift +53 -15
- package/ios/InputCalculator.m +6 -0
- package/ios/InputCalculator.swift +30 -10
- package/package.json +7 -131
- package/src/index.tsx +60 -15
- package/lib/commonjs/index.js +0 -48
- package/lib/commonjs/index.js.map +0 -1
- package/lib/module/index.js +0 -44
- package/lib/module/index.js.map +0 -1
- package/lib/typescript/commonjs/package.json +0 -1
- package/lib/typescript/commonjs/src/index.d.ts +0 -13
- package/lib/typescript/commonjs/src/index.d.ts.map +0 -1
- package/lib/typescript/module/package.json +0 -1
- package/lib/typescript/module/src/index.d.ts +0 -13
- package/lib/typescript/module/src/index.d.ts.map +0 -1
|
@@ -9,12 +9,12 @@ import android.widget.Button
|
|
|
9
9
|
import android.widget.ImageButton
|
|
10
10
|
import androidx.appcompat.app.AppCompatActivity
|
|
11
11
|
import androidx.constraintlayout.widget.ConstraintLayout
|
|
12
|
-
import androidx.core.graphics.ColorUtils
|
|
13
12
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
14
13
|
import org.mariuszgromada.math.mxparser.Expression
|
|
15
14
|
import androidx.core.graphics.toColorInt
|
|
16
|
-
import com.
|
|
17
|
-
|
|
15
|
+
import com.calculatorkeyboard.RCTInputCalculator.Companion.calculatorHeight
|
|
16
|
+
import com.facebook.react.bridge.Arguments
|
|
17
|
+
import com.facebook.react.uimanager.events.RCTEventEmitter
|
|
18
18
|
|
|
19
19
|
@SuppressLint("SetTextI18n", "ViewConstructor")
|
|
20
20
|
class CustomKeyboardView(
|
|
@@ -22,22 +22,32 @@ class CustomKeyboardView(
|
|
|
22
22
|
private val editText: CalculatorEditText
|
|
23
23
|
) : ConstraintLayout(context) {
|
|
24
24
|
private val keys = listOf(
|
|
25
|
-
listOf("
|
|
26
|
-
listOf("
|
|
27
|
-
listOf("
|
|
28
|
-
listOf("
|
|
29
|
-
listOf("000", "0")
|
|
25
|
+
listOf("1", "2", "3", "÷", "back"),
|
|
26
|
+
listOf("4", "5", "6", "×", "="),
|
|
27
|
+
listOf("7", "8", "9", "-", "Xong"),
|
|
28
|
+
listOf("000", "0", "+")
|
|
30
29
|
)
|
|
31
|
-
private val specialKeys = listOf("=", "-", "×", "÷", "
|
|
30
|
+
private val specialKeys = listOf("=", "-", "×", "÷", "back", "+")
|
|
32
31
|
private val separatorWidth = 8f
|
|
33
32
|
private var specialButtonColor: Int = "#D8D8D8".toColorInt()
|
|
34
33
|
|
|
34
|
+
private var customKeyButton: Button? = null
|
|
35
|
+
private var customKeyButtonBackground: Int = "#D8D8D8".toColorInt()
|
|
36
|
+
private var customKeyButtonTextColor: Int = Color.BLACK
|
|
37
|
+
private var customKeyButtonState: String = "default"
|
|
38
|
+
|
|
35
39
|
init {
|
|
36
40
|
val activity = context.currentActivity as? AppCompatActivity
|
|
37
41
|
if (activity != null) {
|
|
38
42
|
val displayMetrics = resources.displayMetrics
|
|
39
|
-
val widthButton = (displayMetrics.widthPixels - separatorWidth * 2 -
|
|
40
|
-
val heightButton = (
|
|
43
|
+
val widthButton = (displayMetrics.widthPixels - separatorWidth * 2 - 4 * separatorWidth) / 5f
|
|
44
|
+
val heightButton = (calculatorHeight - separatorWidth * 2 - 3 * separatorWidth) / 4
|
|
45
|
+
|
|
46
|
+
isClickable = false
|
|
47
|
+
isFocusable = false
|
|
48
|
+
isFocusableInTouchMode = false
|
|
49
|
+
clipToPadding = false
|
|
50
|
+
clipChildren = false
|
|
41
51
|
|
|
42
52
|
renderUI(widthButton, heightButton)
|
|
43
53
|
}
|
|
@@ -46,16 +56,19 @@ class CustomKeyboardView(
|
|
|
46
56
|
|
|
47
57
|
private fun renderUI(buttonWidth: Float, buttonHeight: Float) {
|
|
48
58
|
var yOffset = separatorWidth
|
|
49
|
-
for ((
|
|
59
|
+
for ((rowIndex, row) in keys.withIndex()) {
|
|
50
60
|
var xOffset = separatorWidth
|
|
51
|
-
for ((
|
|
61
|
+
for ((colIndex, key) in row.withIndex()) {
|
|
62
|
+
val isCustomKey = rowIndex == 2 && colIndex == 4
|
|
52
63
|
val width = if (key == "000") buttonWidth * 2 + separatorWidth else buttonWidth
|
|
53
|
-
val height = if (
|
|
64
|
+
val height = if (isCustomKey) buttonHeight * 2 + separatorWidth else buttonHeight
|
|
54
65
|
|
|
55
66
|
val button = if (key == "back") {
|
|
56
67
|
createImageButton(key, xOffset, yOffset, buttonWidth.toInt(), buttonHeight.toInt())
|
|
57
68
|
} else {
|
|
58
|
-
createButton(key, xOffset, yOffset, width.toInt(), height.toInt())
|
|
69
|
+
createButton(key, xOffset, yOffset, width.toInt(), height.toInt(), isCustomKey).also { b ->
|
|
70
|
+
if (isCustomKey) customKeyButton = b
|
|
71
|
+
}
|
|
59
72
|
}
|
|
60
73
|
|
|
61
74
|
addView(button)
|
|
@@ -72,8 +85,8 @@ class CustomKeyboardView(
|
|
|
72
85
|
yOffset: Float,
|
|
73
86
|
buttonWidth: Int,
|
|
74
87
|
buttonHeight: Int,
|
|
88
|
+
isCustomKey: Boolean
|
|
75
89
|
): Button {
|
|
76
|
-
val specialKeys = listOf("=", "-", "×", "÷", "AC", "back", "+")
|
|
77
90
|
return Button(context).apply {
|
|
78
91
|
val shapeInit = GradientDrawable().apply {
|
|
79
92
|
shape = GradientDrawable.RECTANGLE
|
|
@@ -85,9 +98,11 @@ class CustomKeyboardView(
|
|
|
85
98
|
background = shapeInit
|
|
86
99
|
text = key
|
|
87
100
|
setTypeface(typeface)
|
|
88
|
-
textSize = 24.toFloat()
|
|
101
|
+
textSize = (if (isCustomKey) 18 else 24).toFloat()
|
|
89
102
|
setTextColor(Color.BLACK)
|
|
90
103
|
stateListAnimator = null
|
|
104
|
+
maxLines = 1
|
|
105
|
+
isAllCaps = false
|
|
91
106
|
layoutParams = LayoutParams(
|
|
92
107
|
buttonWidth,
|
|
93
108
|
buttonHeight
|
|
@@ -104,10 +119,13 @@ class CustomKeyboardView(
|
|
|
104
119
|
setTextColor(Color.BLACK)
|
|
105
120
|
}
|
|
106
121
|
|
|
122
|
+
isClickable = true
|
|
123
|
+
isFocusable = false
|
|
124
|
+
isFocusableInTouchMode = false
|
|
107
125
|
|
|
108
126
|
translationX = xOffset.toInt().toFloat()
|
|
109
127
|
translationY = yOffset.toInt().toFloat()
|
|
110
|
-
setOnClickListener { onKeyPress(key) }
|
|
128
|
+
setOnClickListener { onKeyPress(key, isCustomKey) }
|
|
111
129
|
}
|
|
112
130
|
}
|
|
113
131
|
|
|
@@ -132,11 +150,16 @@ class CustomKeyboardView(
|
|
|
132
150
|
).apply {
|
|
133
151
|
constrainedWidth = false
|
|
134
152
|
}
|
|
153
|
+
|
|
154
|
+
isClickable = true
|
|
155
|
+
isFocusable = false
|
|
156
|
+
isFocusableInTouchMode = false
|
|
157
|
+
|
|
135
158
|
translationX = xOffset
|
|
136
159
|
translationY = yOffset
|
|
137
160
|
setImageResource(android.R.drawable.ic_input_delete)
|
|
138
161
|
setImageTintList(ColorStateList.valueOf(Color.BLACK))
|
|
139
|
-
setOnClickListener { onKeyPress(key) }
|
|
162
|
+
setOnClickListener { onKeyPress(key, false) }
|
|
140
163
|
}
|
|
141
164
|
}
|
|
142
165
|
|
|
@@ -172,25 +195,18 @@ class CustomKeyboardView(
|
|
|
172
195
|
}
|
|
173
196
|
}
|
|
174
197
|
|
|
175
|
-
private fun onKeyPress(key: String) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
"back" -> {
|
|
182
|
-
onBackSpace()
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
"=" -> {
|
|
186
|
-
calculateResult()
|
|
187
|
-
}
|
|
198
|
+
private fun onKeyPress(key: String, isCustomKey: Boolean) {
|
|
199
|
+
if (isCustomKey) {
|
|
200
|
+
emitCustomKey()
|
|
201
|
+
return
|
|
202
|
+
}
|
|
188
203
|
|
|
204
|
+
emitKeyPress(key)
|
|
205
|
+
when (key) {
|
|
206
|
+
"back" -> onBackSpace()
|
|
207
|
+
"=" -> calculateResult()
|
|
189
208
|
"×", "+", "-", "÷" -> keyDidPress(" $key ")
|
|
190
|
-
|
|
191
|
-
else -> {
|
|
192
|
-
editText.text?.insert(editText.selectionStart, key)
|
|
193
|
-
}
|
|
209
|
+
else -> editText.text?.insert(editText.selectionStart, key)
|
|
194
210
|
}
|
|
195
211
|
}
|
|
196
212
|
|
|
@@ -199,10 +215,6 @@ class CustomKeyboardView(
|
|
|
199
215
|
editText.text?.replace(editText.selectionStart, editText.selectionEnd, key)
|
|
200
216
|
}
|
|
201
217
|
|
|
202
|
-
private fun clearText() {
|
|
203
|
-
editText.text?.clear()
|
|
204
|
-
}
|
|
205
|
-
|
|
206
218
|
private fun onBackSpace() {
|
|
207
219
|
val start = editText.selectionStart
|
|
208
220
|
val end = editText.selectionEnd
|
|
@@ -239,4 +251,51 @@ class CustomKeyboardView(
|
|
|
239
251
|
}
|
|
240
252
|
}
|
|
241
253
|
|
|
254
|
+
private fun emitKeyPress(key: String) {
|
|
255
|
+
val reactContext = context as ThemedReactContext
|
|
256
|
+
val params = Arguments.createMap().apply {
|
|
257
|
+
putString("key", key)
|
|
258
|
+
}
|
|
259
|
+
reactContext.getJSModule(RCTEventEmitter::class.java)
|
|
260
|
+
.receiveEvent(editText.id, "onKeyPress", params)
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
private fun emitCustomKey() {
|
|
264
|
+
val reactContext = context as ThemedReactContext
|
|
265
|
+
reactContext.getJSModule(RCTEventEmitter::class.java)
|
|
266
|
+
.receiveEvent(editText.id, "onCustomKeyEvent", null)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
fun setCustomKeyText(text: String) {
|
|
270
|
+
customKeyButton?.text = text
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
fun setCustomKeyBackground(background: Int) {
|
|
274
|
+
customKeyButtonBackground = background
|
|
275
|
+
updateCustomKeyUI(background, customKeyButtonTextColor, customKeyButtonState)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
fun setCustomKeyTextColor(textColor: Int) {
|
|
279
|
+
customKeyButtonTextColor = textColor
|
|
280
|
+
updateCustomKeyUI(customKeyButtonBackground, textColor, customKeyButtonState)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
fun setCustomKeyState(state: String) {
|
|
285
|
+
customKeyButtonState = state
|
|
286
|
+
customKeyButton?.isEnabled = state != "disable"
|
|
287
|
+
updateCustomKeyUI(customKeyButtonBackground, customKeyButtonTextColor, state)
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
private fun updateCustomKeyUI(background: Int, textColor: Int, state: String){
|
|
291
|
+
|
|
292
|
+
customKeyButton?.background = GradientDrawable().apply {
|
|
293
|
+
shape = GradientDrawable.RECTANGLE
|
|
294
|
+
cornerRadius = 24f
|
|
295
|
+
setColor(background)
|
|
296
|
+
}
|
|
297
|
+
customKeyButton?.setTextColor(textColor)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
|
|
242
301
|
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
package com.calculatorkeyboard
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.app.Activity
|
|
5
|
+
import android.content.Context
|
|
6
|
+
import android.content.ContextWrapper
|
|
7
|
+
import android.util.Log
|
|
8
|
+
import android.view.Gravity
|
|
9
|
+
import android.view.MotionEvent
|
|
10
|
+
import android.view.View
|
|
11
|
+
import android.view.ViewGroup
|
|
12
|
+
import android.widget.FrameLayout
|
|
13
|
+
import androidx.core.view.ViewCompat
|
|
14
|
+
import androidx.core.view.WindowInsetsCompat
|
|
15
|
+
import androidx.core.view.doOnLayout
|
|
16
|
+
import androidx.core.view.updatePadding
|
|
17
|
+
import java.lang.ref.WeakReference
|
|
18
|
+
import androidx.core.view.isNotEmpty
|
|
19
|
+
|
|
20
|
+
internal class KeyboardOverlayHost {
|
|
21
|
+
|
|
22
|
+
private val tag = "KeyboardOverlayHost"
|
|
23
|
+
|
|
24
|
+
private var localRootRef: WeakReference<ViewGroup>? = null
|
|
25
|
+
private var containerRef: WeakReference<FrameLayout>? = null
|
|
26
|
+
private var paddingTargetRef: WeakReference<View>? = null
|
|
27
|
+
|
|
28
|
+
private var originalBottomPadding: Int = 0
|
|
29
|
+
private var isShowing = false
|
|
30
|
+
|
|
31
|
+
private class OverlayContainer(ctx: Context) : FrameLayout(ctx) {
|
|
32
|
+
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean = false
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
fun show(anchorView: View, keyboardView: View, heightPx: Int) {
|
|
36
|
+
val localRoot = findLocalRoot(anchorView) ?: run {
|
|
37
|
+
Log.w(tag, "show: cannot find local root from anchorView")
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
val container = ensureContainer(localRoot, anchorView.context) ?: return
|
|
41
|
+
|
|
42
|
+
val paddingTarget = findPaddingTargetWithin(anchorView, localRoot)
|
|
43
|
+
paddingTargetRef = WeakReference(paddingTarget)
|
|
44
|
+
localRootRef = WeakReference(localRoot)
|
|
45
|
+
|
|
46
|
+
val bottomInset = (ViewCompat.getRootWindowInsets(container)
|
|
47
|
+
?.getInsets(WindowInsetsCompat.Type.systemBars())?.bottom) ?: 0
|
|
48
|
+
|
|
49
|
+
val lp = FrameLayout.LayoutParams(
|
|
50
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
51
|
+
heightPx + bottomInset
|
|
52
|
+
).apply { gravity = Gravity.BOTTOM }
|
|
53
|
+
|
|
54
|
+
if (keyboardView.parent !== container) {
|
|
55
|
+
container.removeAllViews()
|
|
56
|
+
container.addView(keyboardView, lp)
|
|
57
|
+
} else {
|
|
58
|
+
keyboardView.layoutParams = lp
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
keyboardView.isClickable = true
|
|
62
|
+
keyboardView.isFocusable = false
|
|
63
|
+
keyboardView.isFocusableInTouchMode = false
|
|
64
|
+
keyboardView.visibility = View.VISIBLE
|
|
65
|
+
|
|
66
|
+
if (!isShowing) originalBottomPadding = paddingTarget.paddingBottom
|
|
67
|
+
paddingTarget.updatePadding(bottom = heightPx)
|
|
68
|
+
|
|
69
|
+
container.visibility = View.VISIBLE
|
|
70
|
+
container.bringToFront()
|
|
71
|
+
container.translationZ = 10000f
|
|
72
|
+
container.elevation = 10000f
|
|
73
|
+
localRoot.post { container.bringToFront() }
|
|
74
|
+
|
|
75
|
+
keyboardView.animate().cancel()
|
|
76
|
+
keyboardView.post {
|
|
77
|
+
container.bringToFront()
|
|
78
|
+
keyboardView.doOnLayout { child ->
|
|
79
|
+
val h = child.height.takeIf { it > 0 } ?: heightPx
|
|
80
|
+
child.translationY = h.toFloat()
|
|
81
|
+
child.animate()
|
|
82
|
+
.translationY(0f)
|
|
83
|
+
.setDuration(250L)
|
|
84
|
+
.withStartAction {
|
|
85
|
+
isShowing = true
|
|
86
|
+
child.setLayerType(View.LAYER_TYPE_HARDWARE, null)
|
|
87
|
+
container.bringToFront()
|
|
88
|
+
}
|
|
89
|
+
.withEndAction {
|
|
90
|
+
child.setLayerType(View.LAYER_TYPE_NONE, null)
|
|
91
|
+
}
|
|
92
|
+
.start()
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
fun hide() {
|
|
98
|
+
val container = containerRef?.get() ?: return
|
|
99
|
+
val localRoot = localRootRef?.get() ?: return
|
|
100
|
+
val paddingTarget = paddingTargetRef?.get() ?: localRoot
|
|
101
|
+
|
|
102
|
+
val child = if (container.isNotEmpty())
|
|
103
|
+
container.getChildAt(container.childCount - 1) else null
|
|
104
|
+
|
|
105
|
+
if (child == null) {
|
|
106
|
+
paddingTarget.updatePadding(bottom = originalBottomPadding)
|
|
107
|
+
isShowing = false
|
|
108
|
+
return
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
child.animate().cancel()
|
|
112
|
+
val h = child.height.takeIf { it > 0 } ?: (child.measuredHeight.takeIf { it > 0 } ?: 0)
|
|
113
|
+
if (h == 0) {
|
|
114
|
+
container.removeAllViews()
|
|
115
|
+
paddingTarget.updatePadding(bottom = originalBottomPadding)
|
|
116
|
+
isShowing = false
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
child.animate()
|
|
121
|
+
.translationY(h.toFloat())
|
|
122
|
+
.setDuration(250L)
|
|
123
|
+
.withEndAction {
|
|
124
|
+
container.removeAllViews()
|
|
125
|
+
paddingTarget.updatePadding(bottom = originalBottomPadding)
|
|
126
|
+
isShowing = false
|
|
127
|
+
}
|
|
128
|
+
.start()
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
fun detach() {
|
|
132
|
+
containerRef?.get()?.let { (it.parent as? ViewGroup)?.removeView(it) }
|
|
133
|
+
containerRef = null
|
|
134
|
+
localRootRef = null
|
|
135
|
+
paddingTargetRef = null
|
|
136
|
+
isShowing = false
|
|
137
|
+
originalBottomPadding = 0
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private fun findLocalRoot(anchor: View): ViewGroup? {
|
|
141
|
+
var cur: View? = anchor
|
|
142
|
+
|
|
143
|
+
while (cur != null) {
|
|
144
|
+
if (cur is ViewGroup && isReactRoot(cur)) {
|
|
145
|
+
return cur
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
val parent = cur.parent
|
|
149
|
+
if (parent is ViewGroup) {
|
|
150
|
+
val parentName = parent::class.java.simpleName
|
|
151
|
+
if (parentName.contains("FragmentContainerView")) {
|
|
152
|
+
return (cur as? ViewGroup) ?: parent
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
cur = (cur.parent as? View)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return (anchor.rootView as? ViewGroup)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private fun isReactRoot(v: View): Boolean {
|
|
163
|
+
val n = v::class.java.simpleName
|
|
164
|
+
return n.contains("ReactRootView") ||
|
|
165
|
+
n.contains("RNGestureHandlerEnabledRootView") ||
|
|
166
|
+
(n.contains("React") && n.contains("Root"))
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
@SuppressLint("ClickableViewAccessibility")
|
|
170
|
+
private fun ensureContainer(localRoot: ViewGroup, ctx: Context): FrameLayout? {
|
|
171
|
+
var container = containerRef?.get()
|
|
172
|
+
|
|
173
|
+
if (container == null || container.parent !== localRoot) {
|
|
174
|
+
container?.let { (it.parent as? ViewGroup)?.removeView(it) }
|
|
175
|
+
|
|
176
|
+
container = OverlayContainer(ctx).apply {
|
|
177
|
+
layoutParams = ViewGroup.LayoutParams(
|
|
178
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
179
|
+
ViewGroup.LayoutParams.MATCH_PARENT
|
|
180
|
+
)
|
|
181
|
+
isClickable = false
|
|
182
|
+
isFocusable = false
|
|
183
|
+
elevation = 10000f
|
|
184
|
+
translationZ = 10000f
|
|
185
|
+
visibility = View.VISIBLE
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
localRoot.addView(container)
|
|
189
|
+
container.bringToFront()
|
|
190
|
+
localRoot.requestLayout()
|
|
191
|
+
containerRef = WeakReference(container)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return container
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private fun findPaddingTargetWithin(anchor: View, localRoot: ViewGroup): View {
|
|
198
|
+
fun dfs(g: ViewGroup): View? {
|
|
199
|
+
if (isReactRoot(g)) return g
|
|
200
|
+
for (i in 0 until g.childCount) {
|
|
201
|
+
val c = g.getChildAt(i)
|
|
202
|
+
if (c is ViewGroup) {
|
|
203
|
+
val hit = dfs(c)
|
|
204
|
+
if (hit != null) return hit
|
|
205
|
+
} else if (isReactRoot(c)) {
|
|
206
|
+
return c
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return null
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
dfs(localRoot)?.let { return it }
|
|
213
|
+
|
|
214
|
+
var cur: View? = anchor
|
|
215
|
+
var last: View = anchor
|
|
216
|
+
while (cur != null && cur !== localRoot) {
|
|
217
|
+
last = cur
|
|
218
|
+
cur = (cur.parent as? View)
|
|
219
|
+
}
|
|
220
|
+
return last as? ViewGroup ?: localRoot
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
@Suppress("unused")
|
|
224
|
+
private fun findActivityFrom(view: View): Activity? {
|
|
225
|
+
var ctx: Context? = view.context
|
|
226
|
+
while (ctx is ContextWrapper) {
|
|
227
|
+
if (ctx is Activity) return ctx
|
|
228
|
+
ctx = ctx.baseContext
|
|
229
|
+
}
|
|
230
|
+
return null
|
|
231
|
+
}
|
|
232
|
+
}
|