Skip to content

Commit 2f68155

Browse files
committed
feat: 添加FragmentManager低版本的兼容处理
1 parent 041ded9 commit 2f68155

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import androidx.annotation.VisibleForTesting
3232
*/
3333
internal class EditorContainer(context: Context) : FrameLayout(context) {
3434
private val views = mutableMapOf<Editor, View?>()
35+
private val compat = FragmentManagerCompat()
3536
private var lastInsets: WindowInsets? = null
3637
private var editText: EditTextHolder? = null
3738
private var isCheckControlImeEnabled = true
@@ -223,6 +224,14 @@ internal class EditorContainer(context: Context) : FrameLayout(context) {
223224
@Suppress("UNCHECKED_CAST")
224225
private fun checkedAdapter() = adapter as EditorAdapter<Editor>
225226

227+
override fun removeViewAt(index: Int) {
228+
compat.removeViewAt { super.removeViewAt(index) }
229+
}
230+
231+
override fun addView(child: View?, index: Int) {
232+
compat.addView { super.addView(child, index) }
233+
}
234+
226235
private data class PendingChange(
227236
val previous: Editor?,
228237
var waitDispatchImeShown: Boolean = false
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2023 xiaocydx
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.xiaocydx.inputview
18+
19+
import androidx.fragment.app.FragmentManager
20+
21+
/**
22+
* [FragmentManager]低版本兼容类
23+
*
24+
* ```
25+
* public abstract class FragmentManager {
26+
*
27+
* void moveFragmentToExpectedState(@NonNull Fragment f) {
28+
* ...
29+
* final ViewGroup container = f.mContainer;
30+
* int underIndex = container.indexOfChild(underView);
31+
* int viewIndex = container.indexOfChild(f.mView);
32+
* if (viewIndex < underIndex) {
33+
* container.removeViewAt(viewIndex); // 抛出异常不崩溃
34+
* container.addView(f.mView, underIndex); // 拦截addView
35+
* }
36+
* ...
37+
* }
38+
* }
39+
* ```
40+
*
41+
* @author xcc
42+
* @date 2023/12/22
43+
*/
44+
internal class FragmentManagerCompat {
45+
var interceptAddView = false
46+
47+
inline fun removeViewAt(action: () -> Unit) {
48+
try {
49+
action()
50+
} catch (e: NullPointerException) {
51+
val moveFragmentToExpectedState = e.stackTrace.firstOrNull {
52+
it.className == "androidx.fragment.app.FragmentManager"
53+
&& it.methodName == "moveFragmentToExpectedState"
54+
}
55+
interceptAddView = moveFragmentToExpectedState != null
56+
if (!interceptAddView) throw e
57+
}
58+
}
59+
60+
inline fun addView(action: () -> Unit) {
61+
if (!interceptAddView) action()
62+
interceptAddView = false
63+
}
64+
}

0 commit comments

Comments
 (0)