欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2024-02-15 19:38:28
一、实现效果图 二、实现代码 1.自定义view package com.czhappy.showintroduce.view; import andr...

一、实现效果图

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

二、实现代码

1.自定义view

package com.czhappy.showintroduce.view;
import android.content.context;
import android.graphics.bitmap;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.paint;
import android.graphics.path;
import android.util.attributeset;
import android.view.view;
import android.widget.relativelayout;
/**
 * description: 水波纹动画引导view
 * user: chenzheng
 * date: 2017/1/14 0014
 * time: 18:01
 */
public class rippleintroview extends relativelayout implements runnable {
  private int mmaxradius = 70;
  private int minterval = 20;
  private int count = 0;
  private bitmap mcachebitmap;
  private paint mripplepaint;
  private paint mcirclepaint;
  private path marcpath;
  public rippleintroview(context context) {
    this(context, null);
  }
  public rippleintroview(context context, attributeset attrs) {
    this(context, attrs, 0);
  }
  public rippleintroview(context context, attributeset attrs, int defstyleattr) {
    super(context, attrs, defstyleattr);
    init();
  }
  private void init() {
    mripplepaint = new paint();
    mripplepaint.setantialias(true);
    mripplepaint.setstyle(paint.style.stroke);
    mripplepaint.setcolor(color.white);
    mripplepaint.setstrokewidth(2.f);
    mcirclepaint = new paint();
    mcirclepaint.setantialias(true);
    mcirclepaint.setstyle(paint.style.fill);
    mcirclepaint.setcolor(color.white);
    marcpath = new path();
  }
  /**
   * view大小变化时系统调用
   * @param w
   * @param h
   * @param oldw
   * @param oldh
   */
  @override
  protected void onsizechanged(int w, int h, int oldw, int oldh) {
    super.onsizechanged(w, h, oldw, oldh);
    if (mcachebitmap != null) {
      mcachebitmap.recycle();
      mcachebitmap = null;
    }
  }
  @override
  protected void ondraw(canvas canvas) {
    //获取加号图片view
    view mpluschild = getchildat(0);
    //获取提示图片view
    view mrefschild = getchildat(1);
    if (mpluschild == null || mrefschild == null) return;
    //获取加号图片大小
    final int pw = mpluschild.getwidth();
    final int ph = mpluschild.getheight();
    //获取提示图片大小
    final int fw = mrefschild.getwidth();
    final int fh = mrefschild.getheight();
    if (pw == 0 || ph == 0) return;
    //加号图片中心点坐标
    final float px = mpluschild.getx() + pw / 2;
    final float py = mpluschild.gety() + ph / 2;
    //提示图片左上角坐标
    final float fx = mrefschild.getx();
    final float fy = mrefschild.gety();
    final int rw = pw / 2;
    final int rh = ph / 2;
    if (mcachebitmap == null) {
      mcachebitmap = bitmap.createbitmap(getwidth(), getheight(), bitmap.config.argb_8888);
      canvas cv = new canvas(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);
    //保存画布当前的状态
    int save = canvas.save();
    for (int step = 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
  public void run() {
    //把run对象的引用从队列里拿出来,这样,他就不会执行了,但 run 没有销毁
    removecallbacks(this);
    count += 2;
    count %= minterval;
    invalidate();//重绘
  }
  /**
   * 销毁view时调用,收尾工作
   */
  @override
  protected void ondetachedfromwindow() {
    super.ondetachedfromwindow();
    if (mcachebitmap != null) {
      mcachebitmap.recycle();
      mcachebitmap = null;
    }
  }
}

2.mainactivity.java

package com.czhappy.showintroduce.activity;
import android.os.bundle;
import android.support.v7.app.appcompatactivity;
import android.view.view;
import android.view.viewgroup;
import com.czhappy.showintroduce.r;
public class mainactivity extends appcompatactivity {
  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);
    view view = findviewbyid(r.id.layout_ripple);
    view.setonclicklistener(new view.onclicklistener() {
      @override
      public void onclick(view v) {
        ((viewgroup) v.getparent()).removeview(v);
      }
    });
  }
}

3.activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<framelayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
  <textview
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="hello world!" />
  <com.czhappy.showintroduce.view.rippleintroview
    android:id="@+id/layout_ripple"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="true"
    android:fitssystemwindows="true"
    android:background="#aa000000">
    <imageview
      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"/>
    <imageview
      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"/>
  </com.czhappy.showintroduce.view.rippleintroview>
</framelayout>

以上所述是小编给大家介绍的android自定义view 实现水波纹动画引导效果,希望对大家有所帮助