我是靠谱客的博主 敏感黄豆,最近开发中收集的这篇文章主要介绍底部弹窗组建,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

★项目背景、需求

商城项目中多个地方存在底部弹窗,现将ui统一,并输出UI组件,方便后期维护。

目前涉及页面有

1、商详页:商品描述底部弹窗、优惠券底部弹窗

2、订单结算页:注意事项底部弹窗,由于选择日期底部弹窗业务过于耦合,所以不会抽到组件中

★功能定位&目标

★总体设计

主要使用BottomSheetDialog与BottomDialogBuilder,内容区主要是用recyclerview实现,配合FlexibleAdapter,因此需要使用方自定义item继承AbstractFlexibleItem

★详细设计

增加title字体大小、颜色,描述及字体大小、颜色,底部按钮文字、文字颜色、大小、背景颜色等功能。

★接入使用说明

使用

 
 

new BottomDialogBuilder(v.getContext())

.title("买贵赔")

.maxAndMinHeight(500, 240)

.item(new GoodsDetailMaiGuiPeiItem(maiGuiPeiInfo))

.recyclerView(recyclerView -> {

float density = recyclerView.getContext().getResources().getDisplayMetrics().density;

recyclerView.setClipToPadding(false);

recyclerView.setClipChildren(false);

int padding = (int) (20 * density);

recyclerView.setPadding(padding, padding, padding, padding);

return null;

})

.show();

package com.meicai.uikit.bottomdialog

import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.view.WindowManager
import android.widget.*
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.meicai.uikit.R
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.IFlexible

/**
 * 底部弹窗 通用结构
 *
 * @author BiaoWu
 */
class BottomDialogBuilder(private val context: Context) {
    private val bottomSheetDialog: BaseBottomSheetDialog = BaseBottomSheetDialog(context)

    private val recyclerView: androidx.recyclerview.widget.RecyclerView
    private val adapter = FlexibleAdapter<IFlexible<*>>(null)
    private val scrollLinearLayoutManager = ScrollLinearLayoutManager(context).apply {
        orientation = LinearLayoutManager.VERTICAL
    }
    private var titleStr = "";
    private var descStr = "";

    init {
        bottomSheetDialog.setContentView(R.layout.mall_bottom_dialog)

        recyclerView = bottomSheetDialog.findViewById(R.id.rv)!!
        recyclerView.layoutManager = scrollLinearLayoutManager
        recyclerView.adapter = adapter
        bottomSheetDialog.findViewById<View>(R.id.close)?.setOnClickListener {
            bottomSheetDialog.dismiss()
        }

//        bottomSheetDialog.findViewById<View>(R.id.btnRitht)?.setOnClickListener {
//            bottomSheetDialog.dismiss()
//        }
    }

    fun decorView(): View {
        return bottomSheetDialog.window!!.decorView
    }

    fun bgRadius(@ColorInt color: Int, radius: Int): BottomDialogBuilder {
        val bottomSheet = bottomSheetDialog.findViewById<FrameLayout>(R.id.design_bottom_sheet)!!
        val backgroundDrawable = GradientDrawable()
        backgroundDrawable.cornerRadius = radius * context.resources.displayMetrics.density
        backgroundDrawable.setColor(color)
        bottomSheet.background = backgroundDrawable
        return this
    }

    /**
     * 顶部title显示
     */
    fun title(title: String): BottomDialogBuilder {
        bottomSheetDialog.findViewById<TextView>(R.id.title)?.visibility = View.VISIBLE
        bottomSheetDialog.findViewById<TextView>(R.id.title)?.text = title
        titleStr = title
        if (TextUtils.isEmpty(descStr)) {
            bottomSheetDialog.findViewById<TextView>(R.id.title)?.maxLines = 2
        } else {
            bottomSheetDialog.findViewById<TextView>(R.id.title)?.maxLines = 1

        }
        return this
    }

    /**
     * 顶部desc显示
     */
    fun desc(desc: String): BottomDialogBuilder {
        bottomSheetDialog.findViewById<TextView>(R.id.desc)?.visibility = View.VISIBLE
        bottomSheetDialog.findViewById<TextView>(R.id.desc)?.text = desc
        descStr = desc
        if (TextUtils.isEmpty(titleStr)) {
            bottomSheetDialog.findViewById<TextView>(R.id.desc)?.maxLines = 2
        } else {
            bottomSheetDialog.findViewById<TextView>(R.id.desc)?.maxLines = 1
        }
        return this
    }

    fun buttonLeft(buttonStr: String): BottomDialogBuilder {
        bottomSheetDialog.findViewById<TextView>(R.id.btnLeft)?.visibility = View.VISIBLE
        bottomSheetDialog.findViewById<TextView>(R.id.btnLeft)?.text = buttonStr
        if (bottomSheetDialog.findViewById<TextView>(R.id.btnRitht)?.visibility == View.GONE) {
            bottomSheetDialog.findViewById<Space>(R.id.space)?.visibility == View.GONE
        }
        return this
    }

