防止底部表单对话框在双击时显示两次

4

你好,我正在使用底部弹出的对话框碎片(Bottom Sheet Dialog Fragment),当点击recyclerview中的项目时会显示该碎片。在适配器中实现底部弹出的代码。问题是,如果快速双击项目,则会显示两次底部弹出的对话框碎片,是否有办法限制仅允许单击一次或者检查已显示弹出窗口而不再显示?以下是显示底部弹出对话框的处理方式:


@Override
    public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int position) {


        myViewHolder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                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);
                bottomSheetFragment.show(fragmentManager, bottomSheetFragment.getTag());
            }
        });

    }

我已经尝试使用Muhannad Fakhouri的答案,按以下步骤进行:

声明一个布尔值以显示BottomSheet是否正在显示

 private boolean isBottomSheetShowing = false;


底部工作表的实现

if(!isBottomSheetShowing){

                 isBottomSheetShowing = true;

                ItemBottomSheet itemBottomSheet = new ItemBottomSheet();
                Bundle bundle = new Bundle();

                bundle.putString("code",itemPosition.getCode());
                bundle.putString("name",itemPosition.getName());
                bundle.putString("description",itemPosition.getDescription());
                bundle.putString("upcCode",itemPosition.getUpcCode());
                bundle.putString("photoBlob",itemPosition.getPhotoBlob());
                bundle.putDouble("discount",itemPosition.getDiscount());
                bundle.putDouble("price",itemPosition.getPrice());
                bundle.putInt("available",itemPosition.getAvailable());

                itemBottomSheet.setArguments(bundle);
                itemBottomSheet.show(fragmentManager, itemBottomSheet.getTag());

                }else{
                    isBottomSheetShowing = false;
                }


现在出现的问题是,有时我点击该项目时什么也不会发生,然后再次点击该项目后它才会显示。
4个回答

3
我正在尝试检查该片段是否已经添加到片段支持管理器中,如果已经添加,则不再显示。

以下是代码:(将此代码放入同步块以获得更好的功能)

        for(Fragment fragment: activity.getSupportFragmentManager().getFragments()){
            if(fragment instanceof BottomSheetFragment)
                return;
        }
       BottomSheetFragment bottomSheetFragment = BottomSheetFragment.newInstance();
       bottomSheetFragment.show(activity.getSupportFragmentManager(), "bottom_sheet_fragment");

如果出现任何异常,请评论,我会尝试修复它。

将那段代码放入同步块/方法中,它应该是正确的答案! - Paul W
1
感谢Fragment检查,我对它进行了应用,就像这样:private fun isBottomSheetShown(): Boolean { this.childFragmentManager.fragments.forEach { fragment -> if (fragment is ConsentDialogFragment) return true } return false } - writer_chris

1

有很多方法可以做到这一点,其中一种方法是将bottomSheetFragment保存在字段中,并在显示它之前检查它是否正在显示

BottomSheetFragment bottomSheetFragment = new BottomSheetFragment();

@Override
    public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int position) {


        myViewHolder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(bottomSheetFragment.isAdded()) return
                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);
                bottomSheetFragment.showNow(fragmentManager, bottomSheetFragment.getTag());
            }
        });

    }

可以使用BottomSheetBehavior吗? - Emmanuel Njorodongo
以上方法对底部工作表的功能没有任何影响。 - Muhannad Fakhouri
有没有其他实现同样功能的方法? - K Pradeep Kumar Reddy

0

您还可以使用OnSingleClickListener来防止底部菜单表单的重复显示:

OnSingleClickListener

/**
 * This class allows a single click and prevents multiple clicks on
 * the same button in rapid succession. Setting unclickable is not enough
 * because click events may still be queued up.
 *
 * Override onSingleClick() to handle single clicks.
 */
abstract class OnSingleClickListener : View.OnClickListener {

    companion object {
        private const val MIN_DELAY_MS: Long = 500L
    }

    private var mLastClickTime = 0L

    abstract fun onSingleClick(v: View)

    override fun onClick(v: View) {
        val lastClickTime: Long = mLastClickTime
        val now = System.currentTimeMillis()
        mLastClickTime = now
        if (now - lastClickTime < MIN_DELAY_MS) {
            Timber.d("OnClick clicked too quickly: ignored")
        } else {
            // Register the click
            onSingleClick(v)
        }
    }
}

这个类还有一个有用的扩展:

fun View.setOnSingleClickListener(callback: (View) -> Unit) {
    setOnClickListener(object: OnSingleClickListener() {
        override fun onSingleClick(v: View) {
            callback.invoke(v)
        }
    })
}

示例代码:

myViewHolder.cardView.setOnSingleClickListener {
    // Open bottom sheet here
}

-4
如果使用外部库是一个选项,那么你可以使用RxBinding中的RxView来控制它,例如:
RxView.clicks(myViewHolder.cardView)
    .throttle(2, TimeUnit.SECONDS)
    .subscribe {}

在这里,throttle是禁用点击的时间长度。

这是一个库还是随 Android 捆绑的? - Emmanuel Njorodongo
是的,这是一个库: https://github.com/JakeWharton/RxBinding - Muneeb Ahmed
这是无关紧要的答案,RxBinding 在这种情况下没有被使用。 - Wiguna R

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