BottomSheetDialogFragment实现地图导航弹窗效果

Vue结合高德地图实现HTML写自定义信息弹窗 通过HTML写高德地图的自定义信息弹窗 阅读详情

需求如下:从服务器查询列表在地图上弹窗显示,首次只能显示两条Item,下滑隐藏,上滑动铺满位于titleBar下,点击标记物显示详情,详情内可以点击查看列表

看效果图

在这里插入图片描述

首先想到的是NetScrollView CoordinatorLayout Behavior,当然还有BottomSheet系列,个人比较倾向于BottomSheetDialogFragment,不用在layout 绑定behavior操作,就像一般的Fragment dialog使用一样即可

相关BottomSheetDialogFragment的使用操作先推荐一篇文章科普,很有必要看哟

https://www.jianshu.com/p/7fcec871ea36

根据上面这边博客我先搞一个BaseBottomSheetFragment基类,方便其他地方调用


import android.app.Dialog
import android.content.DialogInterface
import android.graphics.Color
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.*
import androidx.annotation.NonNull
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.fragment.app.FragmentManager
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.zgph.xz.sitemap.R
import java.lang.reflect.Method
import kotlin.math.min
import kotlin.properties.Delegates


abstract class BaseBottomSheetFragment : BottomSheetDialogFragment() {

    protected var rootView: View? = null

    /**
     * 默认显示item Count : 0
     */
    protected var itemCount = 0

    /**
     * 设置默认弹出高度peekHeight
     */
    protected var minPeekHeight by Delegates.notNull<Int>()

    /**
     * 设置默认弹出最大高度maxPeekHeight
     */
    protected var maxPeekHeight by Delegates.notNull<Int>()

    /**
     * 控制显示高度、状态值
     */
    private var mBottomSheetBehavior: BottomSheetBehavior<View>? = null

    private lateinit var mBottomSheet: View

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //弹出BottomSheetDialog背景变暗
        /**
         *
        <style name="TransBottomSheetDialogStyle" parent="Theme.Design.Light.BottomSheetDialog">
        <item name="android:windowFrame">@null</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:background">@android:color/transparent</item>
        <item name="android:backgroundDimEnabled">false</item>
        </style>
         *
         */

