Android实现水波纹扩散效果

本文实例为大家分享了Android实现水波纹扩散效果的具体代码,供大家参考,具体内容如下

先上图

囧!没有图片所以就拿了小安代替了。

先看一下如何使用这个View。

<jianpan.com.mybutton.view.RippleDiffuse
 android:layout_width="200dp"
 android:layout_height="200dp"
 app:btn_img_res="@drawable/rd"
 app:ripple_img_res="@drawable/rd">
</jianpan.com.mybutton.view.RippleDiffuse>

是的,没有别的代码了,就这么简单

实现思路

自定义ViewGroup,创建一个用显示图片的view,在创建几个,大小相同的ImageView。当按下时,对这几个ImageView进行放大和渐变。

代码

首先它肯定是一个正方形。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 super.onMeasure(widthMeasureSpec, widthMeasureSpec);
 if (!mInitDataSucceed){
 initData();
 }
}

显示图片的View的大小,该怎么给?这是个比较蛋疼的问题。给大了就看不到扩散效果了,给小,给多少的值合适呢?有没有正好的值,有的用父 view 的 size / 子 view 放大的倍数,这样肯定会达到理想的效果。

private static final int ANIMATION_EACH_OFFSET = 800; // 每个动画的播放时间间隔
private static final int RIPPLE_VIEW_COUNT = 3;//波纹view的个数
private static final float DEFAULT_SCALE = 1.6f;//波纹放大后的大小

//点击有扩散效果的view
private CircleImageView mBtnImg;
private int mBtnViewHeight;
private int mBtnViewWidth;
private float mScale = DEFAULT_SCALE;
//图片资源
private int mBtnImgRes;
private int mRippleRes;
//是否初始化完成
private boolean mInitDataSucceed = false;

private void initData(){
 if (getMeasuredHeight() > 0 && getMeasuredWidth() > 0){
 mInitDataSucceed = true;

 int height = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
 int width = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
 mBtnViewHeight = (int) (height / mScale);
 mBtnViewWidth = (int) (width / mScale);

 mBtnImg = new CircleImageView(getContext());
 mBtnImg.setImageResource(mBtnImgRes);
 mBtnImg.setOnTouchListener(this);

 addView(mBtnImg, getWaveLayoutParams());

 for (int i = 0; i < RIPPLE_VIEW_COUNT; i++){
  //创建view
  CircleImageView wave = createWave();
  mWaves.add(wave);
  //创建动画
  mAnimas.add(getNewAnimationSet());

  addView(wave, 0, getWaveLayoutParams());
 }
 }
}
private CircleImageView createWave(){
 CircleImageView CircleImageView = new CircleImageView(getContext());
 CircleImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
 CircleImageView.setImageResource(mRippleRes);
 return CircleImageView;
}

private LayoutParams getWaveLayoutParams(){
 LayoutParams lp = new LayoutParams(mBtnViewWidth, mBtnViewHeight);
 return lp;
}

private AnimationSet getNewAnimationSet() {
 AnimationSet as = new AnimationSet(true);
 ScaleAnimation sa = new ScaleAnimation(1f, mScale, 1f, mScale,
  ScaleAnimation.RELATIVE_TO_SELF, 0.5f,
  ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
 sa.setDuration(ANIMATION_EACH_OFFSET * 3);
 sa.setRepeatCount(-1);// 设置循环
 AlphaAnimation aniAlp = new AlphaAnimation(1, 0.1f);
 aniAlp.setRepeatCount(-1);// 设置循环
 as.setDuration(ANIMATION_EACH_OFFSET * 3);
 as.addAnimation(sa);
 as.addAnimation(aniAlp);
 return as;
}

View 都初始化完成了,好像还差一步,onLayout,只要把子 View 都显示到中先就可以了。

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
 if (mInitDataSucceed) {
 int childLeft = (getMeasuredWidth() - mBtnViewWidth) / 2;
 int childTop = (getMeasuredHeight() - mBtnViewHeight) / 2;
 for (int i = 0; i < RIPPLE_VIEW_COUNT; i++) {
  CircleImageView wave = mWaves.get(i);
  wave.layout(childLeft, childTop, mBtnViewWidth + childLeft, mBtnViewHeight + childTop);
 }
 mBtnImg.layout(childLeft, childTop, mBtnViewWidth + childLeft, mBtnViewHeight + childTop);
 }else {
 initData();
 }
}

最后处理一下图片的onTouch事件。

@Override
public boolean onTouch(View v, MotionEvent event) {
 switch (event.getAction()) {
 case MotionEvent.ACTION_DOWN:
  showWaveAnimation();
  break;
 case MotionEvent.ACTION_MOVE:
  break;
 case MotionEvent.ACTION_UP:
 case MotionEvent.ACTION_CANCEL:
  cancelWaveAnimation();
  break;
 default:
  cancelWaveAnimation();
  break;
 }
 return true;
}

private void showWaveAnimation() {
 for (int i = 0; i < RIPPLE_VIEW_COUNT; i++){
 Message message = new Message();
 message.obj = i;
 handler.sendMessageDelayed(message, ANIMATION_EACH_OFFSET * i);
 }
}

private void cancelWaveAnimation() {
 for (int i = 0; i < RIPPLE_VIEW_COUNT; i++){
 CircleImageView wave = mWaves.get(i);
 wave.clearAnimation();
 }
}

