IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 基于BottomSheetDialog 自定义底部弹出Dialog -> 正文阅读

[移动开发]Android 基于BottomSheetDialog 自定义底部弹出Dialog

前言

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

Base class for Dialogs styled as a bottom sheet

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


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

一、效果

二、使用步骤

1.引入库

implementation 'androidx.recyclerview:recyclerview:1.1.0'

2.代码

?基础样式布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/top_corners_shape"
    android:gravity="center_vertical"
    android:orientation="vertical"
    android:paddingHorizontal="30dp"
    android:paddingVertical="25dp">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="#2B2B2B"
        android:textSize="18dp"
        android:textStyle="bold"
        android:visibility="gone" />

    <TextView
        android:id="@+id/tv_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:textColor="#2B2B2B"
        android:textSize="24sp"
        android:textStyle="bold"
        android:visibility="gone" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="25dp"
        android:gravity="center"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tv_leftBtn"
            android:layout_width="0dp"
            android:layout_height="45dp"
            android:layout_weight="1"
            android:background="@drawable/dialog_left_btn_shape"
            android:gravity="center"
            android:textColor="#2B2B2B"
            android:textSize="15dp"
            android:textStyle="bold"
            android:visibility="gone" />

        <TextView
            android:id="@+id/tv_rightBtn"
            android:layout_width="0dp"
            android:layout_height="45dp"
            android:layout_marginStart="14dp"
            android:layout_weight="1"
            android:background="@drawable/dialog_right_btn_shape"
            android:gravity="center"
            android:textColor="#2984FF"
            android:textSize="15sp"
            android:textStyle="bold"
            android:visibility="gone" />

    </LinearLayout>

</LinearLayout>

列表样式布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/top_corners_shape"
    android:orientation="vertical"
    android:paddingHorizontal="15dp">

    <TextView
        android:id="@+id/tv_bottom_dialog_title"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:gravity="center"
        android:textColor="#2B2B2B"
        android:textSize="15sp"
        android:textStyle="bold"
        android:visibility="gone" />

    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="#0d000000" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rcv_btn_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

列表Item

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="45dp">

    <TextView
        android:id="@+id/tv_dialog_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textColor="#2B2B2B"
        android:textSize="15dp"
        android:textStyle="bold" />

    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:layout_alignParentBottom="true"
        android:background="#0d000000" />

</RelativeLayout>

列表样式实体类

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<BtnsBottomDialogAdapter.VH> {
    private static final String TAG = "BtnsBottomDialogAdapter";

    private Context context;
    private List<DialogBtnData> btnList;
    private OnItemClickListener itemClickListener;

    public BtnsBottomDialogAdapter(Context context, List<DialogBtnData> 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<DialogBtnData> 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<DialogBtnData> 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);
  }

}

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

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-11-09 19:40:29  更:2021-11-09 19:42:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/24 16:21:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码