Android實(shí)現(xiàn)水波紋擴(kuò)散效果
本文實(shí)例為大家分享了Android實(shí)現(xiàn)水波紋擴(kuò)散效果的具體代碼,供大家參考,具體內(nèi)容如下
先上圖

囧!沒(méi)有圖片所以就拿了小安代替了。
先看一下如何使用這個(gè)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>
是的,沒(méi)有別的代碼了,就這么簡(jiǎn)單
實(shí)現(xiàn)思路
自定義ViewGroup,創(chuàng)建一個(gè)用顯示圖片的view,在創(chuàng)建幾個(gè),大小相同的ImageView。當(dāng)按下時(shí),對(duì)這幾個(gè)ImageView進(jìn)行放大和漸變。
代碼
首先它肯定是一個(gè)正方形。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
if (!mInitDataSucceed){
initData();
}
}顯示圖片的View的大小,該怎么給?這是個(gè)問(wèn)題。給大了就看不到擴(kuò)散效果了,給小,給多少的值合適呢?有沒(méi)有正好的值,有的用父 view 的 size / 子 view 放大的倍數(shù),這樣肯定會(huì)達(dá)到理想的效果。
private static final int ANIMATION_EACH_OFFSET = 800; // 每個(gè)動(dòng)畫的播放時(shí)間間隔
private static final int RIPPLE_VIEW_COUNT = 3;//波紋view的個(gè)數(shù)
private static final float DEFAULT_SCALE = 1.6f;//波紋放大后的大小
//點(diǎn)擊有擴(kuò)散效果的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)建動(dò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);
}
};參考地址:Android實(shí)現(xiàn)水波紋外擴(kuò)效果
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
手把手教你實(shí)現(xiàn)Android編譯期注解
今天給大家介紹Android編譯期注解sdk的步驟以及注意事項(xiàng),并簡(jiǎn)要分析了運(yùn)行時(shí)注解以及字節(jié)碼技術(shù)在生成代碼上與編譯期注解的不同與優(yōu)劣,感興趣的朋友一起看看吧2021-07-07
Android編程開發(fā)中ListView的常見用法分析
這篇文章主要介紹了Android編程開發(fā)中ListView的常見用法,較為詳細(xì)的分析了ListView的功能及常見使用方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10
Flutter網(wǎng)絡(luò)請(qǐng)求的3種簡(jiǎn)單實(shí)現(xiàn)方法
這篇文章主要給大家介紹了給大家Flutter網(wǎng)絡(luò)請(qǐng)求的3種簡(jiǎn)單實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Flutter具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
Android自定義實(shí)現(xiàn)一個(gè)車牌字母選擇鍵盤
這篇文章主要為大家詳細(xì)介紹了Android如何自定義實(shí)現(xiàn)一個(gè)車牌字母選擇鍵盤,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-06-06
Android 判斷日期是否在一年以內(nèi)的算法實(shí)例
下面小編就為大家?guī)?lái)一篇Android 判斷日期是否在一年以內(nèi)的算法實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04
Android實(shí)現(xiàn)頂部導(dǎo)航欄可點(diǎn)擊可滑動(dòng)效果(仿微信仿豆瓣網(wǎng))
Android仿微信圖片選擇器ImageSelector使用詳解

