手把手教你画一个 逼格满满圆形水波纹loadingview Android

才没有完结呢o( ̄︶ ̄)n 。大家好,这里是番外篇。

拜读了爱哥的博客,又学到不少东西。爱哥曾经说过: 要站在巨人的丁丁上。 那么今天,我们就站在爱哥的丁丁上来学习制作一款自定义view(开个玩笑,爱哥看到别打我)。

转载请注明出处:http://blog.csdn.net/wingichoy/article/details/50523713

上一篇 带领大家做了一款炫酷的loading动画view 手把手带你做一个超炫酷loading成功动画view  不知道大家跟着做了一遍没有呢?

在开始之前,首先来说说预备知识,这些知识在爱哥的博客上都有详细的介绍:点我进入爱哥自定义view系列

效果图如下:  应用场景很多。。比如。。。内存占用百分比之类的

预备的知识有:

1.贝塞尔曲线    如果你不了解,可以来这里进行基础知识储备:神奇的贝塞尔曲线

2.Paint.setXfermode()  以及PorterDuffXfermode

千万不要被这个b的名字吓到,不熟悉看到可能会认为很难记,其实 只要站在巨人的丁丁上 还是很简单的。

好了 废话不多说 ,跟我一步步来做一个炫酷的view吧。

首先给一些属性,在构造器里初始化(不要再ondraw new东西不要再ondraw new东西不要再ondraw new东西不要再ondraw new东西)

    //绘制波纹
    private Paint mWavePaint;

    

    private PorterDuffXfermode mMode = new PorterDuffXfermode(PorterDuff.Mode.XOR);//设置mode 为XOR
    //绘制圆
    private Paint mCirclePaint;
    private Canvas mCanvas;//我们自己的画布
    private Bitmap mBitmap;
    private int mWidth;
    private int mHeight;

    public WaveLoadingView(Context context) {
        this(context,null);
    }

    public WaveLoadingView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public WaveLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        mWavePaint = new Paint();
        mWavePaint.setColor(Color.parseColor("#33b5e5"));
        mCirclePaint = new Paint();
        mCirclePaint.setColor(Color.parseColor("#99cc00"));

    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        if (widthMode == MeasureSpec.EXACTLY) {
            mWidth = widthSize;
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            mHeight = heightSize;
        }
        setMeasuredDimension(mWidth, mHeight);
        mBitmap = Bitmap.createBitmap(300,300, Bitmap.Config.ARGB_8888); //生成一个bitmap
        mCanvas = new Canvas(mBitmap);//讲bitmp放在我们自己的画布上,实际上mCanvas.draw的时候 改变的是这个bitmap对象
    }

然后,我们给他绘制一点东西,用来介绍PorterDuffXfermode

@Override
    protected void onDraw(Canvas canvas) {
        mCanvas.drawCircle(100,100,50,mCirclePaint);

        mCanvas.drawRect(100,100,200,200,mWavePaint);
        canvas.drawBitmap(mBitmap,0,0,null);
        super.onDraw(canvas);
    }

嗯,可以看到 是我们现在自己的画布上铺了一个bitmap(这里可以理解canvas为桌子  bitmap为画纸,我们在bimap上画画), 然后在bitmap上画了 一个圆,和一个矩形。最后把我们的mBitmap画到系统的画布上(显示到屏幕上),得到了以下效果。

然后我们用setXfermode()方法给他设置一个mode,这里设置XOR。

可以发现! 相交的地方消失了! 是不是很神奇。

在改一个mode 试试

    private PorterDuffXfermode mMode = new PorterDuffXfermode(PorterDuff.Mode.DST_OVER);

可以看到 圆形跑到了矩形上面来。  然后巨人给我们总结各个模式如了下图,这里给一个说明dst为先画的 src为后画的:.

大家可以根据这个规律试一下。

现在,我们把圆和矩形重叠。模式去掉。

 protected void onDraw(Canvas canvas) {

        //dst
        mCanvas.drawCircle(150,150,50,mCirclePaint);

//        mWavePaint.setXfermode(mMode);
        //src
        mCanvas.drawRect(100,100,200,200,mWavePaint);
        canvas.drawBitmap(mBitmap,0,0,null);
        super.onDraw(canvas);
    }

运行是这样的。

