TabLayout中Fragment内Floating Action Button加载位置异常求助
你遇到的这个问题很常见,核心原因是初始布局测量时,CoordinatorLayout没有正确获取到父容器的完整可用高度,导致FAB的layout_gravity="bottom|end"定位计算错误;而键盘弹出会触发布局重绘,此时CoordinatorLayout拿到了正确的尺寸,FAB就回到了正确位置。下面给你几个可行的解决方案:
方案1:移除不必要的外层LinearLayout(最推荐)
你的根布局是LinearLayout,但里面只嵌套了一个CoordinatorLayout,这个外层LinearLayout完全是多余的,反而会干扰CoordinatorLayout的布局计算。直接让CoordinatorLayout作为根布局即可:
<?xml version="1.0" encoding="utf-8"?> <android.support.design.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:focusable="true" android:focusableInTouchMode="true"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_marginTop="10dp" android:layout_marginLeft="@dimen/common_margin" android:layout_marginRight="@dimen/common_margin"> <!-- 其他字段保留不变 --> <!-- KM FINAL --> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp"> <TextView android:text="@string/end_exam_mileage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:textSize="25sp" android:fontFamily="sans-serif-condensed" android:textColor="@color/primary" /> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/txtFinalKM" android:fontFamily="sans-serif-condensed" android:inputType="number" android:hint="@string/end_exam_insert_mileage" android:textSize="25sp" android:layout_width="match_parent" android:layout_height="wrap_content" /> </android.support.design.widget.TextInputLayout> </LinearLayout> </LinearLayout> <!-- NEXT BUTTON --> <com.github.clans.fab.FloatingActionButton android:id="@+id/fab_next_information" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_marginRight="@dimen/common_margin" android:layout_marginBottom="@dimen/common_margin" android:src="@drawable/icon_fab_mini_next" android:clickable="true" app:fab_shadowColor="#00FFFFFF" app:fab_colorNormal="#272B35" app:fab_colorPressed="@color/accent" app:fab_colorRipple="#272B35" /> </android.support.design.widget.CoordinatorLayout>
这样CoordinatorLayout能直接感知整个页面的可用空间,初始化时就能正确计算FAB的位置。
方案2:给CoordinatorLayout添加权重(如果必须保留外层LinearLayout)
如果因为某些原因不能移除外层LinearLayout,那可以通过layout_weight让CoordinatorLayout占满父容器的剩余空间,确保它能获取到正确的高度:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:focusable="true" android:focusableInTouchMode="true"> <android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <!-- 内部布局完全保留不变 --> </android.support.design.widget.CoordinatorLayout> </LinearLayout>
方案3:代码层面触发布局重绘
如果上述布局调整都无法解决问题,还可以在Fragment的代码里,延迟触发FAB的布局重计算:
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); com.github.clans.fab.FloatingActionButton fab = view.findViewById(R.id.fab_next_information); // 延迟让FAB在布局完成后重新计算位置 fab.post(() -> fab.requestLayout()); }
这个方法是利用post()让代码在UI线程的队列末尾执行,此时布局已经完成初始化,FAB能获取到正确的父容器尺寸。
内容的提问来源于stack exchange,提问作者gregoryp
相关产品推荐
相关产品推荐