    fun buttonRight(buttonStr: String): BottomDialogBuilder {
        bottomSheetDialog.findViewById<TextView>(R.id.btnRitht)?.visibility = View.VISIBLE
        bottomSheetDialog.findViewById<TextView>(R.id.btnRitht)?.text = buttonStr
        if (bottomSheetDialog.findViewById<TextView>(R.id.btnLeft)?.visibility == View.GONE) {
            bottomSheetDialog.findViewById<Space>(R.id.space)?.visibility == View.GONE
        }
        return this
    }

    /*
    * 点击按钮 关闭弹窗
    *
    * */
    fun buttonLeftlClick(buttonclick: View.OnClickListener): BottomDialogBuilder {
        return buttonLeftlClick(true, buttonclick)
    }

    /*
       * 点击按钮
       * autoDismiss 设置是否关闭弹窗
       * */
    fun buttonLeftlClick(autoDismiss: Boolean = true, buttonclick: View.OnClickListener): BottomDialogBuilder {
        bottomSheetDialog.findViewById<TextView>(R.id.btnLeft)?.setOnClickListener { view ->
            if (autoDismiss) {
                bottomSheetDialog.dismiss()
            }
            buttonclick.onClick(view)
        }
        return this
    }

    /*
    * 点击按钮 关闭弹窗
    *
    * */
    fun buttonRightClick(buttonclick: View.OnClickListener): BottomDialogBuilder {
        return buttonRightClick(true, buttonclick)
    }

    /*
      * 点击按钮
      * autoDismiss 设置是否关闭弹窗
      * */
    fun buttonRightClick(autoDismiss: Boolean = true, buttonclick: View.OnClickListener): BottomDialogBuilder {
        bottomSheetDialog.findViewById<TextView>(R.id.btnRitht)?.setOnClickListener { view ->
            if (autoDismiss) {
                bottomSheetDialog.dismiss()
            }
            buttonclick.onClick(view)
        }
        return this
    }

    /*
     * 点击按钮背景颜色
     * */
    fun buttonLeftBg(bg: Drawable): BottomDialogBuilder {
        bottomSheetDialog.findViewById<TextView>(R.id.btnLeft)?.background = bg
        return this
    }

    /*
     * 点击按钮背景颜色
     * */
    fun buttonRightBg(bg: Drawable): BottomDialogBuilder {
        bottomSheetDialog.findViewById<TextView>(R.id.btnRitht)?.background = bg
        return this
    }

    /**
     * 设置button模块的背景
     */
    fun buttonModuleBg(bg: Drawable): BottomDialogBuilder {
        bottomSheetDialog.findViewById<LinearLayout>(R.id.llConfirm)?.background = bg
        return this
    }

    /*
     * 按钮文字颜色
     * */
    fun buttonLeftTextColor(color: Int): BottomDialogBuilder {
        bottomSheetDialog.findViewById<TextView>(R.id.btnLeft)?.setTextColor(color)
        return this
    }

    /**
     * 顶部title 字体大小
     */
    fun titleTextSize(textSize: Float): BottomDialogBuilder {
        bottomSheetDialog.findViewById<TextView>(R.id.title)?.textSize = textSize
        return this
    }

    /**
     * 顶部title icon显示
     */
    fun titleIcon(@DrawableRes resId: Int): BottomDialogBuilder {
        bottomSheetDialog.findViewById<ImageView>(R.id.icon)?.also {
            it.visibility = View.VISIBLE
            it.setImageResource(resId)
        }
        return this
    }

    /**
     * 整个标题模块的背景设置
     */
    fun titleModuleBg(bg: Drawable): BottomDialogBuilder {
        bottomSheetDialog.findViewById<ConstraintLayout>(R.id.top)?.background = bg
        return this
    }

    /**
     * 设置弹窗的padding
     */
    fun padding(left: Int, top: Int, right: Int, bottom: Int): BottomDialogBuilder {
        bottomSheetDialog.findViewById<ConstraintLayout>(R.id.clDlg)?.setPadding(left, top, right, bottom)
        return this
    }

    /**
     * 显示、隐藏左上角关闭按钮
     */
    fun showCloseImage(isShow: Boolean): BottomDialogBuilder {
        if (isShow) {
            bottomSheetDialog.findViewById<FrameLayout>(R.id.close)?.visibility = View.VISIBLE
        } else {
            bottomSheetDialog.findViewById<FrameLayout>(R.id.close)?.visibility = View.GONE
        }
        return this
    }

    /**
     * 设置内容部分(RecyclerView)的最大高度
     *
     * 单位是dp
     */
    fun maxHeight(maxHeight: Int): BottomDialogBuilder {
        maxAndMinHeight(maxHeight, 50)
        return this
    }

    /**
     * 设置内容部分(RecyclerView)的最大高度
     *
     * maxHeightPercent 百分比
     */
    fun maxHeight(maxHeightPercent: Float): BottomDialogBuilder {
        maxAndMinHeight(maxHeightPercent, 0f)
        return this
    }

