前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android实现水波纹扩散效果

Android实现水波纹扩散效果

作者头像
砸漏
发布2020-11-04 10:46:57
2.2K0
发布2020-11-04 10:46:57
举报
文章被收录于专栏:恩蓝脚本恩蓝脚本

本文实例为大家分享了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实现水波纹外扩效果

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档