底部弹出对话框在填充RecyclerView后跳出

9
我遇到了一个奇怪的问题。应用程序的流程如下:
  1. 触发底部表单对话框。
  2. 对话片段调用服务器 API。
  3. 等待响应时,显示旋转指示器。
  4. 接收响应后,填充 Recycler view 和一些 TextViews。
  5. 当 Recycler View 被更新后,对话框会从底部弹起,并与底部不再相连。但是,如果滚动 Recycler View,则会返回到正常位置。

实际情况:

Current Behaviour

预期情况:

Expected

底部表单对话框相关代码:

        //We have to override this method to ensure that the Bottom Sheet opens in expanded mode.
        @NonNull
        @Override
        public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {

            BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);

            dialog.setOnShowListener(dialog1 -> {
                BottomSheetDialog d = (BottomSheetDialog) dialog1;

                FrameLayout bottomSheet = d.findViewById(com.google.android.material.R.id.design_bottom_sheet);
                BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
            });

            return dialog;
        }

@Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        views.layoutCartItem.setLayoutManager(new LinearLayoutManager(getContext()));
        views.layoutCartItem.setItemAnimator(new DefaultItemAnimator());
    viewModel.getOrderConfirmation().observe(this, res -> {
                if(res.isSuccess()){
                    views.loader.setVisibility(View.GONE);
                    views.layoutImage.setVisibility(View.VISIBLE);
                    showViews(res.value);
                } else if(res.isError()) {
                    views.loader.setVisibility(View.GONE);
                } else {
                    views.loader.setVisibility(View.VISIBLE);
                    views.layoutImage.setVisibility(View.GONE);
                }
            });
    }

    private void showViews(CartOrderSummary summary){
            this.orderSummary = summary;
            showItems(summary.items, summary.currency);
            views.txtName.setText(summary.name);
            views.txtCuisine.setText(summary.cuisineType);
            setTypeIcon(summary.type);
            views.txtAddress.setText(summary.address);

            views.txtItemCount.setText(summary.itemCount + " ITEMS");
            views.txtTax.setText(String.format("%.2f",  summary.tax));
            views.txtTip.setText(String.format("%.2f",  0f));
            views.txtDiscount.setText(String.format("%.2f",  (summary.total - summary.subTotal)));
            views.txtCartTotal.setText(String.format("%.2f",  summary.total));

            views.btShowOnMap.setOnClickListener(v->showMap(summary));


        }

布局