    /**
     * 设置内容部分(RecyclerView)的最大高度
     *
     * maxHeightPercent 百分比
     *
     * 如果没有设置最小高度,默认设置50
     */
    fun maxAndMinHeight(maxHeightPercent: Float, minHeightPercent: Float): BottomDialogBuilder {
        val layoutParams = recyclerView.layoutParams as ConstraintLayout.LayoutParams
        val density = context.resources.displayMetrics.density
        val windowManager = context
                .getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val display = windowManager.defaultDisplay
        //屏幕高度
        val displayHeight = display.height
        layoutParams.constrainedHeight = true
        layoutParams.matchConstraintMaxHeight = (maxHeightPercent * displayHeight).toInt()
        if (minHeightPercent == 0f) {
            layoutParams.matchConstraintMinHeight = (Math.min(50, (maxHeightPercent * displayHeight).toInt()) * density).toInt()
        } else {
            layoutParams.matchConstraintMinHeight = (minHeightPercent * displayHeight).toInt()
        }
        Log.i("====matchConstraintMaxHeight===", "  " + (maxHeightPercent * displayHeight).toInt())
        Log.i("====matchConstraintMinHeight===", "  " + (Math.min(50, (maxHeightPercent * displayHeight).toInt()) * density).toInt())
        recyclerView.layoutParams = layoutParams

        return this
    }

    /**
     * 设置内容部分(RecyclerView)的最大高度及最小高度
     *
     * 单位是dp
     */
    fun maxAndMinHeight(maxHeight: Int, minHeight: Int): BottomDialogBuilder {
        val layoutParams = recyclerView.layoutParams as ConstraintLayout.LayoutParams
        val density = context.resources.displayMetrics.density

        layoutParams.constrainedHeight = true
        layoutParams.matchConstraintMaxHeight = (maxHeight * density).toInt()
        layoutParams.matchConstraintMinHeight = (Math.min(minHeight, maxHeight) * density).toInt()

        recyclerView.layoutParams = layoutParams

        return this
    }

    fun recyclerView(fill: (recyclerView: androidx.recyclerview.widget.RecyclerView) -> Unit): BottomDialogBuilder {
        recyclerView.visibility = View.VISIBLE
        fill(recyclerView)
        return this
    }

    /**
     * rv默认状态下 是否可以在垂直方向上滑动
     */
    fun rvCanVerticalScroll(canVerticalScroll: Boolean): BottomDialogBuilder {
        scrollLinearLayoutManager.setCanVerticalScroll(canVerticalScroll)
        return this
    }

    fun adapter(fill: (adapter: FlexibleAdapter<IFlexible<*>>) -> Unit): BottomDialogBuilder {
        recyclerView.visibility = View.VISIBLE
        fill(adapter)
        return this
    }

    /**
     * 关闭按钮的监听,如果不设置的话,有默认的dismiss
     */
    fun onCloseClickListener(onClose: (recyclerView: androidx.recyclerview.widget.RecyclerView, adapter: FlexibleAdapter<IFlexible<*>>) -> Unit): BottomDialogBuilder {
        bottomSheetDialog.findViewById<View>(R.id.close)?.setOnClickListener {
            onClose(recyclerView, adapter)
            bottomSheetDialog.dismiss()
        }
        return this
    }

    fun onDismissListener(disMissListener: DialogInterface.OnDismissListener): BottomDialogBuilder {
        bottomSheetDialog.setOnDismissListener(disMissListener)
        return this
    }

    /**
     * 内容部分的数据,整体替换api
     */
    fun items(items: List<IFlexible<*>>): BottomDialogBuilder {
        recyclerView.visibility = View.VISIBLE
        adapter.updateDataSet(items)
        return this
    }

    /**
     * 内容部分的数据,单个添加的api
     */
    fun item(item: IFlexible<*>): BottomDialogBuilder {
        recyclerView.visibility = View.VISIBLE
        adapter.addItem(item)
        return this
    }

    /**
     * 内容部分的数据,单个TextView
     * @textStr 需要显示的文字内容
     */
    fun itemTextStr(textStr: String): BottomDialogBuilder {
        recyclerView.visibility = View.VISIBLE
        adapter.addItem(TextViewItem(textStr))
        return this
    }

    fun dialog(): Dialog {
        return bottomSheetDialog
    }

    /**
     * 最后调用显示dialog
     */
    fun show() {
        bottomSheetDialog?.show()
        refreshPeekHeight()
    }

    /**
     * 隐藏示dialog
     */
    fun dismiss() {
        bottomSheetDialog?.dismiss()
    }

    /**
     * 设置背景颜色
     */
    fun recyclerViewBg(color: Int): BottomDialogBuilder {
        recyclerView.setBackgroundColor(color)
        return this
    }

    fun refreshPeekHeight() {
        // dialog 弹出来的距离就是整体自定义View的高度
        recyclerView.post {
            val bottomSheet = bottomSheetDialog.findViewById<FrameLayout>(R.id.design_bottom_sheet)!!
            val behavior = BottomSheetBehavior.from(bottomSheet)
            behavior.peekHeight = bottomSheet.height
        }
    }

}

最后

以上就是敏感黄豆为你收集整理的底部弹窗组建的全部内容,希望文章能够帮你解决底部弹窗组建所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部