        //弹出BottomSheetDialog背景变暗解决方案
        setStyle(BottomSheetDialogFragment.STYLE_NORMAL, R.style.pr_TransBottomSheetDialogStyle)
        //item显示几条
        itemCount = getShowItemCount()
        //初始化弹出初始高度和弹出最大高度
        minPeekHeight = BottomSheetDelegate.getMinPeekHeight(context!!,getItemLayoutResId(), getHeaderLayoutResId(), itemCount)
        maxPeekHeight = BottomSheetDelegate.getMaxHeight(activity!!,getTitleBarLayoutResId())
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        if (null != rootView) {
            val parent = rootView!!.parent as ViewGroup
            parent?.removeView(rootView)
        } else {
            rootView = inflater.inflate(getContentViewResID(), null)
            initialize()
        }
        initialize()
        return rootView
    }

    override fun onStart() {
        super.onStart()
        initBottomSheet()
    }

    private fun initBottomSheet() {

        val dialog: Dialog? = dialog
        if (dialog != null) {
            val bottomSheet: View = dialog.findViewById(R.id.design_bottom_sheet)
            //bottomSheet.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
            //点击外部能让dialog 消失
            dialog.setCanceledOnTouchOutside(true)
            //防止最大高度View视图位置显示不正确
            dialog?.window?.setGravity(Gravity.BOTTOM);
        }
        val view = view
        view!!.post {
            val parent = view.parent as View
            val params = parent.layoutParams as CoordinatorLayout.LayoutParams
            mBottomSheetBehavior = params.behavior as BottomSheetBehavior<View>?
            //禁止下拉隐藏
            //mBottomSheetBehavior?.isHideable = false
            //设置初始弹出最大高度
            setPeekHeight(minPeekHeight)
            //解决背景和弹出背景重叠
            parent.setBackgroundColor(Color.TRANSPARENT)
            //设置回调函数用于设置拖拽扩展view最大高度设置
            setBottomSheetCallback()
        }
    }

    private fun setBottomSheetCallback() {
        if (mBottomSheetBehavior != null) {
            mBottomSheetBehavior!!.addBottomSheetCallback(mBottomSheetCallback)
        }
    }

    private val mBottomSheetCallback: BottomSheetCallback = object : BottomSheetCallback() {
        override fun onStateChanged(@NonNull bottomSheet: View,
            @BottomSheetBehavior.State newState: Int) {
            mBottomSheet = bottomSheet
            var layoutParams = bottomSheet.layoutParams
            if (bottomSheet.height > maxPeekHeight) {
                layoutParams.height = maxPeekHeight
                bottomSheet.layoutParams = layoutParams
            }

            if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
                listener?.onCollapsed()
            } else if (newState == BottomSheetBehavior.STATE_EXPANDED) {
                listener?.onExpand()
            }
        }

        override fun onSlide(@NonNull bottomSheet: View, slideOffset: Float) {

        }
    }

    /**
     * 设置显示弹窗高度
     */
    protected fun setPeekHeight(mPeekHeight: Int) {
        if (mPeekHeight <= 0) {
            return
        }
        minPeekHeight = mPeekHeight
        mBottomSheetBehavior!!.peekHeight = minPeekHeight
    }
    
    override fun show(manager: FragmentManager, tag: String?) {
        super.show(manager, tag)
        dialog?.setOnShowListener {
            var parentView = rootView?.parent as View
            val params = parentView.layoutParams as CoordinatorLayout.LayoutParams
            params.gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
            parentView.layoutParams = params
        }
    }

    override fun onDismiss(dialog: DialogInterface) {
        super.onDismiss(dialog)
        onBottomSheetDismiss()
    }
  //Dialog消失毁掉可以自己处理一些逻辑,如果不需要可以取消函数相关调用
    protected abstract fun onBottomSheetDismiss()
   //整体布局setContentView
    protected abstract fun getContentViewResID(): Int
    //设置初始弹出显示Item布局ID(adapte 单一type)
    protected abstract fun getItemLayoutResId(): Int
    //设置初始弹出显示位于某个Layout布局之下(例如自定义的titleBar)
    protected abstract fun getTitleBarLayoutResId(): Int
  //设置初始弹出显示RecyclerView的HeaderView布局,如果没有HeaderView默认返回-1
    protected abstract fun getHeaderLayoutResId(): Int
   //设置初始弹出显示Item条数
    protected abstract fun getShowItemCount(): Int

    protected abstract fun initialize()

    interface OnBottomSheetSiteListener {
        //展开状态毁掉 
        fun onExpand()
        //收缩状态毁掉
        fun onCollapsed()
    }

    private var listener: OnBottomSheetSiteListener? = null

    protected fun addOnBottomSheetSiteListener(onBottomSheetSiteListener: OnBottomSheetSiteListener) {
        listener = onBottomSheetSiteListener
    }
}

使用时注意拷贝注释掉的style,关于一些view高度测量相关的函数提取到BottomSheetDelegate类代理


import android.app.Activity
import android.content.Context
import android.util.DisplayMetrics
import android.view.Display
import android.view.LayoutInflater
import android.view.View
import java.lang.reflect.Method

class BottomSheetDelegate {