日了狗了!!我的圆怎么没了。。  其实圆是被覆盖掉了。 然后我们想实现一个效果,就是在圆的范围内,显示矩形的内容,该怎么做呢。自己照着图找找吧哈哈。

--------------------------------------------回归正题------------------------------------

我们要实现的是一个圆形的水波纹那种loadingview。。首要就是实现这个水波纹。

这时候贝塞尔曲线就派上用场了。这里采用三阶贝塞尔, 不停地改变X 模拟水波效果。

 if (x > 50) {
            isLeft = true;
        } else if (x < 0) {
            isLeft = false;
        }
<span style="white-space:pre">		</span>if (y > -50) {  //大于-50是因为辅助点是50  为了让他充满整个屏幕
            y--;
        }        if (isLeft) {
            x = x - 1;
        } else {
            x = x + 1;
        }
        mPath.reset();
        mPath.moveTo(0,  y);
        mPath.cubicTo(100 + x*2, 50 + y, 100 + x*2, y-50, mWidth, y);//前两个参数是辅助点
        mPath.lineTo(mWidth, mHeight);//充满整个画布
        mPath.lineTo(0, mHeight);//充满整个画布
        mPath.close();

之后用mCanvas来绘制这个bitmap,要注意的是 绘制之前要清空mBitmap,不然path会重叠

        mBitmap.eraseColor(Color.parseColor("#00000000"));

        //dst
         mCanvas.drawPath(mPath, mPaint);
 canvas.drawBitmap(mBitmap, 0, 0, null);

        postInvalidateDelayed(10);

在最上面动态改变Y  通知重绘,现在的效果是这样的

哈,水波效果出来了。   接着想办法让他画到一个圆形中。 首先绘制一个圆

 mCanvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, mSRCPaint);

额。。有点海上日出的感觉(看太阳都是绿色!)

现在让我们回到刚才的问题,如何在dst的范围内绘制src呢。。。答案是。。SRC_IN 你找对了吗。添加模式

  //dst
        mCanvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, mSRCPaint);

        mPaint.setXfermode(mMode);
        //src
        mCanvas.drawPath(mPath, mPaint);

        canvas.drawBitmap(mBitmap, 0, 0, null);

运行 效果如下:

咦 哈哈哈,是不是有点感觉了。如果不这样做 就需要考虑好多问题。动态计算沿着圆弧x,y坐标  计算arcTo的范围(我已经算出来了。。有兴趣的可以提。。没兴趣的话我就不写了。。)

完善一下,添加一个percent来代表进度,让y来根据percent动态改变

 y = (int) ((1-mPercent /100f) *mHeight);

添加setPercent方法

public void setPercent(int percent){
        mPercent = percent;
    }

画上百分比的文字。

 String str = mPercent + "%";
        float txtLength = mTextPaint.measureText(str);
        canvas.drawText(mPercent + "%", mWidth / 2-txtLength/2, mHeight / 2, mTextPaint);

然后配合seekBar。 效果如下:

最后改改字体大小  画笔透明度。 添加个背景图 就成了效果图上的效果。

本项目地址:点击打开链接   求star

如果你觉得本博客还可以,那么求关注,点个顶,评个论咯。。以后还会有更多的文章等着你~

时间: 2024-10-12 10:23:14

手把手教你画一个 逼格满满圆形水波纹loadingview Android的相关文章

手把手教你打造一个Material Design风格的App(二)

--接上文. 3.1添加ToolBar(ActionBar) 添加ToolBar非常简单,你需要做的仅仅是为toolbar创建一个单独的layout布局,如果你想在哪里展示toolbar,只要在对应布局里将toolbar的布局文件include进来即可. (8)在res-->layout文件夹下创建一个名为toolbar.xml的文件,然后在里面添加一个android.support.v7.widget.Toolbar元素,这样就创建了一个具有特定高度和主题的toolbar. toolbar.x

手把手教你打造一个Material Design风格的App(三)

--接上文. 3.2添加抽屉导航 添加导航抽屉跟Android 5.0之前是一样的,只是以前我们使用ListView来作为菜单容器,现在我们则使用Material Design风格的RecyclerView. (14)在你工程的java文件夹中,创建3个名为activity.adapter.model的包,将MainActivity.java移到activtiy包中,这样做使得你的代码可以很好地组织和管理. (15)打开位于app模块下的build.gradle文件并添加如下依赖.添加完依赖之后