private Handler handler = new Handler() {
 @Override
 public void handleMessage(Message msg) {
 int position = (int) msg.obj;
 CircleImageView wave = mWaves.get(position);
 wave.startAnimation(mAnimas.get(position));
 super.handleMessage(msg);
 }
};

参考地址:Android实现水波纹外扩效果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android特效之水波纹的实现

    前言 水波纹特效,想必大家或多或少见过,在我的印象中,大致有如下几种: 支付宝 "咻咻咻" 式 流量球 "荡漾" 式 真实的水波纹效果,基于Bitmap处理式 话不多说,先来看看效果: 填充式水波纹,间距相等 非填充式水波纹,间距相等 非填充式水波纹,间距不断变大 填充式水波纹,间距不断变小 想必大家已经知道基本的原理了,就是用Canvas来画嘛,但可不是简单的画哦,请往下看. 分析 这种类型的水波纹,其实无非就是画圆而已,在给定的矩形中,一个个圆由最小半径扩大到最

  • Android 5.0 实现水波扩散效果

    本文实例为大家分享了Android 5.0 实现水波扩散效果的具体代码,供大家参考,具体内容如下 该效果是通过自定义界面来实现的 1.首先自定义属性,attrs.xml代码如下: <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="RippleView"> <attr name="rippleCo

  • Android水波纹载入控件CircleWaterWaveView使用详解

    一.效果图 本控件已上传Github,欢迎Star和Fork,项目地址:CircleWaterWaveView 二.设计思路 观察效果图,可以看出,该自定义控件由三个部分构成:外圆.内圆.正弦曲线.他们的关系如下图: 因为控件是动态的,所以我们需要一个线程去不停地绘制,所以我选择了SurfaceView来作为该控件地父类.该控件地核心是如何去绘制波浪,我采用如下的思路来进行内圆下部地绘制.利用内圆与正弦曲线地交集,来绘制. 核心代码如下: /** * 绘制图像 * * @author luxun

  • Android实现点击Button产生水波纹效果

    先上图,看看接下来我要向大家介绍的是个什么东西,如下图: 接下来要介绍的就是如何实现上述图中的波纹效果,这种效果如果大家没有体验过的话,可以看看百度手机卫士或者360手机卫士,里面的按钮点击效果都是这样的,另外Android 5.0以上的版本也出现了这种效果.不多说,下面聊聊具体的怎么实现. 首先大家看到的是三个button,水波纹的出现给我们的错觉是直接将波纹绘制在button上面的,但是这样能做到吗?首先button自己有background和src,如果把半透明的水波纹当作backgrou

  • android自定义WaveView水波纹控件

    本文实例为大家分享了android自定义WaveView水波纹控件的使用方法,供大家参考,具体内容如下 Github Repository and libaray WaveView水波纹控件 首先看下演示demo demo中可以看到不同高度,不同速度,不同幅度的水波纹:你可以通过view的参数直接控制view的表现形式. 引入你的工程 在项目的根目录下的build.gradle文件中添加如下代码: allprojects { repositories { ... maven { url 'htt

  • Android自定义控件实现水波纹效果

    本文实例为大家分享了Android自定义控件实现水波纹的具体代码,供大家参考,具体内容如下 示例代码: MainActivity.java package com.example.mhy.shuibowen; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protec

  • Android实现水波纹特效

    最近需要做个类似于水波纹动画的效果,思考了一下不需要UI切个动态图,Android原生的技术利用动画或者自定义控件都可以实现,下面上个图类似于这样的效果 下面请看第一种动画实现,这种方式较为简单些,就是利用3个ImageView不断地做缩放和渐变的动画. 布局文件定义一下 <RelativeLayout android:id="@+id/rl" android:layout_width="match_parent" android:layout_height=

  • Android项目实战手把手教你画圆形水波纹loadingview

    本文实例讲解的是如何画一个满满圆形水波纹loadingview,这类效果应用场景很多,比如内存占用百分比之类的,分享给大家供大家参考,具体内容如下 效果图如下: 预备的知识: 1.贝塞尔曲线    如果你不了解,可以来这里进行基础知识储备:神奇的贝塞尔曲线 2.Paint.setXfermode()  以及PorterDuffXfermode 千万不要被这个b的名字吓到,不熟悉看到可能会认为很难记,其实 只要站在巨人的丁丁上 还是很简单的. 好了 废话不多说 ,跟我一步步来做一个炫酷的view吧

  • Android中Item实现点击水波纹效果

    前言 水波纹效果大致上可以分为两类,一类是有界水波纹,而另一类是无界水波纹,较为广泛使用的是有界水波纹. 系统自带的水波纹实现 系统自带的方法非常方便,只需要给相应的空间设置背景,背景内容则为系统自带的 selectableItemBackground ,这样的话,水波纹就会在TextView所在的区域内进行绘制. <TextView android:background="?android:attr/selectableItemBackground" ... /> 先上效

  • Android仿水波纹流量球进度条控制器

    仿水波纹流球进度条控制器,Android实现高端大气的主流特效,供大家参考,具体内容如下 效果图: CircleView 这里主要是实现中心圆以及水波特效 package com.lgl.circleview; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.gra

随机推荐