    companion object{
        /**
         * @param titleBarLayoutResId: NoActionBar Theme》屏幕高度-虚拟按键高度-指定的top view 部分高度,这里id=topView部分id
         * 默认展示两个Item,为了测量方便这里布局子view高度用精确值
         */
        fun getMinPeekHeight(context: Context,itemLayoutResId: Int, headerLayoutResId: Int,itemCount:Int):Int {
            var minPeekHeight = 0
            if (headerLayoutResId == -1) {
                minPeekHeight = getMeasuredHeightWithResId(context!!,itemLayoutResId) * itemCount
            } else {
                minPeekHeight = getMeasuredHeightWithResId(context!!,itemLayoutResId) * itemCount + getMeasuredHeightWithResId(context!!,headerLayoutResId)
            }
            return minPeekHeight
        }

        /**
         * 测量view 高度,布局使用精确值
         */
        fun getMaxHeight(activity: Activity,titleBarLayoutResId: Int): Int {

            //系统屏幕高度
            val outMetrics = DisplayMetrics()
            activity?.windowManager?.defaultDisplay?.getMetrics(outMetrics)
            val heightPixels = outMetrics.heightPixels

            //自定义标题栏背景向上填充statusBar 高度
            val resourceId: Int =
                activity!!.resources.getIdentifier("status_bar_height", "dimen", "android")
            val statusBarHeight: Int = activity!!.resources.getDimensionPixelSize(resourceId)

            //计算自定义标题栏高度
            var itemView = LayoutInflater.from(activity).inflate(titleBarLayoutResId, null, false)
            var w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
            var h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
            itemView.measure(w, h);

            //兼容凹凸屏幕
            var max = 0
            var notchSize = activity!!.let { NotchScreenUtil.getNotchHeight(it) }
            if (notchSize != 0) {
                max = heightPixels - itemView.measuredHeight - statusBarHeight + notchSize
            } else {
                max = heightPixels - itemView.measuredHeight - statusBarHeight
            }

            return max
        }

        /**
         * 获取虚拟按键高度
         */
         fun getVirtualBarHeight(activity:Activity): Int {
            var vh = 0
            val display: Display = activity!!.windowManager.defaultDisplay
            val dm = DisplayMetrics()
            try {
                val c = Class.forName("android.view.Display")
                val method: Method = c.getMethod("getRealMetrics", DisplayMetrics::class.java)
                method.invoke(display, dm)
                vh = dm.heightPixels - display.height
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return vh
        }

        /**
         * 测量view 高度,布局使用精确值
         */
         fun getMeasuredHeightWithResId(context:Context,layoutResId: Int): Int {
            var itemView = LayoutInflater.from(context).inflate(layoutResId, null, false)
            var w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
            var h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
            itemView.measure(w, h);
            return itemView.measuredHeight
        }

        fun setBottomSheetCallback(){

        }
    }
}

Tip: 这里的测量模式是根据自己布局写死的,具体使用具体修改,maxHeight的计算是根据自己UI实现的,也是具体界面具体修改,虚拟按键高度获取提供了暂未使用

这里面还做了关于华为、vivo、oppo手机凹凸屏幕高度获取适配NotchScreenUtil


import android.annotation.SuppressLint
import android.content.Context
import android.os.Build
import android.util.Log
import android.util.TypedValue
import java.lang.reflect.Method


class NotchScreenUtil {
    companion object{
        /**
         * 华为start
         */
        // 判断是否是华为刘海屏
        fun hasNotchInScreenAtHuawei(context: Context): Boolean {
            var ret = false
            try {
                val cl: ClassLoader = context.getClassLoader()
                val HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil")
                val get: Method = HwNotchSizeUtil.getMethod("hasNotchInScreen")
                ret = get.invoke(HwNotchSizeUtil) as Boolean
                Log.d("NotchScreenUtil", "this Huawei device has notch in screen?$ret")
            } catch (e: ClassNotFoundException) {
                Log.e("NotchScreenUtil", "hasNotchInScreen ClassNotFoundException", e)
            } catch (e: NoSuchMethodException) {
                Log.e("NotchScreenUtil", "hasNotchInScreen NoSuchMethodException", e)
            } catch (e: Exception) {
                Log.e("NotchScreenUtil", "hasNotchInScreen Exception", e)
            }
            return ret
        }

        /**
         * 获取华为刘海的高
         * @param context
         * @return
         */
        fun getNotchSizeAtHuawei(context: Context): Int {
            var ret = intArrayOf(0, 0)
            try {
                val cl: ClassLoader = context.getClassLoader()
                val HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil")
                val get: Method = HwNotchSizeUtil.getMethod("getNotchSize")
                ret = get.invoke(HwNotchSizeUtil) as IntArray
            } catch (e: ClassNotFoundException) {
                Log.e("NotchScreenUtil", "getNotchSize ClassNotFoundException")
            } catch (e: NoSuchMethodException) {
                Log.e("NotchScreenUtil", "getNotchSize NoSuchMethodException")
            } catch (e: Exception) {
                Log.e("NotchScreenUtil", "getNotchSize Exception")
            }
            return ret[1]
        }

        /**
         * Oppo start
         */
        fun hasNotchInScreenAtOppo(context: Context): Boolean {
            val hasNotch: Boolean =
                context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism")
            Log.d("NotchScreenUtil", "this OPPO device has notch in screen?$hasNotch")
            return hasNotch
        }

        val notchSizeAtOppo: Int
            get() = 80

        val NOTCH_IN_SCREEN_VOIO = 0x00000020 // 是否有凹槽

        fun hasNotchInScreenAtVivo(context: Context): Boolean {
            var ret = false
            try {
                val cl: ClassLoader = context.getClassLoader()
                val FtFeature = cl.loadClass("com.util.FtFeature")
                val get: Method = FtFeature.getMethod("isFeatureSupport", Int::class.javaPrimitiveType)
                ret = get.invoke(FtFeature, NOTCH_IN_SCREEN_VOIO) as Boolean
                Log.d("NotchScreenUtil", "this VIVO device has notch in screen?$ret")
            } catch (e: ClassNotFoundException) {
                Log.e("NotchScreenUtil", "hasNotchInScreen ClassNotFoundException", e)
            } catch (e: NoSuchMethodException) {
                Log.e("NotchScreenUtil", "hasNotchInScreen NoSuchMethodException", e)
            } catch (e: Exception) {
                Log.e("NotchScreenUtil", "hasNotchInScreen Exception", e)
            }
            return ret
        }

        fun getNotchSizeAtVivo(context: Context): Int {
            return dp2px(context, 32)
        }
        /**
         * vivo end
         */
        /**
         * dp转px
         * @param context
         * @param dpValue
         * @return
         */
        private fun dp2px(context: Context, dpValue: Int): Int {
            return TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, dpValue.toFloat(), context.getResources()
                    .getDisplayMetrics()
            )
                .toInt()
        }

