多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > Android Ripple 按鈕水波紋效果(二)優化

Android Ripple 按鈕水波紋效果(二)優化

來源:程序員人生   發布時間:2015-05-07 09:49:20 閱讀次數:5758次

上1篇中我們講了自定義ripple 水波紋效果,先來回顧1下效果吧!
這里寫圖片描述

看了以后感覺沒什么問題,我1開始也覺得很滿意了,那好,我們拿Android 5.0自帶的效果來對照1下
這里寫圖片描述

發現了不同的地方沒?點擊中間的時候是看不出甚么區分,但是點擊兩邊的時候,就很明顯了,我們自定義的效果,波紋向兩邊同速度的分散,所以就會出現,如果點擊點不在中心的時候,距離短的1邊波紋先到達,而距離長的1邊后到達,不能同時到達邊沿!而系統自帶的則不存在這類情況,所以這是1個優化點;另外一個優化點是:我們自定義的效果,在波紋全部覆蓋以后,按鈕的選中效果沒了。

有兩處需要優化的
1、實現不論是否點擊中間點都能實現波紋同步到達邊沿
2、當手指未松開時,選中效果不消失

實現:
第2點好實現,我們主要講1下第1點,
第1點我們視察系統的效果,看似兩邊速度不1致致使的,其實我們知道實現原理的話,很容易想到,它是不斷改變圓的圓心來實現,我們上1篇中的實現方法是圓形固定,就是在我們手指按下的位置,而不斷改變半徑來實現,
很明顯,這里也需要改變半徑來實現,我記得我們上1篇中半徑的最大值是需要計算,而這類效果是不需要計算的,由于其最大值是固定的,就是按鈕對角線的1半!
肯定了半徑的最大值,我們還需要肯定圓心X、Y的偏移量,相當于步長吧,其圓心從按下的點到按鈕正中間的時間因該是和半徑從0到最大值的時間保持1致,所以我們可以通過1下代碼來獲得圓心的偏移量和最大半徑。

/*最大半徑*/ mRadius = (float) Math.sqrt(mRect.width() / 2 * mRect.width() / 2 + mRect.height() / 2 * mRect.height() / 2); /*半徑的偏移量*/ mStepRadius = mRadius / mCycle; /*圓心X的偏移量*/ mStepOriginX = (mRect.width() / 2 - mInitX) / mCycle; /*圓心Y的偏移量*/ mStepOriginY = (mRect.height() / 2 - mInitY) / mCycle;

全部實現代碼

