zoukankan      html  css  js  c++  java
  • (Android自定义View)来来来,一起再撸一个Material风格loadingView。

    本文同步自博主的个人博客wing的地方酒馆
    很久很久以前,撸了一款loadingview(点击这里回顾),当时觉得还不错,现在看看觉得好丑啊!!! 于是想再撸一个,无意间在这里看到一个很不错的效果,于是手痒了,就想动动手,算起来,也有很久没有写过View了。

    效果图

    这里写图片描述

    哈,可能又是我自我感觉良好,觉得效果还不错,不过没准再过半年我又嫌弃之前的自己了 哈哈哈。

    还有呢,如果你看这篇比较吃力,推荐先去看看我之前学view的时候写的一些博客,难度是一点一点增加的。
    简单说说自定义view的学习方式

    实现思路

    看到效果,首先要分析,这里主要是什么组成的。

    首先呐,肯定要画两个圆圈,对吧? 不要告诉我你不会画圆。如果不会,请看上面的链接。

    private void drawCircle(Canvas canvas, float present) {
        canvas.drawCircle(mWidth / 2, mHeight / 2 -mMaxOffset, mMaxRadius, mPaint);
        canvas.drawCircle(mWidth / 2, mHeight / 2 + mMaxOffset, mMaxRadius, mPaint);
      }
    

    这里写图片描述

    然后想办法让圈圈转起来,怎么转起来呢,肯定是rotate方法了~~这里提供一个角度参数,让他自增,如果到360呢,就让他等于0,然后invalidate(),就可以实现圈圈转动的效果。

    
        canvas.rotate(mDegrees += 3, mWidth / 2, mHeight / 2);
        if (mDegrees == 360) {
          mDegrees = 0;
        }
        invalidate();

    这里写图片描述
    恩。。已经转起来了。

    接下来要想办法让两个小圆在转圈的过程中靠近,再远离,怎么实现呢?注意上面让小圆有间隔的mMaxOffset!我们可以根据旋转的百分比来动态改变这个offset!
    所以,要改一下drawCircle()代码

    float present = mDegrees / 360;
        if (present < 0.5) {
          mOffset = mMaxOffset * present;
        } else {
          mOffset = mMaxOffset * (1 - present);
      }
    
      private void drawCircle(Canvas canvas) {
    
        canvas.drawCircle(mWidth / 2, mHeight / 2 - mOffset, mMaxRadius, mPaint);
        canvas.drawCircle(mWidth / 2, mHeight / 2 + mOffset, mMaxRadius, mPaint);
      }

    现在是这样,恩..已经有点效果了。

    这里写图片描述

    那小圈靠近的时候,粘合动画怎么做?还记得qq消息点去除吗?跟那个道理一样!!! 就是画一个贝塞尔的path。坐标计算思路在模仿qq消息去除效果 这里思路是一样的,只不过微调了辅助点坐标。直接上代码:

     if (present <= 0.37 || present >= 0.63) drawPath(canvas, present);
    
     private void drawPath(Canvas canvas, float present) {
        mPath.reset();
        mPath.moveTo(mWidth / 2 - mMaxRadius, mHeight / 2 - mOffset);
        mPath.lineTo(mWidth / 2 + mMaxRadius, mHeight / 2 - mOffset);
    
        float supportOffset = -30;
    
        if (present < 0.25) { //两个球相交
          supportOffset = 30;
        } else if (present >= 0.25 && present < 0.375f) {
          Log.e("present", present + "");
          supportOffset = -(480 * present - 150f);
        } else if (present > 0.625) {   //开始缩小
    
          supportOffset = (480 * present - 330f);
          if (present > 0.75) {  //两个球开始相交
            supportOffset = 30;
          }
          //supportOffset = 30;
        }
    
        Log.e("wing", supportOffset + "");
    
        mPath.quadTo(mWidth / 2 + supportOffset, mHeight / 2, mWidth / 2 + mMaxRadius,
            mHeight / 2 + mOffset);
        mPath.lineTo(mWidth / 2 - mMaxRadius, mHeight / 2 + mOffset);
        mPath.quadTo(mWidth / 2 - supportOffset, mHeight / 2, mWidth / 2 - mMaxRadius,
            mHeight / 2 - mOffset);
        mPath.close();
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawPath(mPath, mPaint);
      }

    有一点值得注意的是,辅助点偏移坐标和percent的关系。以 supportOffset = -(480 * present - 150f);作为说明。这个方程式怎么得出出来的呢。 因为我想让百分比从0.25->0.375变化,而辅助点坐标从-30->30变化,所以是一个简单的初中数学中的线性方程。将k和b带入 y = kx +b 即可轻易得出。

    之后在根据percent控制path的显隐,即可实现最上效果图的效果。

    如果你感兴趣,可以下载源码研究下~~当然,如果觉得赞,点个star是对我最大的支持~

    https://github.com/githubwing/LoadingView

  • 相关阅读:
    《DSP using MATLAB》Problem 6.17
    一些老物件
    《DSP using MATLAB》Problem 6.16
    《DSP using MATLAB》Problem 6.15
    《DSP using MATLAB》Problem 6.14
    《DSP using MATLAB》Problem 6.13
    《DSP using MATLAB》Problem 6.12
    《DSP using MATLAB》Problem 6.11
    P1414 又是毕业季II
    Trie树
  • 原文地址:https://www.cnblogs.com/muyuge/p/6333512.html
Copyright © 2011-2022 走看看