You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决RecyclerView双击触发Bottom Sheet Dialog Fragment重复显示问题

Fixing Double Bottom Sheet Popup & Unresponsive Click Issues in RecyclerView Adapter

Hey there! Let's tackle your problem step by step. The double Bottom Sheet popup happens because fast clicks trigger the onClick listener multiple times before the first Bottom Sheet finishes showing. Your initial boolean flag approach caused unresponsive clicks because it didn't sync with the actual Bottom Sheet lifecycle—let's fix that.

Why Your Initial Flag Approach Failed

Your code toggled isBottomSheetShowing every time the item was clicked, but it never reset the flag when the Bottom Sheet was dismissed. Here's what happened:

  1. First click: Flag becomes true, Bottom Sheet opens.
  2. Bottom Sheet closes: Flag stays true (no code to reset it).
  3. Second click: Flag becomes false, no Bottom Sheet opens.
  4. Third click: Flag is false again, Bottom Sheet opens.

That's why you saw random unresponsive clicks.

Solution 1: Sync Flag with Bottom Sheet Dismissal

The most reliable fix is to update the flag only when the Bottom Sheet is actually dismissed. This keeps the flag in sync with the Bottom Sheet's real state.

Updated Adapter Code:

// Inside your RecyclerView Adapter class
private boolean isBottomSheetShowing = false;

@Override 
public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int position) {
    myViewHolder.cardView.setOnClickListener(new View.OnClickListener() {
        @Override 
        public void onClick(View v) {
            if (!isBottomSheetShowing) {
                isBottomSheetShowing = true;
                
                // Create and configure your Bottom Sheet
                BottomSheetFragment bottomSheetFragment = new BottomSheetFragment();
                Bundle bundle = new Bundle();
                bundle.putInt("id", productList.get(position).getId());
                bundle.putString("name", productList.get(position).getName());
                bundle.putDouble("price", productList.get(position).getPrice());
                bundle.putInt("stock", productList.get(position).getStock());
                bundle.putInt("quantity", productList.get(position).getQuantity());
                bundle.putString("photo", productList.get(position).getPhoto());
                bottomSheetFragment.setArguments(bundle);
                
                // Show the Bottom Sheet and add a dismiss listener
                bottomSheetFragment.show(fragmentManager, bottomSheetFragment.getTag());
                bottomSheetFragment.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @Override
                    public void onDismiss(DialogInterface dialog) {
                        // Reset flag when Bottom Sheet closes
                        isBottomSheetShowing = false;
                    }
                });
            }
        }
    });
}

Solution 2: Check for Existing Bottom Sheet Instance

Instead of using a boolean flag, you can directly check if the Bottom Sheet is already visible via the FragmentManager. This avoids state sync issues entirely.

First, add a static TAG to your BottomSheetFragment:

public class BottomSheetFragment extends BottomSheetDialogFragment {
    public static final String TAG = "ProductBottomSheet";
    // ... rest of your fragment code
}

Updated Adapter Click Listener:

@Override 
public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int position) {
    myViewHolder.cardView.setOnClickListener(new View.OnClickListener() {
        @Override 
        public void onClick(View v) {
            // Check if the Bottom Sheet is already showing
            BottomSheetFragment existingSheet = (BottomSheetFragment) fragmentManager.findFragmentByTag(BottomSheetFragment.TAG);
            if (existingSheet == null || !existingSheet.isVisible()) {
                // Create and show the Bottom Sheet as before
                BottomSheetFragment bottomSheetFragment = new BottomSheetFragment();
                Bundle bundle = new Bundle();
                // Populate bundle data...
                bottomSheetFragment.setArguments(bundle);
                bottomSheetFragment.show(fragmentManager, BottomSheetFragment.TAG);
            }
        }
    });
}

Solution 3: Add a Click Throttle (Quick Fix)

If you want a simple way to prevent rapid clicks without tracking the Bottom Sheet state, add a time-based throttle. This limits clicks to once every X milliseconds (e.g., 1000ms = 1 second).

Adapter Code with Throttle:

// Inside your RecyclerView Adapter class
private long lastClickTime = 0;
private static final long CLICK_THROTTLE_MS = 1000; // 1 second

@Override 
public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int position) {
    myViewHolder.cardView.setOnClickListener(new View.OnClickListener() {
        @Override 
        public void onClick(View v) {
            long currentTime = System.currentTimeMillis();
            if (currentTime - lastClickTime > CLICK_THROTTLE_MS) {
                lastClickTime = currentTime;
                // Show your Bottom Sheet here
                BottomSheetFragment bottomSheetFragment = new BottomSheetFragment();
                // ... bundle setup and show code
            }
        }
    });
}

Solutions 1 and 2 are the most robust because they directly tie to the Bottom Sheet's actual visibility state. Solution 3 is a quick fix but won't help if the Bottom Sheet is still open after the throttle period.

Content of the question comes from stack exchange, question author Emmanuel Njorodongo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 21:47:49