一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Android自定义View实现水波纹动画引导效果

时间:2017-01-24 编辑:简简单单 来源:一聚教程网

一、实现效果图

这里写图片描述

二、实现代码

1.自定义view

 代码如下复制代码

packagecom.czhappy.showintroduce.view;

importandroid.content.Context;

importandroid.graphics.Bitmap;

importandroid.graphics.Canvas;

importandroid.graphics.Color;

importandroid.graphics.Paint;

importandroid.graphics.Path;

importandroid.util.AttributeSet;

importandroid.view.View;

importandroid.widget.RelativeLayout;

/**

 * Description: 水波纹动画引导view

 * User: chenzheng

 * Date: 2017/1/14 0014

 * Time: 18:01

 */

publicclassRippleIntroViewextendsRelativeLayoutimplementsRunnable {

  privateintmMaxRadius =70;

  privateintmInterval =20;

  privateintcount =0;

  privateBitmap mCacheBitmap;

  privatePaint mRipplePaint;

  privatePaint mCirclePaint;

  privatePath mArcPath;

  publicRippleIntroView(Context context) {

    this(context,null);

  }

  publicRippleIntroView(Context context, AttributeSet attrs) {

    this(context, attrs,0);

  }

  publicRippleIntroView(Context context, AttributeSet attrs,intdefStyleAttr) {

    super(context, attrs, defStyleAttr);

    init();

  }

  privatevoidinit() {

    mRipplePaint =newPaint();

    mRipplePaint.setAntiAlias(true);

    mRipplePaint.setStyle(Paint.Style.STROKE);

    mRipplePaint.setColor(Color.WHITE);

    mRipplePaint.setStrokeWidth(2.f);

    mCirclePaint =newPaint();

    mCirclePaint.setAntiAlias(true);

    mCirclePaint.setStyle(Paint.Style.FILL);

    mCirclePaint.setColor(Color.WHITE);

    mArcPath =newPath();

  }

  /**

   * view大小变化时系统调用

   * @param w

   * @param h

   * @param oldw

   * @param oldh

   */

  @Override

  protectedvoidonSizeChanged(intw,inth,intoldw,intoldh) {

    super.onSizeChanged(w, h, oldw, oldh);

    if(mCacheBitmap !=null) {

      mCacheBitmap.recycle();

      mCacheBitmap =null;

    }

  }

  @Override

  protectedvoidonDraw(Canvas canvas) {

    //获取加号图片view

    View mPlusChild = getChildAt(0);

    //获取提示图片view

    View mRefsChild = getChildAt(1);

    if(mPlusChild ==null|| mRefsChild ==null)return;

    //获取加号图片大小

    finalintpw = mPlusChild.getWidth();

    finalintph = mPlusChild.getHeight();

    //获取提示图片大小

    finalintfw = mRefsChild.getWidth();

    finalintfh = mRefsChild.getHeight();

    if(pw ==0|| ph ==0)return;

    //加号图片中心点坐标

    finalfloatpx = mPlusChild.getX() + pw /2;

    finalfloatpy = mPlusChild.getY() + ph /2;

    //提示图片左上角坐标

    finalfloatfx = mRefsChild.getX();

    finalfloatfy = mRefsChild.getY();

    finalintrw = pw /2;

    finalintrh = ph /2;

    if(mCacheBitmap ==null) {

      mCacheBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);

      Canvas cv =newCanvas(mCacheBitmap);

      super.onDraw(cv);

      //清空所有已经画过的path至原始状态

      mArcPath.reset();

      //起始轮廓点移至x,y坐标点,即加号图片正下方再往下20位置

      mArcPath.moveTo(px, py + rh + mInterval);

      //设置二次贝塞尔,实现平滑曲线,前两个参数为操作点坐标,后两个参数为结束点坐标

      mArcPath.quadTo(px, fy - mInterval, fx + fw *0.618f, fy - mInterval);

      //0~255,数值越小越透明

      mRipplePaint.setAlpha(255);

      cv.drawPath(mArcPath, mRipplePaint);

      //绘制半径为6的实心圆点

      cv.drawCircle(px, py + rh + mInterval,6, mCirclePaint);

    }

    //绘制背景图片

    canvas.drawBitmap(mCacheBitmap,0,0, mCirclePaint);

    //保存画布当前的状态

    intsave = canvas.save();

    for(intstep = count; step <= mMaxRadius; step += mInterval) {

      //step越大越靠外就越透明

      mRipplePaint.setAlpha(255* (mMaxRadius - step) / mMaxRadius);

      canvas.drawCircle(px, py, (float) (rw + step), mRipplePaint);

    }

    //恢复Canvas的状态

    canvas.restoreToCount(save);

    //延迟80毫秒后开始运行

    postDelayed(this,80);

  }

  @Override

  publicvoidrun() {

    //把run对象的引用从队列里拿出来,这样,他就不会执行了,但 run 没有销毁

    removeCallbacks(this);

    count +=2;

    count %= mInterval;

    invalidate();//重绘

  }

  /**

   * 销毁view时调用,收尾工作

   */

  @Override

  protectedvoidonDetachedFromWindow() {

    super.onDetachedFromWindow();

    if(mCacheBitmap !=null) {

      mCacheBitmap.recycle();

      mCacheBitmap =null;

    }

  }

}

2.MainActivity.Java

 

 

 代码如下复制代码

packagecom.czhappy.showintroduce.activity;

importandroid.os.Bundle;

importandroid.support.v7.app.AppCompatActivity;

importandroid.view.View;

importandroid.view.ViewGroup;

importcom.czhappy.showintroduce.R;

publicclassMainActivityextendsAppCompatActivity {

  @Override

  protectedvoidonCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    View view = findViewById(R.id.layout_ripple);

    view.setOnClickListener(newView.OnClickListener() {

      @Override

      publicvoidonClick(View v) {

        ((ViewGroup) v.getParent()).removeView(v);

      }

    });

  }

}

 

3.activity_main.xml

 

 代码如下复制代码

  android:layout_width="match_parent"

  android:layout_height="match_parent">

  

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:text="Hello World!"/>

  

    android:id="@+id/layout_ripple"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:clickable="true"

    android:fitsSystemWindows="true"

    android:background="#AA000000">

    

      android:id="@+id/iv_plus"

      android:layout_marginTop="36dp"

      android:src="@mipmap/ic_add"

      android:layout_alignParentRight="true"

      android:layout_marginRight="6dp"

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"/>

    

      android:src="@mipmap/tips_subscribe"

      android:id="@+id/tv_title"

      android:layout_below="@id/iv_plus"

      android:layout_marginTop="50dp"

      android:layout_alignParentRight="true"

      android:layout_marginRight="40dp"

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"/>

  

 

热门栏目