<layout 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">
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="525dp"
        android:minHeight="525dp"
        android:theme="@style/AppTheme">


        <TextView
            android:id="@+id/txtTitle"
            android:layout_width="0dp"
            android:layout_height="22dp"
            android:layout_marginStart="12dp"
            android:layout_marginTop="12dp"
            android:layout_marginEnd="12dp"
            android:fontFamily="@font/avenir_next_lt_pro_regular"
            android:text="Order Confirmation"
            android:textColor="#000000"
            android:textSize="18sp"
            app:layout_constraintEnd_toStartOf="@+id/button_close_drawer"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />


        <TextView
            android:id="@+id/txtCaption"
            android:layout_width="0dp"
            android:layout_height="14dp"
            android:layout_marginStart="12dp"
            android:layout_marginTop="4dp"
            android:layout_marginEnd="12dp"
            android:fontFamily="@font/avenir_next_lt_pro_regular"
            android:text="Dear customer, please confirm the order."
            android:textColor="@color/grey_40"
            android:textSize="12sp"
            app:layout_constraintEnd_toStartOf="@+id/button_close_drawer"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/txtTitle" />

        <ImageButton
            android:id="@+id/button_close_drawer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:background="?attr/selectableItemBackgroundBorderless"
            android:contentDescription="@string/add_address"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@drawable/ic_close_black_24dp" />



        <View
            android:id="@+id/title_divider"
            android:layout_width="0dp"
            android:layout_height="1dp"
            android:layout_marginTop="14dp"
            android:background="#FFDADADA"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/txtCaption" />

        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@id/title_divider"
            app:layout_constraintBottom_toTopOf="@id/btPay"
            >


            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/layoutImage"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:elevation="9dp"
                android:paddingTop="5dp"
                >
                <androidx.constraintlayout.widget.Guideline
                    android:id="@+id/start"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    app:layout_constraintGuide_begin="12dp" />

                <androidx.constraintlayout.widget.Guideline
                    android:id="@+id/end"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    app:layout_constraintGuide_end="12dp" />



                <TextView
                    android:id="@+id/txtName"
                    android:layout_width="0dp"
                    android:layout_height="24dp"
                    android:layout_marginTop="6dp"
                    android:layout_marginEnd="12dp"
                    android:textColor="@color/black"
                    android:textSize="20sp"
                    android:transitionName="NAME"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="@id/start"
                    app:layout_constraintTop_toTopOf="parent"
                    tools:text="Las Iguanas" />
                <ImageView
                    android:id="@+id/imgType"
                    android:layout_width="16dp"
                    android:layout_height="16dp"
                    android:layout_marginEnd="2dp"
                    app:layout_constraintEnd_toStartOf="@+id/txtType"
                    app:layout_constraintTop_toTopOf="@+id/txtType"
                    app:srcCompat="@drawable/ic_type_cafe" />

                <TextView
                    android:id="@+id/txtType"
                    android:layout_width="wrap_content"
                    android:layout_height="16dp"
                    android:layout_marginEnd="12dp"
                    android:layout_marginTop="14dp"
                    android:fontFamily="@font/avenir_next_lt_pro_bold"
                    android:gravity="bottom"
                    android:lineHeight='18dp'
                    android:textSize="12sp"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    tools:text="Cafe" />
                <TextView
                    android:id="@+id/txtCuisine"
                    android:layout_width="0dp"
                    android:layout_height="20dp"
                    android:layout_marginTop="2dp"
                    android:layout_marginEnd="12dp"
                    android:textColor="@color/black"
                    android:textSize="14sp"
                    android:transitionName="CUISINE"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="@id/start"
                    app:layout_constraintTop_toBottomOf="@id/txtName"
                    tools:text="Tex-Mex, Spicy Veggie" />


                <View
                    android:id="@+id/dividerTitle"
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:layout_marginTop="17dp"
                    android:background="@color/grey"
                    app:layout_constraintTop_toBottomOf="@id/txtCuisine" />


                <ImageView
                    android:id="@+id/imgLocationPin"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:layout_marginTop="9dp"
                    android:src="@drawable/ic_location_pin"
                    app:layout_constraintStart_toStartOf="@id/start"
                    app:layout_constraintTop_toBottomOf="@id/dividerTitle" />

                <TextView
                    android:id="@+id/txtAddress"
                    android:layout_width="0dp"
                    android:layout_height="36dp"
                    android:layout_marginStart="4dp"
                    android:layout_marginTop="10dp"
                    android:layout_marginEnd="4dp"
                    android:maxLines="2"
                    android:minLines="2"
                    android:textColor="@color/black"
                    android:textSize="12sp"
                    app:layout_constraintEnd_toStartOf="@id/btShowOnMap"
                    app:layout_constraintStart_toEndOf="@id/imgLocationPin"
                    app:layout_constraintTop_toBottomOf="@id/dividerTitle"
                    tools:text="3253 Delawae Avenue, San\n Francisco, CA- California, 94107" />


                <com.google.android.material.button.MaterialButton
                    android:id="@+id/btShowOnMap"
                    style="@style/Widget.MaterialComponents.Button.TextButton"
                    android:layout_width="wrap_content"
                    android:layout_height="20dp"
                    android:layout_marginTop="10dp"
                    android:includeFontPadding="false"
                    android:insetTop="0dp"
                    android:insetBottom="0dp"
                    android:text="Show on Map"
                    android:textAlignment="viewEnd"
                    android:textAllCaps="false"
                    android:textColor="@color/pinkishOrange"
                    android:textSize="12sp"
                    app:layout_constraintEnd_toEndOf="@id/end"
                    app:layout_constraintTop_toBottomOf="@id/dividerTitle" />


                <View
                    android:id="@+id/dividerAddress"
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:layout_marginTop="15dp"
                    android:background="@color/grey"
                    app:layout_constraintTop_toBottomOf="@id/txtAddress" />


                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/layoutCartItem"
                    android:layout_width="0dp"
                    android:layout_height="300dp"
                    android:orientation="vertical"
                    app:layout_constraintStart_toStartOf="@id/start"
                    app:layout_constraintEnd_toEndOf="@id/end"
                    app:layout_constraintTop_toBottomOf="@id/dividerAddress"
                    >
                </androidx.recyclerview.widget.RecyclerView>
                <View
                    android:id="@+id/dividerItemList"
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:layout_marginTop="15dp"
                    android:background="@color/grey"
                    app:layout_constraintTop_toBottomOf="@id/layoutCartItem" />

                <TextView
                    android:id="@+id/txtItemCount"
                    android:layout_width="wrap_content"
                    android:layout_height="12dp"
                    app:layout_constraintEnd_toEndOf="@id/end"
                    app:layout_constraintTop_toBottomOf="@id/dividerItemList"
                    android:layout_marginTop="20dp"
                    tools:text="10 items"
                    android:textColor="@color/black"
                    android:textSize="10sp"
                    />

                <TextView
                    android:id="@+id/txtTip"
                    android:layout_width="wrap_content"
                    android:layout_height="12dp"
                    app:layout_constraintEnd_toEndOf="@id/end"
                    app:layout_constraintTop_toBottomOf="@id/txtItemCount"
                    android:layout_marginTop="6dp"
                    tools:text="10 items"
                    android:textColor="@color/black"
                    android:textSize="12sp"
                    />

                <TextView
                    android:id="@+id/txtTipLabel"
                    android:layout_width="wrap_content"
                    android:layout_height="12dp"
                    app:layout_constraintEnd_toStartOf="@id/txtTip"
                    app:layout_constraintTop_toTopOf="@id/txtTip"
                    app:layout_constraintBottom_toBottomOf="@id/txtTip"

                    android:text="Tip: "
                    android:textColor="@color/black"
                    android:textSize="12sp"
                    />

                <TextView
                    android:id="@+id/txtTax"
                    android:layout_width="wrap_content"
                    android:layout_height="12dp"
                    app:layout_constraintEnd_toEndOf="@id/end"
                    app:layout_constraintTop_toBottomOf="@id/txtTip"
                    android:layout_marginTop="6dp"
                    tools:text="10 items"
                    android:textColor="@color/black"
                    android:textSize="12sp"
                    />

                <TextView
                    android:id="@+id/txtTaxLabel"
                    android:layout_width="wrap_content"
                    android:layout_height="12dp"
                    app:layout_constraintEnd_toStartOf="@id/txtTax"
                    app:layout_constraintTop_toTopOf="@id/txtTax"
                    app:layout_constraintBottom_toBottomOf="@id/txtTax"
                    android:text="Tax: "
                    android:textColor="@color/black"
                    android:textSize="12sp"
                    />


                <TextView
                    android:id="@+id/txtDiscount"
                    android:layout_width="wrap_content"
                    android:layout_height="12dp"
                    app:layout_constraintEnd_toEndOf="@id/end"
                    app:layout_constraintTop_toBottomOf="@id/txtTax"
                    android:layout_marginTop="6dp"
                    tools:text="10 items"
                    android:textColor="@color/black"
                    android:textSize="12sp"
                    />

                <TextView
                    android:id="@+id/txtDiscountLabel"
                    android:layout_width="wrap_content"
                    android:layout_height="12dp"
                    app:layout_constraintEnd_toStartOf="@id/txtDiscount"
                    app:layout_constraintTop_toTopOf="@id/txtDiscount"
                    app:layout_constraintBottom_toBottomOf="@id/txtDiscount"
                    android:text="Discount: "
                    android:textColor="@color/black"
                    android:textSize="12sp"
                    />

                <TextView
                    android:id="@+id/txtCartTotal"
                    android:layout_width="wrap_content"
                    android:layout_height="20dp"
                    app:layout_constraintEnd_toEndOf="@id/end"
                    app:layout_constraintTop_toBottomOf="@id/txtDiscount"
                    app:layout_constraintBottom_toBottomOf="parent"
                    android:layout_marginTop="14dp"
                    tools:text="10 items"
                    android:textColor="@color/black"
                    android:layout_marginBottom="24dp"
                    android:textSize="16sp"
                    />

                <TextView
                    android:id="@+id/txtCartTotalLabel"
                    android:layout_width="wrap_content"
                    android:layout_height="20dp"
                    app:layout_constraintEnd_toStartOf="@id/txtCartTotal"
                    app:layout_constraintTop_toTopOf="@id/txtCartTotal"
                    app:layout_constraintBottom_toBottomOf="@id/txtCartTotal"
                    android:text="Total Due: "
                    android:textColor="@color/black"
                    android:textSize="16sp"
                    />


            </androidx.constraintlayout.widget.ConstraintLayout>

        </androidx.core.widget.NestedScrollView>

        <ProgressBar
            android:visibility="gone"
            android:id="@+id/loader"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@id/title_divider"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toTopOf="@id/btPay"

            />
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="12dp"
            android:src="@drawable/shadow_top"
            app:layout_constraintBottom_toTopOf="@id/btPay"
            android:layout_marginBottom="12dp"
            android:elevation="30dp"
            />
        <View
            android:layout_width="match_parent"
            android:layout_height="64dp"
            android:background="@color/white"
            app:layout_constraintBottom_toBottomOf="parent"
            />
        <com.google.android.material.button.MaterialButton
            android:id="@+id/btPay"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_marginStart="10dp"
            android:layout_marginTop="12dp"
            android:layout_marginEnd="10dp"
            android:layout_marginBottom="12dp"
            android:backgroundTint="@color/grass"
            android:enabled="true"
            android:gravity="center"
            android:insetTop="0dp"
            android:insetBottom="0dp"
            android:paddingRight="4dp"
            android:text="Pay"
            android:textAllCaps="false"
            android:textColor="@color/white"
            android:textSize="16sp"
            android:elevation="30dp"
            app:layout_constraintBottom_toBottomOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

