安卓给相对布局RelativeLayout增加一个通用遮罩层

效果图

解决方案

  • 关键代码
    对RelativeLayout增加一个函数扩展
/**
 * 针对RelativeLayout,显示或隐藏一个遮罩层
 * shouldShow:是否显示遮罩层
 * maskColor:遮罩层颜色
 */
fun RelativeLayout.showMaskLayer(shouldShow: Boolean = true, maskColor: String = "#80F6BCC4") {
    val maskViewTag = "MASK_VIEW_TAG"
    var maskView = findViewWithTag<View>(maskViewTag)
    if (shouldShow) {
        if (maskView == null) {
            maskView = View(context)
            maskView.tag = maskViewTag
            //设置遮罩层颜色
            maskView.setBackgroundColor(Color.parseColor(maskColor))
            //屏蔽点击事件
            maskView.setOnClickListener { }
            addView(this, maskView)
        }
    } else {
        maskView?.let { removeView(it) }
    }
}

fun RelativeLayout.showGradientMaskLayer(shouldShow: Boolean = true) {
    val maskViewTag = "MASK_VIEW_TAG"
    var maskView = findViewWithTag<View>(maskViewTag)
    if (shouldShow) {
        if (maskView == null) {
            maskView = View(context)
            maskView.tag = maskViewTag
            //设置遮罩层颜色
            setGradientBackground(context, maskView)
            //屏蔽点击事件
            maskView.setOnClickListener { }
            addView(this, maskView)
        }
    } else {
        maskView?.let { removeView(it) }
    }
}

private fun setGradientBackground(context: Context, view: View) {
    val colors = intArrayOf(
        ContextCompat.getColor(context, R.color.gradientStartColor),
        ContextCompat.getColor(context, R.color.gradientCenterColor),
        ContextCompat.getColor(context, R.color.gradientEndColor)
    )
    val g = GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, colors)
    view.background = g
}

/**
 * 动态添加遮罩层view。
 * 通过调用viewTreeObserver的addOnPreDrawListener方法,可以在视图绘制前进行添加。
 * 因为此时视图已经经过了onMeasure,知道了自己的宽高。
 */
private fun addView(viewGroup: ViewGroup, maskView: View?) {
    viewGroup.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
        override fun onPreDraw(): Boolean {
            viewGroup.viewTreeObserver.removeOnPreDrawListener(this)
            viewGroup.addView(maskView, viewGroup.width, viewGroup.height)
            return true
        }
    })
}
  • 使用样例
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        relativeLayout1.showMaskLayer(true)
    }
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/relativeLayout1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="文字纯色遮罩"
            android:textSize="40dp" />
    </RelativeLayout>

</LinearLayout>

完整源代码

https://gitee.com/cxyzy1/maskLayer

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值