Skip to content

Commit bd92164

Browse files
committed
feat: 兼容insets-systembar的层级关系,调整rootView的可视逻辑
1 parent 081965e commit bd92164

File tree

3 files changed

+34
-10
lines changed

3 files changed

+34
-10
lines changed

app/src/main/kotlin/com/xiaocydx/inputview/sample/scene/figure/content/TextTransformer.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class TextEnterReturn(
3535
private val textTarget: () -> WeakReference<View>?,
3636
private val lastInsets: () -> WindowInsetsCompat
3737
) : Transformer() {
38+
private val point = IntArray(2)
3839
private val startPaddings = Rect()
3940
private val endPaddings = Rect()
4041
private val currentPaddings = Rect()
@@ -48,14 +49,14 @@ class TextEnterReturn(
4849

4950
override fun onPrepare(state: ImperfectState) = with(state) {
5051
val isEnter = isEnter(Text)
51-
val textLocation = textTarget()?.get()?.let(ViewLocation::from) ?: ViewLocation()
52+
// contentView布局完成过,取contentView的位置进行计算
53+
contentView.getLocationInWindow(point)
5254

53-
// rootView还未测量完成,取rootParent的尺寸进行计算
54-
val rootParent = rootView.parent as ViewGroup
55+
val textLocation = textTarget()?.get()?.let(ViewLocation::from) ?: ViewLocation()
5556
val paddings = if (isEnter) startPaddings else endPaddings
5657
paddings.set(textLocation)
57-
paddings.right = rootParent.width - paddings.right
58-
paddings.bottom = rootParent.height - paddings.bottom
58+
paddings.right = rootView.width - paddings.right
59+
paddings.bottom = point[1] + rootView.height - paddings.bottom
5960

6061
// 在下一帧布局之前设置startPaddings和toolsHeight
6162
if (isEnter) binding.root.updatePaddings(startPaddings)

inputview-transform/src/main/kotlin/com/xiaocydx/inputview/transform/overlay/OverlayImpl.kt

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,18 @@ import com.xiaocydx.inputview.EditorChangedListener
4545
import com.xiaocydx.inputview.EditorMode
4646
import com.xiaocydx.inputview.FadeEditorAnimator
4747
import com.xiaocydx.inputview.InputView
48+
import com.xiaocydx.inputview.ViewTreeWindow
4849
import com.xiaocydx.inputview.current
4950
import com.xiaocydx.inputview.disableGestureNavBarOffset
50-
import com.xiaocydx.inputview.isVisible
5151
import com.xiaocydx.inputview.notifyHideCurrent
5252
import com.xiaocydx.inputview.notifyShow
53+
import com.xiaocydx.inputview.requireViewTreeWindow
5354
import com.xiaocydx.inputview.transform.Overlay.Companion.ROOT_PARENT_ID
55+
import com.xiaocydx.insets.consumeInsets
56+
import com.xiaocydx.insets.navigationBarHeight
57+
import com.xiaocydx.insets.navigationBars
58+
import com.xiaocydx.insets.setOnApplyWindowInsetsListenerCompat
59+
import com.xiaocydx.insets.updateMargins
5460

5561
/**
5662
* [Overlay]的实现类
@@ -102,6 +108,15 @@ internal class OverlayImpl<S : Scene<C, E>, C : Content, E : Editor>(
102108
transformerDispatcher.initialize(rootView, editorAnimator)
103109
}
104110

111+
// 兼容insets-systembar的层级关系,补充未消费的导航栏间距
112+
var viewTreeWindow: ViewTreeWindow? = null
113+
transformState.rootView.setOnApplyWindowInsetsListenerCompat { v, insets ->
114+
viewTreeWindow = viewTreeWindow ?: v.requireViewTreeWindow()
115+
val isSupport = viewTreeWindow!!.run { insets.supportGestureNavBarEdgeToEdge }
116+
v.updateMargins(bottom = if (isSupport) 0 else insets.navigationBarHeight)
117+
if (isSupport) insets else insets.consumeInsets(navigationBars())
118+
}
119+
105120
if (rootParent != null && rootParent.id != ROOT_PARENT_ID) {
106121
rootParent.addView(transformState.rootView)
107122
} else {
@@ -486,18 +501,26 @@ internal class OverlayImpl<S : Scene<C, E>, C : Content, E : Editor>(
486501
backgroundView = View(context)
487502
contentView = ContentContainer(context)
488503
inputView = InputView(context)
489-
rootView.isVisible = false
490504
rootView.addView(backgroundView, MATCH_PARENT, MATCH_PARENT)
491505
rootView.addView(contentView, MATCH_PARENT, MATCH_PARENT)
492506
rootView.addView(inputView, MATCH_PARENT, MATCH_PARENT)
507+
setVisible(isVisible = false)
508+
}
509+
510+
fun setVisible(isVisible: Boolean) {
511+
rootView.isEnabled = isVisible
512+
// 设置View.INVISIBLE是为了让rootView能布局,在执行变换操作之前rootView有尺寸。
513+
// 当current = null时,Content和Editor的视图都会被移除,布局流程不会有性能问题。
514+
val visibility = if (isVisible) View.VISIBLE else View.INVISIBLE
515+
if (visibility != rootView.visibility) rootView.visibility = visibility
493516
}
494517

495518
fun invalidate() {
496519
isInvalidated = true
497520
}
498521

499522
fun prepare(previous: S?, current: S?) {
500-
rootView.isVisible = true
523+
setVisible(true)
501524
if (!isInvalidated) return
502525
isInvalidated = false
503526

@@ -545,7 +568,7 @@ internal class OverlayImpl<S : Scene<C, E>, C : Content, E : Editor>(
545568
}
546569

547570
fun postEnd(animation: AnimationState) {
548-
rootView.isVisible = current != null
571+
setVisible(current != null)
549572
contentView.removeChangeRecordPrevious()
550573
previous = current
551574
setOffset(animation.endOffset)

inputview/src/main/kotlin/com/xiaocydx/inputview/ViewTreeWindow.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ internal class ViewTreeWindow(
206206
}
207207
}
208208

209-
private val WindowInsetsCompat.supportGestureNavBarEdgeToEdge: Boolean
209+
val WindowInsetsCompat.supportGestureNavBarEdgeToEdge: Boolean
210210
get() = gestureNavBarEdgeToEdge && isGestureNavigationBar(decorView)
211211

212212
val WindowInsetsCompat.navBarOffset: Int

0 commit comments

Comments
 (0)