将您的ConstraintLayout放入FrameLayout中,并将其添加到ConstraintLayout中,使用android:layout_gravity="bottom"。尝试一下。 - Chhatrasal Singh Bundela
额外的嵌套看起来像是一个权宜之计。这违背了ConstraintLayout的初衷。你有任何想法为什么会出现上述情况吗? - Puneet
FYI,换行没有起作用。 - Puneet
你定义了BottomSheet的peek高度吗? - Wahdat Jan
@WahdatKashmiri 我尝试过使用和不使用 peek height。在将项目添加到 RecyclerView 后,添加 BottomSheetDialog 会使其向上跳动。如果 BottomSheetDialog 是从缓存数据加载的,则不会跳动。这很奇怪。 - Puneet
3个回答

2

我通过将View.GONE更改为View.INVISIBLE并删除android:animateLayoutChanges="true",使其对我起作用。 如果不行,请尝试使用BottomSheetDialogFragment


1

对我而言,这只发生在我将android:animateLayoutChanges="true"设置为我的根布局时。


另外,我想在这里补充一点,如果你正在使用自定义视图,并且它们的根布局中包含android:animateLayoutChanges="true",你也需要将其移除。 - Astrit Veliu

0

经过一番搜索,我发现thisthis的答案可能与您的问题有关。

根据Jimmy Macaraeg的回答,尝试将View.Gone更改为View.INVISIBLE。由于View.GONE没有大小,底部表无法计算正在更新的子项的高度。

我能想到的另一个可能的解决方案是:

  1. 当数据不存在时关闭bottomsheet,否则展开它
  2. 使用Viewswitcher从一个布局切换到另一个布局,而不是使用if else视图可见性

View.Gone不应该影响BottomSheet的父元素,因为它具有固定高度,即525DP。但我将其更改为View.Gone,行为仍然没有改变。 在此处使用Viewswitcher不可行,因为切换可以在2个以上的视图之间进行。问题似乎源于RecyclerView在加载BottomSheetFragment后被更新。只要我填充RecyclerView,它就会跳动。如果我不更新RecyclerView,无论View.Gone/View.Visible/View.Invisible如何,它都能正常工作。 - Puneet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接