BottomSheetDialog 是 Android 6.0 推出的新控件,即
Base class for Dialogs styled as a bottom sheet
基于Dialog样式的一个底部对话框
但原生控件可扩展性往往满足不了日常开发,于是自己基于它自定义一个Dialog,使用方便,可扩展性高
implementation 'androidx.recyclerview:recyclerview:1.1.0'
基础样式布局
列表样式布局
列表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);
}
}
细心,耐心 问题终会迎刃而解,需要源码留言哦,以上其实已经很全面拉,哈哈 ,加油老铁,