Android利用自定义View实现水波纹效果



 自定义View实现水波纹的效果

  记录下来,以后多看看

 温故而知新 



  效果图就是这样


 


  

这是 在自定义View类写的代码

package com.example.ripplebackdemo;

import java.util.ArrayList;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.ImageView;

public class RippleView extends ImageView {
 private final static long INTERVAL = 400;// 每个波纹间隔(毫秒)
 private final static long SPEED = 6;// 波纹移动速度 数值越大越慢
 private final static float IMGAE_SCALE = 0.25f;// 按钮占整个区域的大小比例 值越大按钮越大

 private boolean run;// 动画开始标识
 private long startTime;// 动画开始时间
 private long MAX_RADIUS;
 private Paint paint;// 波纹属性
 private Paint imagePaint;// 按钮属性
 private ArrayList<Ripple> rippleList; //波纹集合
 private Bitmap image;  
 private Rect imageRect = new Rect();
 private int width; 
 private int height;

 public RippleView(Context context) {
  super(context);
  init();
 }

 public RippleView(Context context, AttributeSet attrs) {
  super(context, attrs);
  init();
 }

 public RippleView(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
  init();
 }

 // 初始化paint对象
 private void init() {
  imagePaint = new Paint();
  imagePaint.setAntiAlias(true);
  paint = new Paint();
  paint.setAntiAlias(true);
  paint.setColor(Color.WHITE);
  paint.setStrokeWidth(3);
  paint.setStyle(Paint.Style.STROKE);
  rippleList = new ArrayList<RippleView.Ripple>();
  image = BitmapFactory.decodeResource(getContext().getResources(),
    R.drawable.fy_id_select);
 }

 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  MAX_RADIUS = Math.max(w, h) / 2;
  width = w;
  height = h;
  imageRect.set((int) (w - w * IMGAE_SCALE) / 2, (int) (h - h
    * IMGAE_SCALE), (int) (w + w * IMGAE_SCALE) / 2, h);
 }

 // 开始动画
 public void start() {
  run = true;
  startTime = System.currentTimeMillis();
  postInvalidate();
 }

 // 结束动画
 public void stop() {
  if (!run) {
   return;
  }
  rippleList.clear();
  run = false;
 }

 @SuppressLint("DrawAllocation")
 @Override
 protected void onDraw(Canvas canvas) {
  if (run) {
   long current = System.currentTimeMillis();
   long coast = current - startTime;
   synchronized (rippleList) {
    checkNeedAddCicle(coast);
    updateSize(current);
    int size = rippleList.size();
    for (int i = 0; i < size; i++) {
     Ripple ripple = rippleList.get(i);
     if (ripple.canDraw()) {
      paint.setAlpha(ripple.alpha);
      canvas.drawCircle(ripple.x, ripple.y, ripple.radius,
        paint);
     }
    }
   }
   this.postInvalidateDelayed(5);
  }
  if (image != null) {
   canvas.setDrawFilter(new PaintFlagsDrawFilter(0,
     Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
   canvas.drawBitmap(image, null, imageRect, imagePaint);
  }
 }

 // 更新波纹半径
 private void updateSize(long current) {
  int size = rippleList.size();
  for (int i = 0; i < size; i++) {
   Ripple ripple = rippleList.get(i);
   long coast = current - ripple.addTime;
   ripple.y = height - height * IMGAE_SCALE / 2 - coast / SPEED;
   ripple.radius = height * IMGAE_SCALE / 2 + coast / SPEED;
   ripple.alpha=(int) (300 - ripple.radius * 2 / height
     * 255);
  }

 }

 // 检查是否需要增加新的波纹
 private void checkNeedAddCicle(long coast) {
  int count = (int) (coast / INTERVAL);
  if (count > rippleList.size()) {
   addRipple();
  }
 }

 // 增加一个波纹
 private void addRipple() {
  Ripple ripple = new Ripple();
  ripple.x = width / 2;
  ripple.y = height - height * IMGAE_SCALE / 2;
  ripple.radius = height * IMGAE_SCALE / 2;
  ripple.addTime = System.currentTimeMillis();
  rippleList.add(ripple);
 }
 //波纹对象
 class Ripple {
  public float x;//x坐标
  public float y;//y坐标
  public float radius;//半径
  public long addTime;//开始时间
  public int alpha;//透明像素

  // 波纹是否需要显示
  public boolean canDraw() {
   if (radius > MAX_RADIUS) {
    // 超过最大尺寸则不画出来
    return false;
   }
   return true;
  }
 }
}





布局文件需要的   很简单



<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000000"
    tools:context=".MainActivity" >

    <com.example.ripplebackdemo.RippleView
        android:id="@+id/centerImage"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_centerInParent="true" />

</RelativeLayout>



Activity 文件中调用 

public class MainActivity extends Activity {

 RippleView button;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);


  button = (RippleView) findViewById(R.id.centerImage);
  button.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {
    button.start();
    //10秒后停止
    new Handler().postDelayed(new Runnable() {
     
     @Override
     public void run() {
      button.stop();
      
     }
    }, 10000);
   }
  });
  
 }


}








  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值