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

来源:互联网 发布:长沙百度快照优化 编辑:程序博客网 时间:2024/06/05 11:33

工作太久都忘记了学习,落下了很多基础而又实用的东西,尤其在自定义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/

原创粉丝点击