BottomSheetDialog 是 Android 6.0 推出的新控件,即
base class for Dialogs styled as a bottom sheet
基于Dialog样式的一个底部对话框
但原生控件可扩展性往往满足不了日常开发,于是自己基于它自定义一个Dialog,使用方便,可扩展性高
一、效果 二、使用步骤 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 会显示不全。需要手动上拉下,很是头痛 ,但问题不大,最后还是完美解决,代码中有记录)
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;
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);
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);
}
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);
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);
}
}
细心,耐心 问题终会迎刃而解,需要源码留言哦,以上其实已经很全面拉,哈哈 ,加油老铁,