        /**
         * 获取手机厂商
         *
         * @return  手机厂商
         */
        val DEVICE_BRAND_OPPO = 0x0001
        val DEVICE_BRAND_HUAWEI = 0x0002
        val DEVICE_BRAND_VIVO = 0x0003

        @get:SuppressLint("DefaultLocale")
        val deviceBrand: Int
            get() {
                val brand = Build.BRAND.trim { it <= ' ' }.toUpperCase()
                if (brand.contains("HUAWEI")) {
                    return DEVICE_BRAND_HUAWEI
                } else if (brand.contains("OPPO")) {
                    return DEVICE_BRAND_OPPO
                } else if (brand.contains("VIVO")) {
                    return DEVICE_BRAND_VIVO
                }
                return 0
            }

        fun getNotchHeight(context: Context):Int{
            var height = 0
            when (deviceBrand) {

                DEVICE_BRAND_HUAWEI -> {
                    if (hasNotchInScreenAtHuawei(context)) {
                        height = getNotchSizeAtHuawei(context)
                    }
                }

                DEVICE_BRAND_OPPO -> {
                    if (hasNotchInScreenAtOppo(context)) {
                        height = notchSizeAtOppo
                    }
                }

                DEVICE_BRAND_VIVO -> {
                    if (hasNotchInScreenAtVivo(context)) {
                        height = getNotchSizeAtVivo(context)
                    }
                }
            }
            return height
        }
    }
}

最后再提供一个函数关于上图效果三角形旋转的代码块(如果使用两张图就可以忽略了)

