Android 基于BottomSheetDialog 自定义底部弹出Dialog


前言

BottomSheetDialog 是 Android 6.0 推出的新控件,即

Base class for Dialogs styled as a bottom sheet

基于Dialog样式的一个底部对话框


但原生控件可扩展性往往满足不了日常开发,于是自己基于它自定义一个Dialog,使用方便,可扩展性高


一、效果

Android 基于BottomSheetDialog 自定义底部弹出Dialog_第1张图片

Android 基于BottomSheetDialog 自定义底部弹出Dialog_第2张图片


二、使用步骤


1.引入库

implementation 'androidx.recyclerview:recyclerview:1.1.0'


2.代码

 基础样式布局



    

    

    

        

        

    



列表样式布局



    

    

    

列表Item



    

    

列表样式实体类

public class DialogBtnData {

    private int id;
    private String title;

    public DialogBtnData() {
    }

    public DialogBtnData(int id, String title) {
        this.id = id;
        this.title = title;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

列表适配器

public class BtnsBottomDialogAdapter extends RecyclerView.Adapter {
    private static final String TAG = "BtnsBottomDialogAdapter";

    private Context context;
    private List btnList;
    private OnItemClickListener itemClickListener;

    public BtnsBottomDialogAdapter(Context context, List btnList) {
        this.context = context;
        this.btnList = btnList;
    }

    @NonNull
    @Override
    public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.btns_item_layout, parent, false);
        return new VH(v);
    }

    @Override
    public void onBindViewHolder(@NonNull VH holder, int position) {
        DialogBtnData curData = btnList.get(position);
        if (curData == null || TextUtils.isEmpty(curData.getTitle())) {
            return;
        }
        holder.itemView.setOnClickListener(v -> {
            //item 点击事件
            Log.d(TAG, "onClick position:" + position + ", data:" + curData);
            if (itemClickListener != null) {
                itemClickListener.onItemClick(v, position);
            }
        });
        holder.titleTv.setText(curData.getTitle());
    }

    @Override
    public int getItemCount() {
        return btnList.size();
    }

    public void setOnItemClickListener(OnItemClickListener itemClickListener) {
        this.itemClickListener = itemClickListener;
    }

    public static class VH extends RecyclerView.ViewHolder {

        private TextView titleTv;

        public VH(@NonNull View view) {
            super(view);
            titleTv = view.findViewById(R.id.tv_dialog_btn);
        }
    }

    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }
}

自定义 BottomDialog (此处有一个坑,当我在平板上运用的时候 横屏下 Dialog 会显示不全。需要手动上拉下,很是头痛 ,但问题不大,最后还是完美解决,代码中有记录)

/**
 * 自定义底部弹出dialog
 */
public class BottomDialog implements View.OnClickListener, BtnsBottomDialogAdapter.OnItemClickListener {
    private static final String TAG = "BottomDialog";

    private Context context;
    private BottomSheetDialog dialog;
    private TextView titleTv;
    private TextView contentTv;
    private TextView leftBtnTv;
    private TextView rightBtnTv;

    private OnBtnClickListener listener;
    private RecyclerView recyclerView;
    private BtnsBottomDialogAdapter adapter;
    private BtnsBottomDialogAdapter.OnItemClickListener listener1;

    /**
     * 基本样式
     *
     * @param context
     */
    public BottomDialog(Context context) {
        this.context = context;
        dialog = new BottomSheetDialog(context, R.style.BottomSheetEdit);
        View view = LayoutInflater.from(context).inflate(R.layout.bottom_dialog_layout, null);
        dialog.setContentView(view);
        // 将BottomSheetDialog背景设为透明
        FrameLayout bottom = dialog.findViewById(R.id.design_bottom_sheet);
        if (bottom != null) {
            bottom.setBackgroundResource(android.R.color.transparent);
            //解决BottomSheetDialog底部弹出框 横屏显示不全的问题
            BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottom);
            /**
             * 控制展开跟收缩
             *
             * STATE_EXPANDED 展开状态
             * STATE_COLLAPSED 收缩状态
             * STATE_DRAGGING 正在拖动状态
             * STATE_HIDDEN 隐藏状态
             */
            bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
        }

