在嵌套片段中打开键盘时 BottomSheet 中出现超级奇怪的故障

Super Weird Glitch in BottomSheet when open Keyboard in nested Fragment

我的应用程序出现了这个超级奇怪的故障。

当我打开键盘然后膨胀另一个片段时,bottomsheet 片段将滚动直到到达 recyclerview 的顶部隐藏 bottomsheet 视图的顶部。

我有一个带有两个 FragmentContainerView 的 MainFragment。第一个是我在两个片段(NestedFragment_0NestedFragment_1)之间切换的容器,第二个我用它来填充具有 BottomSheet 的片段。两个片段之间的按钮切换。

只有当 EditText 位于其中一个嵌套片段内并且 BottomSheet 内有 RecyclerView 时才会发生。

项目我已经上传了here如果有人要下载

主要片段布局:

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.main.MainFragment">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/content_container"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_marginTop="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/button" />

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:text="Switch Nested Fragment"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/bottom_sheet_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

MainFragment 代码:

class MainFragment : Fragment() {

    companion object {
        fun newInstance() = MainFragment()
    }

    private lateinit var binding: MainFragmentBinding

    private var activeSubFragment: Fragment = Nested0Fragment()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = MainFragmentBinding.inflate(inflater, container, false)

        binding.button.setOnClickListener {
            activeSubFragment = if (activeSubFragment is Nested0Fragment) {
                Nested1Fragment()
            } else {
                Nested0Fragment()
            }
            childFragmentManager.beginTransaction()
                .replace(R.id.content_container, activeSubFragment).commit()
        }

        childFragmentManager.beginTransaction().replace(R.id.content_container, activeSubFragment)
            .commit()

        childFragmentManager.beginTransaction()
            .replace(R.id.bottom_sheet_container, BottomSheetFragment.newInstance()).commit()

        return binding.root
    }
}

BottomSheet 布局:

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.core.widget.NestedScrollView
        android:id="@+id/nestedScroll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:behavior_peekHeight="100dp"
        android:background="@color/teal_200"
        app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
        android:fillViewport="true">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/frameLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".ui.main.BottomSheetFragment">

            <TextView
                android:id="@+id/textView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="32dp"
                android:text="BottomSheet"
                android:textSize="16sp"
                android:textStyle="bold"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.5"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/recyclerView"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="32dp"
                app:layoutManager="LinearLayoutManager"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/textView" />

        </androidx.constraintlayout.widget.ConstraintLayout>
    </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

问题与焦点有关,当EditText失去焦点时,系统会将焦点移至RecyclerView,这就是它移动到顶部的原因。在 Fragment 版本 1.4.0 中,它解决了 API 28 及更高版本的问题,对于 API 27 及以下版本,只需在最顶部添加 focusable=truefocusableInTouchMode=true父视图。