private fun rotateBitmap(bm: Bitmap, orientationDegree: Float): Bitmap? {
        //方便判断,角度都转换为正值
        var degree = orientationDegree
        if (degree < 0) {
            degree = 360 + orientationDegree
        }
        val srcW = bm.width
        val srcH = bm.height
        val m = Matrix()
        m.setRotate(degree, srcW.toFloat() / 2, srcH.toFloat() / 2)
        val targetX: Float
        val targetY: Float
        var destH = srcH
        var destW = srcW

        //根据角度计算偏移量,原理不明
        if (degree == 90f) {
            targetX = srcH.toFloat()
            targetY = 0f
            destH = srcW
            destW = srcH
        } else if (degree == 270f) {
            targetX = 0f
            targetY = srcW.toFloat()
            destH = srcW
            destW = srcH
        } else if (degree == 180f) {
            targetX = srcW.toFloat()
            targetY = srcH.toFloat()
        } else {
            return bm
        }
        val values = FloatArray(9)
        m.getValues(values)
        val x1 = values[Matrix.MTRANS_X]
        val y1 = values[Matrix.MTRANS_Y]
        m.postTranslate(targetX - x1, targetY - y1)

        //注意destW 与 destH 不同角度会有不同
        val bm1 = Bitmap.createBitmap(destW, destH, Bitmap.Config.ARGB_8888)
        val paint = Paint()
        val canvas = Canvas(bm1)
        canvas.drawBitmap(bm, m, paint)
        return bm1
    }

有以上代码我相信你也可以轻松实现上图效果,源码暂不上传了

Android 之BottomsheetDialogFragment仿抖音评论底部弹出对话框效果(实例代码) 实现的效果图: 自定义Fragment继承BottomSheetDialogFragment 重写它的三个方法: onCreateDialog() onCreateView() onStart() 他们的执行顺序是从上到下 import android.app.Dialog; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.util. 立即下载

相关推荐

QMI8658A和QMC5883L传感器校准全攻略:从零偏校准到椭球拟合

本文详细解析了QMI8658A和QMC5883L传感器的校准方法,从零偏校准到椭球拟合,涵盖了9轴运动传感器的核心误差来源及补偿技术。通过实战案例和数学建模,帮助开发者提升传感器精度,适用于无人机、AR/VR等智能硬件应用。

weixin_29189381的博客 158

Android开发-BottomSheet的使用和说明

Android开发-BottomSheetDialogFragment的使用和封装介绍在官方提供的android.support.design.widget包中,加入bottom sheet能够很方便的实现一些酷炫的功能。官方blog说明得比较简单,中文博客上也有一些介绍和说明 Android Bottom Sheet详解本文就是从这些博文中开始探索,最后总结一些使用经验和封装方便之后的使用。简单

李可乐的专栏 1万+

设备树实践:从零构建一个嵌入式板级的设备树描述

本文详细介绍了如何从零开始为嵌入式Linux系统构建设备树(Device Tree),以i.MX6ULL处理器为例,涵盖硬件分析、设备树语法、外设配置及调试技巧。通过实践指导,帮助开发者掌握设备树编写,实现硬件与软件的高效对接,提升嵌入式开发效率。

plum99的博客 305

Android开发之BottomsheetDialogFragment的使用

Android 开发之 BottomsheetDialogFragment 的使用 BottomSheetDialogFragment 继承自 AppCompatDialogFragment,官方解释为模态底部表,是 DialogFragment 的一个版本,它使用的是 BottomSheetDialog,而不是浮动对话框。BottomSheetDialogFragment 相对于其它对话框有着...

付小华的博客 3万+

Dify 进阶指南 | 5步打造智能JSON转换器(Excel数据预处理神器)

本文详细介绍了如何利用Dify平台的Chatflow功能,通过5个步骤构建一个智能JSON转换器,专门用于Excel数据预处理。该工具能够根据用户指令自动解析Excel表格,执行数据清洗、聚合计算,并精准输出定制化的JSON格式,极大提升前端开发、数据分析与测试工作的效率。

weixin_28520495的博客 574

shopee app算法分析第一篇

shopee app算法分析第一篇分析完整算法大概要好几篇,耐心等待下.国内只会发律师函,牛逼,一个律师套话,一个律师发函,大意了(警惕卡通律师头像),希望law可以保护好你,还是干国外好.

2531

Android BottomSheetDialogFragment 使用详解,设置圆角、固定高度、默认全屏

Android BottomSheetDialogFragment 使用详解,设置圆角、固定高度、默认全屏

leveretz的博客 2926

YOLOv8改进策略【Conv和Transformer】| CVPR-2023 BiFormer 稀疏自注意力,减少内存占用

