PopUpWindow显示在控件之上(动态测量PopUpWindow高度)

在开发中可能会遇到这样的需求,需要弹窗展示在某个控件之上,如下:

很多人第一时间会想到使用PopUpWindow实现弹窗显示,使用其ShowAsDropDown(acheorView,0,y)方法实现,设置y的值为某个固定值就能实现,但是这种方法太过于粗暴,且无法适配其他页面的调用,下面介绍一种可适配不同大小的PopWindow显示在控件之上的方法:

方案:使用PopUpWindow中的ShowAsDropDown方法,测量出PopUpWindow高度和控件高度可完美实现展示在控件之上。

一、控件高度测量:

/**
 * 计算出参考View的高度
 * @param  anchorView  参考view对象
 * @return 参考View的高度
 */
private fun calculateViewHeight(anchorView: View): Int {
    return anchorView.bottom - anchorView.top
}

二、测量PopUpWIndow高度:

注意点:

1、因PopUpWindow还未展示,需使用PopUpWindow.contentView.measureHeight方式测量出其高度

2、 为适配不同布局的高度测量,根据popupWindow的宽度来选择PopUpWindow的测量模式

3、若popupWindow的宽度为WRAP_CONTENT,测量会存在偏差。因此需要设置PopUpWindow的宽度为屏幕宽度的一半,测试模式为精准测量(MeasureSpc.EXACTLY),MeasureSpc.EXACTLY ,UNSPECIFILD ,AT_MOST的使用方式可参照:

/**
 * 计算出PopUpWindow显示的高度
 * @param context Context
 * @param  popupWindow  PopupWindow对象
 * @return PopUpWindow的高度
 */
private fun calculatePopWindowHeight(context: Context, popupWindow: PopupWindow): Int {
    
    val screenWidth = context.resources.displayMetrics.widthPixels
    //若popupWindow高度已被定义,可直接返回
    if(popupWindow.height>0){
        return popupWindow.height
    }
    val popupWindowWidth = popupWindow.width
    //根据popupWindow的宽度来选择PopUpWindow的测量模式
    val measureWidthParams = when {
        popupWindowWidth > 0 -> {
            View.MeasureSpec.makeMeasureSpec(popupWindowWidth, View.MeasureSpec.EXACTLY)
        }
        popupWindowWidth == WindowManager.LayoutParams.MATCH_PARENT -> {
            View.MeasureSpec.makeMeasureSpec(screenWidth, View.MeasureSpec.EXACTLY)
        }
        popupWindowWidth == WindowManager.LayoutParams.WRAP_CONTENT -> {
            //若popupWindow的宽度为WRAP_CONTENT,测量会存在偏差。因此需要设置PopUpWindow的宽度为屏幕宽度的一半,测试模式为精准测量
            popupWindow.width = screenWidth / 2
            View.MeasureSpec.makeMeasureSpec(screenWidth / 2, View.MeasureSpec.EXACTLY)
        }
        else -> 0
    }
    popupWindow.contentView.measure(measureWidthParams, View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED))
    return popupWindow.contentView.measuredHeight
}

三、定义PopUpWindow扩展函数实现显示PopUpWindow在参考布局之上

/**
 * 显示PopUpWindow在参考布局之上
 * @param context Context
 * @param anchorView 参考布局
 */

fun PopupWindow.showAsAbove(context: Context, anchorView: View?) {
    val popupWindowHeight = calculatePopWindowHeight(context, this)
    val anchorViewHeight = if (anchorView == null) 0 else calculateViewHeight(anchorView)
    //实际需要偏移的高度为参考view的高度加上PopUpWindow的高度
    val yOffset = -(popupWindowHeight + anchorViewHeight)
    this.showAsDropDown(anchorView, 0, yOffset)
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值