Android實現(xiàn)水波紋擴散效果
本文實例為大家分享了Android實現(xiàn)水波紋擴散效果的具體代碼,供大家參考,具體內(nèi)容如下
先上圖
囧!沒有圖片所以就拿了小安代替了。
先看一下如何使用這個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>
是的,沒有別的代碼了,就這么簡單
實現(xiàn)思路
自定義ViewGroup,創(chuàng)建一個用顯示圖片的view,在創(chuàng)建幾個,大小相同的ImageView。當按下時,對這幾個ImageView進行放大和漸變。
代碼
首先它肯定是一個正方形。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, widthMeasureSpec); if (!mInitDataSucceed){ initData(); } }
顯示圖片的View的大小,該怎么給?這是個問題。給大了就看不到擴散效果了,給小,給多少的值合適呢?有沒有正好的值,有的用父 view 的 size / 子 view 放大的倍數(shù),這樣肯定會達到理想的效果。
private static final int ANIMATION_EACH_OFFSET = 800; // 每個動畫的播放時間間隔 private static final int RIPPLE_VIEW_COUNT = 3;//波紋view的個數(shù) 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++){ //創(chuàng)建view CircleImageView wave = createWave(); mWaves.add(wave); //創(chuàng)建動畫 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);// 設(shè)置循環(huán) AlphaAnimation aniAlp = new AlphaAnimation(1, 0.1f); aniAlp.setRepeatCount(-1);// 設(shè)置循環(huán) 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); } };
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android編程程序?qū)崿F(xiàn)一鍵鎖屏的方法講解
今天小編就為大家分享一篇關(guān)于Android編程程序?qū)崿F(xiàn)一鍵鎖屏的方法講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03Android自定義可拖拽的懸浮按鈕DragFloatingActionButton
這篇文章主要介紹了Android自定義可拖拽的懸浮按鈕DragFloatingActionButton,需要的朋友可以參考下2017-06-06Android開發(fā)中MJRefresh自定義刷新動畫效果
本文給大家介紹了MJRefresh自定義刷新動畫效果,包括常見用法等相關(guān)知識,非常不錯,具有參考借鑒價值,感興趣的朋友一起看看吧2016-11-11Android向Excel寫入數(shù)據(jù)導(dǎo)出U盤并發(fā)送郵件
這篇文章主要為大家詳細介紹了Android將數(shù)據(jù)寫入Excel格式導(dǎo)出U盤、發(fā)送郵件,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-07-07android?viewflipper實現(xiàn)左右滑動切換顯示圖片
這篇文章主要為大家詳細介紹了android?viewflipper實現(xiàn)左右滑動切換顯示圖片,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05