首页 > 系统 > Android > 正文

Android实现水波纹扩散效果

2019-10-21 21:26:02
字体:
来源:转载
供稿:网友

本文实例为大家分享了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进行放大和渐变。

代码

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

@Overrideprotected 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;//波纹放大后的大小//点击有扩散效果的viewprivate 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 都显示到中先就可以了。

@Overrideprotected 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事件。

@Overridepublic 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); }};

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


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表