package eyeclip.myapplication; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.support.v4.view.MotionEventCompat; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.LinearLayout; /** * Created by moon.zhong on 2015/4/27. */ public class RippleLinearLayout extends LinearLayout { /*起始點*/ private int mInitX; private int mInitY; private float mCurrentX; private float mCurrentY; /*高度和寬度*/ private int mWidth; private int mHeight; /*繪制的半徑*/ private float mRadius; private float mStepRadius; private float mStepOriginX; private float mStepOriginY; private float mDrawRadius; private boolean mDrawFinish; private final int DURATION = 150; private final int FREQUENCY = 10; private float mCycle; private final Rect mRect = new Rect(); private boolean mPressUp = false; private Paint mRevealPaint = new Paint(Paint.ANTI_ALIAS_FLAG); public RippleLinearLayout(Context context) { super(context); initView(context); } public RippleLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } public RippleLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context); } private void initView(Context context) { mRevealPaint.setColor(0x25000000); mCycle = DURATION / FREQUENCY; final float density = getResources().getDisplayMetrics().density ; mCycle = (density*mCycle); mDrawFinish = true; } @Override protected void onDraw(Canvas canvas) { if (mDrawFinish) { super.onDraw(canvas); return; } canvas.drawColor(0x15000000); super.onDraw(canvas); if (mStepRadius == 0) { return; } mDrawRadius = mDrawRadius + mStepRadius; mCurrentX = mCurrentX + mStepOriginX; mCurrentY = mCurrentY + mStepOriginY; if (mDrawRadius > mRadius) { mDrawRadius = 0; canvas.drawCircle(mRect.width() / 2, mRect.height() / 2, mRadius, mRevealPaint); mDrawFinish = true; if (mPressUp) invalidate(); return; } canvas.drawCircle(mCurrentX, mCurrentY, mDrawRadius, mRevealPaint); ViewCompat.postInvalidateOnAnimation(this); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight()); } private void updateDrawData() { // int radiusLeftTop = (int) Math.sqrt((mRect.left - mInitX) * (mRect.left - mInitX) + // (mRect.top - mInitY) * (mRect.top - mInitY)); // int radiusRightTop = (int) Math.sqrt((mRect.right - mInitX) * (mRect.right - mInitX) + // (mRect.top - mInitY) * (mRect.top - mInitY)); // int radiusLeftBottom = (int) Math.sqrt((mRect.left - mInitX) * (mRect.left - mInitX) + // (mRect.bottom - mInitY) * (mRect.bottom - mInitY)); // int radiusRightBottom = (int) Math.sqrt((mRect.right - mInitX) * (mRect.right - mInitX) + // (mRect.bottom - mInitY) * (mRect.bottom - mInitY)); // mRadius = getMax(radiusLeftTop, radiusRightTop, radiusLeftBottom, radiusRightBottom); /*最大半徑*/ mRadius = (float) Math.sqrt(mRect.width() / 2 * mRect.width() / 2 + mRect.height() / 2 * mRect.height() / 2); ; /*半徑的偏移量*/ mStepRadius = mRadius / mCycle; /*圓心X的偏移量*/ mStepOriginX = (mRect.width() / 2 - mInitX) / mCycle; /*圓心Y的偏移量*/ mStepOriginY = (mRect.height() / 2 - mInitY) / mCycle; mCurrentX = mInitX; mCurrentY = mInitY; } @Override public boolean onTouchEvent(MotionEvent event) { final int action = MotionEventCompat.getActionMasked(event); switch (action) { case MotionEvent.ACTION_DOWN: { mPressUp = false; mDrawFinish = false; int index = MotionEventCompat.getActionIndex(event); int eventId = MotionEventCompat.getPointerId(event, index); if (eventId != -1) { mInitX = (int) MotionEventCompat.getX(event, index); mInitY = (int) MotionEventCompat.getY(event, index); updateDrawData(); invalidate(); } break; } case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: mStepRadius = (int) (5 * mStepRadius); mStepOriginX = (int) (5 * mStepOriginX); mStepOriginY = (int) (5 * mStepOriginY); mPressUp = true; invalidate(); break; } return super.onTouchEvent(event); } private int getMax(int... radius) { if (radius.length == 0) { return 0; } int max = radius[0]; for (int m : radius) { if (m > max) { max = m; } } return max; } @Override public boolean performClick() { postDelayed(new Runnable() { @Override public void run() { RippleLinearLayout.super.performClick(); } }, 150); return true; } }

效果圖對照
這里寫圖片描述

這篇主要是對上1篇的內容進行優化,固然你覺得不優化也行!

demo下載

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 五月天视频网站 | 国产精品亚洲欧美 | 精品久 | 国产亚洲精品热视频在线观看 | 国产精品日韩 | 欧美色频| 手机看片国产免费久久网 | 国产一区福利 | 中文字幕在线资源 | 欧美一二区 | 成人国产在线24小时播放视频 | 欧美性视频在线 | 午夜影院私人 | 日本www在线观看 | 性欧美性另类双性人互交 | 国产精品久久久久久久久免费hd | 99久久精品男女性高爱 | 噜噜噜噜私人影院老湿在线观看 | 欧美黑人乱大交 | 范冰冰一级做a爰片久久毛片 | 欧洲美女粗暴交视频 | 手机在线观看免费视频 | 2020久久精品亚洲热综合一本 | 欧美日韩乱码毛片免费观看 | 亚洲性色永久网址 | 欧美性色黄大片www喷水 | 91精品国产福利在线观看 | 最近中文字幕无免费视频 | 欧美日韩午夜视频 | 亚洲一级毛片免费在线观看 | 武则天a级片 | 伊人久久综合网站 | 中文字幕人成乱码在线观看 | 中文字幕亚洲高清综合 | 精品久久国产 | 男男gaygays亚洲中国 | 欧美在线不卡视频 | 波多野结衣一区二区三区四区 | 国内免费视频成人精品 | 人人澡人人爱 | 日韩中文字幕精品久久 |