本文记录的是利用双级路由注意力机制优化的目标检测网络模型。传统的复杂度高,随着输入空间分辨率增加,计算量呈平方增长,导致严重的可扩展性问题。而本文所使用的在获取全局信息的同时,通过区域到区域路由和令牌到令牌注意力的合理设计,减少了不必要的计算量。BiFormer: Vision Transformer with Bi-Level Routing Attention采用四阶段金字塔结构,与一些先进的视觉Transformer类似。在每个阶段,首先使用重叠的补丁嵌入(在第一阶段)或补丁合并模块(在第二到第四阶段

Limiiiing的博客 613

一文分析 BottomSheetDialogFragment使用方式及实现原理

分析 BottomSheetDialogFragment 使用方式及实现原理

bjxiaxueliang的CODING小栈 1万+

【华为OD机试真题 2025C卷新题】855、识文断句 | 机试真题+思路参考+代码分析(C++、Java、Py、C语言、JS)

【华为OD机试真题 2025C卷新题】855、识文断句 | 机试真题+思路参考+代码分析(C++、Java、Py、C语言、JS) 华为od机试,华为od机试真题,华为od机试E卷,华为odE卷,华为od机试真题E卷,华为OD,华为OD机试,华为OD机试真题,华为od机考,华为od机试D卷,华为od机试真题D卷,华为od手撕代码,华为od,华为od机试C卷,华为od e卷,华为2025e卷,od机试,2025E卷,华为OD机试E卷,什么是华为od,华为od介绍,全面了解华为od,2025华为od,如何备战华为

KJ.JK 1850

STM32开发 -- LIS3DH三轴加速度计开发详解

这次要讲一下LIS3DH三轴加速度计的开发使用,之前是有讲过 MPU6050开发 的,但当时是在Linux下做的。额,还是个半成品,哈哈。现在手边有STM32的开发板,可以实实在在的来实现以下卡尔曼滤波了。 一、LIS3DH初识 依照惯例,先看一下手册,大致先了解一下,LIS3DH是什么模块。 下载:LIS3DH datasheet 1、描述 LIS3DH是一款超低功耗高性能三轴线性加速度计,属于...

不积跬步,无以至千里 2万+

BottomSheetDialogFragment使用

BottomSheetDialogFragment继承于DialogFragment,一个Dialog形式的framgnet,可实现拖动打开及关闭 如源码所示,在BottonSheetDialogFragment内部是创建了一个BottomSheetDialog public class BottomSheetDialogFragment extends AppCompatDialogFragment { public BottomSheetDialogFragment() { }

Super_666的博客 3748

【深度学习|地学应用】MODIS AOD产品和HYSPLIT模型的局限性和不确定性?

【深度学习|地学应用】MODIS AOD产品和HYSPLIT模型的局限性和不确定性?

985小水博的摸鱼日常 462

Android BottomSheetDialogFragment 可随手势滑动关闭的底部弹窗

在APP开发中,经常会有一个需求: 从底部弹出弹窗,并且可以跟随手指滑动关闭弹窗. 简介 BottomSheetDialogFragment是位于com.google.android.material包下的一个类. BottomSheetDialogFragment 继承自AppCompatDialogFragment AppCompatDialogFragment继承自DialogFragme...

卓原的进化之旅 8078

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

【Android】BottomSheet基本用法总结(BottomSheetDialog,BottomSheetDialogFragment)

是一种位于屏幕底部的面板,用于显示附加内容或选项。提供了从屏幕底部向上滑动显示内容的交互方式。这种设计模式在 Material Design 中被广泛推荐,因为它可以提供一种优雅且不干扰主屏幕内容的方式来展示额外信息或操作。具体实现主要包含:BottomSheetBeahvior 、BottomSheetDialog、BottomSheetDialogFragment。

Patrick_yuxuan的博客 3768

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

BottomSheetDialogFragment大量踩坑-自适应高度和最大高度和滚动问题等等

BottomSheetDialogFragment有大量的坑,这里做了不少的记录。固定展开,含有EditText的处理,自定义Toast的显示父控件,无法在dismiss之前得到监听,自适应高度和限定最大高度,含有滚动内容的处理。

jzlhll123的专栏 2577

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

BottomSheet 的使用介绍(BottomSheetBeahvior,BottomSheetDialog,BottomSheetDialogFragment)

BottomSheet是一种从屏幕底部向上滑出一个对话框的效果,可以用来显示内容或者提供与用户相关的操作,在开发过程中十分常见,Bottom Sheet 具体实现主要包含:BottomSheetBeahvior 、BottomSheetDialog、BottomSheetDialogFragment,这三个组件均可以实现半屏弹出效果,区别点在于接入和使用方式上的差异三个组件的概述。

m0_73986294的博客 4463

BottomSheetDialogFragment使用的注意点

最近重构项目,想把之前的一些控件替换成BottomSheetDialog。最后选用的是更加方便的BottomSheetDialogFragment。也遇到了很多坑,写出来分享一下。 1.BottomSheetDialogFragment背景圆角设置 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:

lyglostangel的专栏 3126

Android DialogFragment、BottomSheetDialogFragment的基本使用

在前面两篇我们介绍了Fragment的基本使用和Fragment配套ViewPager的使用,接下来我们就来看看除此之外其他的平时不常用但是我们很有必要掌握的其他的Fragment的基本使用。主要介绍的就是两种:DialogFragment和BottomSheetDialogFragment。 (一)DialogFragment DialogFragment看名字就知道是Dialog样式的Fragment,其推出的初衷就是为了解决传统Dialog无法与宿主的生命周期绑定导致需要后台时刻监听其动态变化,特别当

zhoufan11132的博客 2167

Android BottomSheetDialogFragment 使用详解,设置圆角、固定高度、默认全屏等

MD风格的底部弹窗,比自定义dialog或popupwindow使用更简单,功能也更强大。其实细分来说,是BottomSheet、BottomSheetDialog、BottomSheetDialogFragment。

赵彦军 9939

Android实现底部弹出对话框效果(附带源码)

Android实现底部弹出对话框效果(附带源码)

欢迎来到我的博客!这里是一个专注于计算机技术的分享平台,涵盖编程开发、算法研究、系统架构、软件工程等多个领域。无论你是初学者还是资深开发者,都能在这里找到有价值的内容。 1404

BottomSheetDialog 、DialogFragment 、BottomSheetDialogFragment二次封装及使用方法

这三种dialog,在Android 开发中经常会使用到,基本用法网络上也有很多,下面主要阐述一下我在项目中遇到的坑以及对应的解决办法 BottomSheetDialog issue : BottomSheetDialog 弹出时,阴影无法覆盖到状态栏,导致状态栏还是默认的背景色 处理方法: 在oncreate 的时候重新计算并设置window 窗口的高度 public class T3Botto...

weixin_43038028的博客 4021

关于安卓DialogFragment使用(二)

关于安卓底部dialogfragment封装

motosheep的博客 1466

Android底部弹窗实战:从DialogFragment到BottomSheetDialog的进阶指南

本文详细对比了Android底部弹窗的多种实现方式,重点解析了DialogFragment和BottomSheetDialog的实战应用与优势。BottomSheetDialog基于Material Design,提供开箱即用的手势交互和状态管理,是开发复杂底部弹窗的首选方案。文章还提供了全屏适配、动画优化及常见问题解决方案,助力开发者提升用户体验与开发效率。

rice5的博客 983

Android studio如何用BottomSheetDialog实现底部弹窗

因为必须要使用Dialog,使用上局限相对多,因此一般适用于底部弹出的轻交互弹窗,如底部说明弹窗等。BottomSheetDialogFragment 的使用同普通的Fragment一样,可以将交互和UI写到Fragment内,适合一些有简单交互的弹窗场景,如底部分享弹窗面板等。BottomSheetBeahvior 一般直接作用在view上,一般在xml布局文件中直接对view设置属性,轻量级、代码入侵低、灵活性高,适用于复杂页面下的半屏弹出效果。对BottomSheetDialog中控件实现监听事件。

weixin_73928886的博客 2158
上一篇: Android自定义弧型View
下一篇: android 表单信息提交与设计之美
AnalyzeSystem
博客等级 码龄11年 204粉丝 114原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值