        titleTv = view.findViewById(R.id.tv_title);
        contentTv = view.findViewById(R.id.tv_content);
        leftBtnTv = view.findViewById(R.id.tv_leftBtn);
        rightBtnTv = view.findViewById(R.id.tv_rightBtn);
        leftBtnTv.setOnClickListener(this);
        rightBtnTv.setOnClickListener(this);
    }

    /**
     * 列表样式
     *
     * @param context
     * @param btnList
     */
    public BottomDialog(Context context, List btnList) {
        dialog = new BottomSheetDialog(context, R.style.BottomSheetEdit);
        View view = LayoutInflater.from(context).inflate(R.layout.btn_bottom_dialog_layout, null);
        dialog.setContentView(view);
        // 将BottomSheetDialog背景设为透明
        FrameLayout bottom = dialog.findViewById(R.id.design_bottom_sheet);
        if (bottom != null) {
            bottom.setBackgroundResource(android.R.color.transparent);
            //解决BottomSheetDialog底部弹出框 横屏显示不全的问题
            BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottom);
            /**
             * 控制展开跟收缩
             *
             * STATE_EXPANDED 展开状态
             * STATE_COLLAPSED 收缩状态
             * STATE_DRAGGING 正在拖动状态
             * STATE_HIDDEN 隐藏状态
             */
            bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
        }


        recyclerView = view.findViewById(R.id.rcv_btn_list);
        recyclerView.setLayoutManager(new LinearLayoutManager(context));
        adapter = new BtnsBottomDialogAdapter(context, btnList);
        adapter.setOnItemClickListener(this);
        recyclerView.setAdapter(adapter);
        titleTv = view.findViewById(R.id.tv_bottom_dialog_title);
    }

    public void show() {
        dialog.show();
    }

    public void dismiss() {
        dialog.dismiss();
    }

    public BottomDialog setDismissListener(DialogInterface.OnDismissListener dismissListener) {
        dialog.setOnDismissListener(dismissListener);
        return this;
    }

    public BottomDialog setTitle(String title) {
        if (!TextUtils.isEmpty(title)) {
            titleTv.setVisibility(View.VISIBLE);
            titleTv.setText(title);
        }
        return this;
    }

    public BottomDialog setContent(String content) {
        if (!TextUtils.isEmpty(content)) {
            contentTv.setVisibility(View.VISIBLE);
            contentTv.setText(content);
        }
        return this;
    }

    public BottomDialog setLeftBtn(String btn) {
        if (!TextUtils.isEmpty(btn)) {
            leftBtnTv.setVisibility(View.VISIBLE);
            leftBtnTv.setText(btn);
        }
        return this;
    }

    public BottomDialog setRightBtn(String btn) {
        if (!TextUtils.isEmpty(btn)) {
            rightBtnTv.setVisibility(View.VISIBLE);
            rightBtnTv.setText(btn);
        }
        return this;
    }

    public BottomDialog setOnBtnClickListener(OnBtnClickListener listener) {
        this.listener = listener;
        return this;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_leftBtn:
                dismiss();
                if (listener != null) {
                    listener.onLeftBtnClick(v);
                }
                break;
            case R.id.tv_rightBtn:
                dismiss();
                if (listener != null) {
                    listener.onRightBtnClick(v);
                }
                break;
            default:
                break;
        }
    }

    public void setOnItemClickListener(BtnsBottomDialogAdapter.OnItemClickListener itemClickListener) {
        this.listener1 = itemClickListener;
    }

    @Override
    public void onItemClick(View view, int position) {
        dismiss();
        if (listener != null) {
            listener1.onItemClick(view, position);
        }
    }

    public interface OnBtnClickListener {
        void onLeftBtnClick(View view);

        void onRightBtnClick(View view);
    }

}

 最后终于要应用了

  //普通底部弹出窗
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String text = false ? "您当前可升级更新到V" + 1.1 : "您当前已是最新版本";
                BottomDialog dialog = new BottomDialog(MainActivity.this);
                dialog.setTitle("检查更新").setContent(text).setLeftBtn("取消");
                if (false) {
                    dialog.setRightBtn("点此下载最新版");
                }
                //自定义Dialog按钮监听
                dialog.setOnBtnClickListener(new BottomDialog.OnBtnClickListener() {
                    @Override
                    public void onLeftBtnClick(View view) {
                    }

                    @Override
                    public void onRightBtnClick(View view) {
                    }
                }).show();

            }
        });
        //列表底部弹出窗
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                List btnList = new ArrayList<>();
                btnList.add(new DialogBtnData(1, "保存"));
                btnList.add(new DialogBtnData(2, "取消"));
                BottomDialog dialog = new BottomDialog(MainActivity.this, btnList);

                dialog.setOnItemClickListener(new BtnsBottomDialogAdapter.OnItemClickListener() {
                    @Override
                    public void onItemClick(View view, int pos) {
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                            }
                        }).start();
                    }
                });
                dialog.show();
            }
        });


总结

切记 遇到问题不要慌不要慌,实在没思路就去看源码,尤其自定义的控件,问题千奇百怪,要细心排查。就像这个横屏dialog显示不全的问题,源码上是这样的

@Override

protected void onStart() {

super.onStart();

   if (behavior != null && behavior.getState() == BottomSheetBehavior.STATE_HIDDEN) {

    behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
  }

}

 细心,耐心  问题终会迎刃而解,需要源码留言哦,以上其实已经很全面拉,哈哈 ,加油老铁,

你可能感兴趣的:(自定义,View,android,java,apache)