Android自定义View实现水波纹引导动画
程序员文章站
2024-02-16 23:32:22
一、实现效果图
关于贝塞尔曲线
二、实现代码
1.自定义view
package com.czhappy.showintroduce.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>
三、源码下载
http://xiazai.jb51.net/201701/yuanma/androidshowintroduce(jb51.net).rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 字体图标