美文网首页
2020-04-12

2020-04-12

作者: SmallWalnutBG | 来源:发表于2020-04-12 21:37 被阅读0次

Android 实现水波纹动效


WaterRippleView核心文件

package com.manss.myapplication.widget.animationimport android.content.Contextimport android.graphics.Canvasimport android.graphics.Colorimport android.graphics.Paintimport android.util.AttributeSetimport android.view.Viewimport com.manss.myapplication.widget.DisplayUtilimport java.util.*/** * 水波纹动画view */class WaterRippleView : View { private var mMaxWaveAreaRadius = 0f private var mWaveIntervalSize = 0f//波距 = 0f private var mStirStep = 0f // 波移动的步幅 = 0f private var mWidth = 0 private var mWaveStartWidth = 0f// px = 0f private var mWaveEndWidth = 0f// px 最大半径,超过波消失 = 0f private var mWaveColor = 0 /** * 颜色渐变控制器 */// private Interpolator interpolator = new CycleInterpolator(0.5f); private var mViewCenterX = 0f private var mViewCenterY = 0f private val rippleColor = Color.BLUE //波动属性设置 private val mWavePaint = Paint() //中心点属性设置 private val mWaveCenterShapePaint = Paint() private var mFillAllView = false private var mFillWaveSourceShapeRadius = 0f private val mWaves: MutableList<Wave?> = ArrayList() constructor(context: Context?, attrs: AttributeSet?) : super( context, attrs ) { init() } constructor(context: Context?) : super(context) { init() } private fun init() { setWaveInfo(2f, 1f, 2f, 15f, rippleColor) mWaveIntervalSize = DisplayUtil.dip2px(context, 20f).toFloat() mWidth = DisplayUtil.dip2px(context, 2f) //初始化波动最大半径 mWaveEndWidth = DisplayUtil.dip2px(context, 100f).toFloat() } override fun onLayout( changed: Boolean, left: Int, top: Int, right: Int, bottom: Int ) { super.onLayout(changed, left, top, right, bottom) mViewCenterX = width / 2.toFloat() mViewCenterY = height / 2.toFloat() var waveAreaRadius = mMaxWaveAreaRadius waveAreaRadius = if (mFillAllView) { Math.sqrt( (mViewCenterX * mViewCenterX + mViewCenterY * mViewCenterY).toDouble() ).toFloat() } else { Math.min(mViewCenterX, mViewCenterY) } if (mMaxWaveAreaRadius != waveAreaRadius) { mMaxWaveAreaRadius = waveAreaRadius resetWave() } } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) stir() for (w in mWaves) { mWavePaint.color = w!!.color mWavePaint.strokeWidth = mWidth.toFloat() mWavePaint.alpha = w.alpha canvas.drawCircle(mViewCenterX, mViewCenterY, w.radius, mWavePaint) } if (mFillWaveSourceShapeRadius > 0f) { canvas.drawCircle( mViewCenterX, mViewCenterY, mFillWaveSourceShapeRadius, mWaveCenterShapePaint ) } postInvalidateDelayed(FPS.toLong()) } /** * 波 * * @author sky */ internal inner class Wave { var radius = 0f var width = 0f var color = 0 var alpha = 0 fun reset() { radius = 0f width = mWaveStartWidth color = mWaveColor } override fun toString(): String { return ("Wave [radius=" + radius + ", width=" + width + ", color=" + color + "]") } init { reset() } } private var mLastRmoveWave: Wave? = null /** * 触发涌动传播 */ private fun stir() { val nearestWave = if (mWaves.isEmpty()) null else mWaves[0] if (nearestWave == null || nearestWave.radius >= mWaveIntervalSize) { var w: Wave? = null if (mLastRmoveWave != null) { w = mLastRmoveWave mLastRmoveWave = null w!!.reset() } else { w = Wave() } mWaves.add(0, w) } val waveWidthIncrease = mWaveEndWidth - mWaveStartWidth val size = mWaves.size for (i in 0 until size) { val w = mWaves[i] var rP = w!!.radius / mMaxWaveAreaRadius if (rP > 1f) { rP = 1f } w.width = mWaveStartWidth + rP * waveWidthIncrease w.radius += mStirStep w.color = rippleColor w.alpha = 255 / (i + 1) } val farthestWave = mWaves[size - 1] if (farthestWave!!.radius > mWaveEndWidth) { mWaves.removeAt(size - 1) } } /** * 如果true会选择view的最大的对角线作为活动半径 * * @param fillAllView */ fun setFillAllView(fillAllView: Boolean) { mFillAllView = fillAllView resetWave() } fun resetWave() { mWaves.clear() postInvalidate() } /** * 填充波形起源的中心点 * * @param radius 半径大小 */ fun setFillWaveSourceShapeRadius(radius: Float) { mFillWaveSourceShapeRadius = radius } /** * 设置波形属性 * * @param intervalSize 两个波形之间的间距 * @param stireStep 波形移动速度 * @param startWidth 起始波形宽度 * @param endWidth 终止波形宽度 * @param color 波形颜色 */ fun setWaveInfo( intervalSize: Float, stireStep: Float, startWidth: Float, endWidth: Float, color: Int ) { mWaveIntervalSize = intervalSize mStirStep = stireStep mWaveStartWidth = startWidth mWaveEndWidth = endWidth setWaveColor(color) resetWave() } /** * 设置波形颜色 * * @param color */ fun setWaveColor(color: Int) { mWaveColor = color mWaveCenterShapePaint.color = mWaveColor } companion object { private const val FPS = 1000 / 40 } init { mWavePaint.isAntiAlias = true mWavePaint.style = Paint.Style.FILL } init { mWaveCenterShapePaint.isAntiAlias = true mWaveCenterShapePaint.style = Paint.Style.FILL }}

util文件

packagecom.manss.myapplication.widget;importandroid.content.Context;publicclassDisplayUtil{publicstaticintdip2px(Context context,floatdipValue){finalfloatscale = context.getResources().getDisplayMetrics().density;return(int) (dipValue * scale +0.5f);    }}

activity_water_ripple_view.xml文件

<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:background="@android:color/white">        <com.manss.myapplication.widget.animation.WaterRippleView            android:id="@+id/activity_water_ripple_view"            android:layout_width="match_parent"            android:layout_height="match_parent" />    </RelativeLayout></androidx.constraintlayout.widget.ConstraintLayout>

方法调用

packagecom.example.myapplicationimportandroid.os.Bundleimportandroidx.appcompat.app.AppCompatActivityimportcom.manss.myapplication.Rimportcom.manss.myapplication.widget.DisplayUtilimportcom.manss.myapplication.widget.animation.WaterRippleView/*** 水波纹动画*/classWaterRippleActivity:AppCompatActivity(){overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)        setContentView(R.layout.activity_water)varwaterRipple: WaterRippleView = findViewById(R.id.activity_water_ripple_view)        waterRipple.setFillWaveSourceShapeRadius(DisplayUtil.dip2px(this,15f).toFloat())//        waterRipple.setFillAllView(true)//        waterRipple.setWaveColor(android.R.color.holo_blue_bright)}}


总结,如果波纹是线条效果,修改WaterRippleView文件的

init {        mWavePaint.isAntiAlias =truemWavePaint.style = Paint.Style.FILL    }

修改后

init {        mWavePaint.isAntiAlias =truemWavePaint.style = Paint.Style.STROKE    }

修改波纹半径

//初始化波动最大半径mWaveEndWidth = DisplayUtil.dip2px(context,100f).toFloat()

修改波纹颜色

privatevalrippleColor = Color.BLUE//波动属性设置

相关文章

  • 佛陀的证悟

    佛陀的证悟 三圣阳明文化书院 关注 6.959 · 字数 1634 · 阅读 594 2020-04-12 21:...

  • 读物-呼啸山庄

    书名:呼啸山庄 作者:艾米莉·勃朗特 阅读时长:2020-04-03 至 ~2020-04-12 一:打卡记录: ...

  • 怎么老是那么纠结——“三个我”

    2020-04-12 课上,Z君肚子饿了。 本我说:“你想饿死我吗?快去给我找吃的!” 超我说:”现在在上课,怎么...

  • 坚持打卡2020-04-11

    2020-04-11周六 学习-2-打卡-redis 运动-2-打卡-20min室内运动 2020-04-12周日

  • 【周总结】第八期第14周07号-醒

    2020-04-12 【本周计划/总结】 一、职业发展 本周好好学习,没有太多的简单事情,最近亲戚经常在家里,自己...

  • 《贫穷的本质》3

    Day27 2020-04-12 《简七:只需3赵,打造你的“万能财富池”》 【字数】 以前的社会求温饱,渐渐地奔...

  • 如果是去见你 我一定是跑着去的/跟同桌小聚

    2020-04-12 今天是休假。7:40几分也正常醒来了。起床的话,把自己的昨晚的衣服还有我的枕套都给洗了。 准...

  • 遇见NO.148

    2020-04-12 星期日 晴 遇见NO.148 前几天,在爱播者朗诵时,听到日记星球的一位同学朗读的内...

  • 2020-04-12

    2020-04-12 2020年4月12星期六【子湘妈读经典感恩日记第644篇】晴 读经方法:育心147累积法 读...

  • 父女关于“屁”的对话--宝贝成长记录11

    2020-04-12 lucky3岁4个月27天,很快就到3岁半啦 宝贝日常记录: 父女对话: 听到爸爸和女儿的对...

网友评论

      本文标题:2020-04-12

      本文链接:https://www.haomeiwen.com/subject/anhimhtx.html