自定义View学习之锯齿波纹效果

xiaoxiao2021-02-28  66

工作太久都忘记了学习,落下了很多基础而又实用的东西,尤其在自定义View这块,每每提及都惶恐不已,在我家小棉袄的鞭策之下,痛定思痛,拿起手中之笔,开启了我的学习之旅。

在网上看到一篇自定义View的文章,以此为基准来学习了自定义View中结合Path和drawArc来实现锯齿波纹效果。 先上一张效果图

看图先来分析下整个View的组成部分,其实很简单 - 中间是一个矩阵 - 锯齿状的两侧可以通过Path来绘制 - 圆形波纹效果可以通过画扇形的方式来绘制

接下来我正式开始绘制 - 1.老规矩,先在values目录下新建一个attr.xml文件,定义几个属性,如下:

<declare-styleable name="WaveView"> <!--波浪的总个数--> <attr name="waveCount" format="integer" /> <!--波浪的宽度--> <attr name="waveWidth" format="integer" />/ <attr name="waveMode" format="integer"> <enum name="circle" value="1" /> <enum name="triangle" value="0" /> </attr> <attr name="waveColor" format="color" /> </declare-styleable> 2.在代码中获取自定属性,就不贴出代码了3.在onMeasure()方法中测量出View的大小,计算出矩阵的大小 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //测量宽度 int specMode = MeasureSpec.getMode(widthMeasureSpec); int specSize = MeasureSpec.getSize(widthMeasureSpec); if (specMode == MeasureSpec.EXACTLY) { mWidth = specSize; } else { if (specMode == MeasureSpec.AT_MOST) { //如果设置为wrap_content就默认给它一个值 mWidth = 600; } } specMode = MeasureSpec.getMode(heightMeasureSpec); specSize = MeasureSpec.getSize(heightMeasureSpec); if (specMode == MeasureSpec.EXACTLY) { mHeight = specSize; } else { if (specMode == MeasureSpec.AT_MOST) { //如果设置为wrap_content就默认给它一个值 mHeight = 550; } } //矩阵的宽高为View宽度的0.7倍 mRectWidth = (float) ((mWidth - getPaddingLeft() - getPaddingRight()) * 0.7); mRectHeight = (float) ((mHeight - getPaddingLeft() - getPaddingRight()) * 0.7); //计算出每个波浪的高度,这样保证波浪与view两边你的绝对融合 mWaveHeight = mRectHeight / mWaveCount; //计算出矩阵的位置让它显示在View的中间 left = (mWidth - mRectWidth) / 2; top = (mHeight - mRectHeight) / 2; right = (mWidth - mRectWidth) / 2 + mRectWidth; bottom = (mHeight - mRectHeight) / 2 + mRectHeight; mRectF = new RectF(left, top, right, bottom); setMeasuredDimension(mWidth, mHeight); } 4.绘制

通过改变Path的坐标来绘制尖角的图形

//尖角型的 float startX = left; float startY = top; mPath.moveTo(startX, startY); for (int i = 0; i < mWaveCount; i++) { //先画左边 mPath.lineTo(startX - mWaveWidth, startY + mWaveHeight / 2 + i * mWaveHeight); mPath.lineTo(startX, startY + (i + 1) * mWaveHeight); } canvas.drawPath(mPath, mPaint); startX = left + mRectWidth; mPath.moveTo(startX, startY); for (int i = 0; i < mWaveCount; i++) { //再右边 mPath.lineTo(startX + mWaveWidth, startY + mWaveHeight / 2 + i * mWaveHeight); mPath.lineTo(startX, startY + (i + 1) * mWaveHeight); } canvas.drawPath(mPath, mPaint);

通过drawArc来绘制波浪型的

//圆角型的 for (int i = 0; i < mWaveCount; i++) { RectF mWaveRectF = new RectF(left - mWaveWidth / 2, top + i * mWaveHeight, left + mWaveWidth / 2, top + (i + 1) * mWaveHeight); canvas.drawArc(mWaveRectF, 90, 180, true, mPaint); } for (int i = 0; i < mWaveCount; i++) { RectF mWaveRectF = new RectF(left + mRectWidth - mWaveWidth / 2, top + i * mWaveHeight, left + mRectWidth + mWaveWidth / 2, top + (i + 1) * mWaveHeight); canvas.drawArc(mWaveRectF, 270, 180, true, mPaint); }

这些都是比较简单的自定义View主要目的在于学会使用canvas提供的方法来达到我们想要的效果。 附送源码地址:https://github.com/wutq/WaveView/

转载请注明原文地址: https://www.6miu.com/read-79598.html

最新回复(0)