手把手教你打造一个Material Design风格的App(一)

你应该听说过Android的Material Design,它是在Android 5.0(Lollipop)版本引入的.在Material Design中还引入了很多新东西,比如Material Theme,新的小部件,自定义的阴影,矢量图片及自定义动画等.如果你之前没有用过Material Design,那么本文将是一个很好的入门教程. 在这篇教程中,我们将会学习Material Design开发的基本步骤,即编写自定义的主题以及使用RecyclerView来实现抽屉导航. 通过下面的两个链接

手把手教你画AndroidK线分时图及指标

先废话一下:来到公司之前,项目是由外包公司做的,面试初,没有接触过分时图k线这块,觉得好难,我能搞定不!但是一段时间之后,发现之前做的那是一片稀烂,但是这货是主功能啊,迟早的自己操刀,痛下决心,开搞,本想用开源控件,但是想自己实现一下:接着有了本文 开始用surfaceview,但是这货在上下滑动的时候会出现黑边,这个问题我也是纠结了好久,想想产品肯定会打回,打回了还丢脸,算了没多少东西就用view吧,废话真tm多,开始吧. 1,创建项目(Android studio) 2,对了,先上个效果图吧

手把手带你画一个动态错误提示 Android自定义view

嗯..再差1篇就可以获得持之以恒徽章了,今天带大家画一个比较简单的view. 转载请注明出处:http://blog.csdn.net/wingichoy/article/details/50477108 废话不多说,看效果图: 首先 构造函数 测量... 这里就一笔带过了. public ErrorView(Context context) { this(context, null); } public ErrorView(Context context, AttributeSet attrs

手把手带你画一个漂亮蜂窝view Android自定义view

上一篇做了一个水波纹view  不知道大家有没有动手试试呢点击打开链接 这个效果做起来好像没什么意义,如果不加监听回调 图片就能直接替代.写这篇博客的目的是锻炼一下思维能力,以更好的面多各种自定义view需求. 转载请注明出处:http://blog.csdn.net/wingichoy/article/details/50554058 本文是和代码同步写的.也就是说在写文章的时候才敲的代码.这样会显得文章有些许混乱.但是我想这样记录下来,一个自定义view的真正的制作过程,是一点一点,一步步跟

手把手带你画一个 时尚仪表盘 Android 自己定义View

拿到美工效果图.咱们程序猿就得画得一模一样. 为了不被老板喷,仅仅能多练啊. 听说你认为前面几篇都so easy,那今天就带你做个相对照较复杂的. 转载请注明出处:http://blog.csdn.net/wingichoy/article/details/50468674 注意:每一篇博客都是建立在之前博客的基础知识上的,假设你刚接触自己定义view.能够来说说自己定义view简单学习的方式这里看我曾经的文章.记录了我学习自己定义view的过程,并且前几篇博客或多或少犯了一些错误(反复绘制,o

恭喜发财! -- 手把手教你仿造一个qq下拉抢红包 Android自定义view

猴年猴赛雷啊各位,今天没吃药我感觉自己萌萌哒! qq和微信和支付宝红包大战,不知道各位的战绩是多少嘞? 反正我qq抢到的都是气泡.因为太不爽,所以自己写一个下拉抢红包自己玩(自己跟自己玩). 先来看效果图.这个-- 呃~~ -__-" ..有点丑 是低仿. 转载请注明出处:http://blog.csdn.net/wingichoy/article/details/50662592 学习完本篇博客你能获得到的知识 正确的获得view的大小 listview的下拉header 自定义字体 自己添加

手把手教你打造一个心电图效果View Android自定义View

大家好,看我像不像蘑菇-因为我在学校呆的发霉了. 思而不学则殆 丽丽说得对,我有奇怪的疑问,大都是思而不学造成的,在我书读不够的情况下想太多,大多等于白想,所以革命没成功,同志仍需努力. 好了废话不说了,由于布总要做一个心电图的玩意,所以做来练练手,总之拿到的UI图如下: 做好的效果如下: 拿到图,先做一些简单的分析.呃.. 背景表格的绘制 心电图的绘制 背景表格的绘制: 首先drawColor黑色,然后用循环来画线. 心电图的绘制: 看样子是path,应该没问题. 于是就大干一番,按照这俩步骤