Android ViewPager中Fragment悬浮按钮被虚拟软键遮挡问题求助
兄弟我太懂这种闹心的情况了!一模一样的悬浮按钮,在主Activity里乖乖待在右下角,到ViewPager的Fragment里就被HTC One M8的虚拟软键挡住,换谁都得挠头。既然你已经定位到和CoordinatorLayout相关,那大概率是Fragment的布局没正确处理系统窗口的内边距(insets)——主Activity的CoordinatorLayout默认适配了系统导航栏空间,但Fragment里的布局没跟上节奏。
给你几个靠谱的解决办法,按需选就行:
方法一:让Fragment根布局自动适配系统窗口
确保Fragment的根布局是CoordinatorLayout,并且加上android:fitsSystemWindows="true"属性。这个属性会让布局自动预留出虚拟导航栏、状态栏的空间,悬浮按钮自然就不会被挡住了。示例布局代码:<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <!-- 你的Fragment其他布局内容 --> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="16dp" app:srcCompat="@drawable/ic_add" /> </androidx.coordinatorlayout.widget.CoordinatorLayout>方法二:手动给悬浮按钮补全底部间距
如果不想改动根布局,也可以在Fragment的代码里手动处理窗口内边距,给悬浮按钮加上虚拟导航栏高度的margin。在onViewCreated方法里加这段代码就行:@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); FloatingActionButton fab = view.findViewById(R.id.fab); fab.setOnApplyWindowInsetsListener((v, insets) -> { ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) v.getLayoutParams(); // 把虚拟导航栏的高度加到悬浮按钮的底部margin里 params.bottomMargin += insets.getSystemWindowInsetBottom(); v.setLayoutParams(params); return insets.consumeSystemWindowInsets(); }); }这种方法更灵活,能自动适配不同设备的虚拟键高度,不止HTC One M8,其他带固定虚拟键的设备也能搞定。
方法三:给父布局加适配(非CoordinatorLayout场景)
如果Fragment的根布局不是CoordinatorLayout,也可以给悬浮按钮所在的父布局设置android:fitsSystemWindows="true",同时给父布局加上android:paddingBottom="?android:attr/navigationBarSize",这样父布局会预留出虚拟键的空间,悬浮按钮自然就不会被遮挡了。
另外要注意:HTC One M8的虚拟键是固定显示的,不像有些设备可以隐藏,所以一定要确保布局的底部空间足够,要是Fragment里有滚动控件(比如RecyclerView、ScrollView),也记得给它们加上底部padding,避免列表内容也被虚拟键挡住。
内容的提问来源于stack exchange,提问作者David D

