布局透明形状的view的做法

最近要弄一个透明的圆形的一个覆盖view,这个平时做应用的时候经常需要用到。如下图所示:

1.png

我想大多数人平时的用法就是要设计出一张这样的图片,这样简单省事,但是也有个难题就是这个图片是死的,中间部分的透明圆不能移动。
我整理了下面的三种方法,

一、就是上面说的用图片

这种方法就是图片是死的不方便移动。

二、就是自己画,(这种方式应该说是最简单了,还可以随心所欲的变动)

自定义一个透明背景的view,在view上画出一个圆

下面说实现

4.png

如果你需要一个半径为b的透明圆,实现如下
首先定义画笔Paint mPaint = new Paint();
然后定义你想要的颜色

mPaint.setAntiAlias(true);
mPaint.setColor(ContextCompat.getColor(context, R.color.jasper));
mPaint.setStyle(Paint.Style.STROKE);
复制代码

再定义你画笔的宽度mPaint.setStrokeWidth(a+b);
a是圆据顶部的高度,b是圆的半径,实际上就是这个画布高度的一半

重点来了

你如果就这么canvas.drawCircle(x, y, b, mPaint);画圆,那你得到的圆的大小肯定不对,这个时候圆的半径需要扩大,才能得到你想要的半径是b的圆,那怎么扩大呢?
实际上就是将半径的大小变为原本的半径大小加上画笔宽度的一半。即 raduis=b + (a+b)/2
然后canvas.drawCircle(x, y, raduis, mPaint);这样画出的圆的半径才是b。

这样做的好处是你想将圆画在哪里都可以,也可以是其他的任何形状。

三、也是画,这种方式复杂点

定义画笔将圆之外的部分画满,留下圆不画。那就是了,这需要用path实现。
首先一样是定义画笔

val mPaint = Paint()
mPaint.isAntiAlias = true
mPaint.color = ContextCompat.getColor(context!!, R.color.colorWhite)
mPaint.style = Paint.Style.FILL
mPaint.strokeWidth = 5f
复制代码

随后开始画,例如我的圆心在宽度的中间,

mPath.moveTo(getDisplayWidth() / 2 - mRadius, mMarginTop + mRadius)//第一个点在圆心左侧的边缘
mPath.lineTo(0F, mMarginTop + mRadius)//第二个点横移到最左侧
mPath.lineTo(0F, 0F)//第三个点到屏幕左上角
mPath.lineTo((getDisplayWidth() / 2).toFloat(), 0F)//第四个点到圆心的正上方,屏幕的最顶端
mPath.lineTo((getDisplayWidth() / 2).toFloat(), mMarginTop.toFloat())//第五个点圆心上方,圆的边缘
mPath.cubicTo((getDisplayWidth() / 2).toFloat(), mMarginTop.toFloat(),
            getDisplayWidth() / 2 - mRadius, mMarginTop.toFloat(),
            getDisplayWidth() / 2 - mRadius,
            mMarginTop + mRadius
        )//利用贝塞尔曲线来画半圆
canvas?.drawPath(mPath, mPaint)
复制代码

画出来的效果

5.png

总共要画四个这样的部分,其实画出来后也不是那么圆,还是要在变化在画上一个稍微宽一点的圆,这比较麻烦,建议使用第二种。

四、其实还有一种方法,但是这种方法对布局有要求,有缺陷下面会讲

比如我上一篇 一个非常好用的页面引导工具guideView
这里面就是画的一个透明的图形。
首先是定义画笔

mPaint.isAntiAlias = true
mPaint.style = Paint.Style.FILL_AND_STROKE
mPaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
复制代码

然后直接画出一想要的形状即可canvas?.drawCircle(x,y,mRaduis,mPaint)
你还可以定义一个半透明的背景 setBackgroundColor(ContextCompat.getColor(context!!, R.color.translucence))

这样定义出来的view直接就有那个效果。但是这个view我直接放在layout中是不行的画出来的是一个黑色不透明的图形,只有将这个view放在popupwindow或者dialog中时起作用。(这里目前我也不知道为什么,我尝试将所有的activity都变成透明的背景,但还是一样都是不起作用)

我想上面三种方法已经够用了,晚点我打成一个库,可以通过设置padding、margin、半径、或者图形选择来画出任何位置的任何图形的透明图片,现在没时间,有个项目正在催。

好了,今天就到这里。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享