最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android 5.0 實(shí)現(xiàn)水波擴(kuò)散效果

 更新時(shí)間:2019年01月30日 10:23:20   作者:?jiǎn)杽馒Q  
這篇文章主要為大家詳細(xì)介紹了Android 5.0 實(shí)現(xiàn)水波擴(kuò)散效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

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

該效果是通過(guò)自定義界面來(lái)實(shí)現(xiàn)的

1、首先自定義屬性,attrs.xml代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
 
  <declare-styleable name="RippleView">
    <attr name="rippleColor" format="color" />
    <attr name="rippleAlpha" format="float" />
    <attr name="maskAlpha" format="float" />
    <attr name="rippleTime" format="integer" />
  </declare-styleable>
 
</resources>

其中屬性rippleColor為水波動(dòng)畫(huà)的顏色,rippleAlpha為其透明度,rippleTime為動(dòng)畫(huà)持續(xù)時(shí)間,maskAlpha為觸摸遮掩層的透明度。

2、自定義RippleView類繼承RelativeLayout布局,也可以由需求所定繼承于其它類,實(shí)現(xiàn)水波擴(kuò)散效果主要的有兩點(diǎn):水波擴(kuò)散的繪制和動(dòng)畫(huà)

1)水波的繪制其實(shí)就是繪制一個(gè)圓形

canvas.drawCircle(mDownX, mDownY, mRadius, mRipplePaint);

2)動(dòng)畫(huà)效果就是該圓形的繪制從小到大的過(guò)程,而該圓形到最大時(shí)的半徑長(zhǎng)度就是當(dāng)前所在布局的對(duì)角線長(zhǎng)度:

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
 super.onSizeChanged(w, h, oldw, oldh);
 // 獲取最大半徑
 mMaxRadius = (float) Math.sqrt(w * w + h * h);
}

動(dòng)畫(huà)效果用屬性動(dòng)畫(huà)ObjectAnimator來(lái)實(shí)現(xiàn)(ObjectAnimator是android3.0后出現(xiàn)的)如下

mRippleAnim = ObjectAnimator.ofFloat(this, "radius", 0, mMaxRadius);
mRippleAnim.setInterpolator(new AccelerateDecelerateInterpolator());
mRippleAnim.setDuration(mRippleTime);

其中的radius為自定義的屬性,在動(dòng)畫(huà)執(zhí)行時(shí)會(huì)回調(diào)對(duì)應(yīng)的方法,只需要在該方法中更新圓形的半徑就行了

public void setRadius(final float radius) {
 mRadius = radius;
 invalidate();
}

RippleView完整代碼如下:

public class RippleView extends RelativeLayout {
 
 private int mRippleColor;// 水波顏色
 
 private float mMaskAlpha;// 遮掩透明度
 private float mRippleAlpha;// 水波透明度
 
 private int mRippleTime;// 水波動(dòng)畫(huà)時(shí)間
 private ObjectAnimator mRippleAnim;// 顯示水波動(dòng)畫(huà)
 
 private float mRadius;// 當(dāng)前的半徑
 private float mMaxRadius;// 水波最大半徑
 
 private float mDownX; // 記錄手指按下的位置
 private float mDownY;
 private boolean mIsMask;
 private boolean mIsAnimating;// 是否正在播放動(dòng)畫(huà)
 
 private RectF mRect;
 private Path mPath;
 private Paint mMaskPaint;
 private Paint mRipplePaint;
 
 public RippleView(Context context) {
 this(context, null);
 }
 
 public RippleView(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
 }
 
 public RippleView(Context context, AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);
 init();
 // 獲取自定義屬性
 TypedArray ta = context.obtainStyledAttributes(attrs,
  R.styleable.RippleView);
 mRippleColor = ta.getColor(R.styleable.RippleView_rippleColor,
  mRippleColor);
 mMaskAlpha = ta.getFloat(R.styleable.RippleView_maskAlpha, mMaskAlpha);
 mRippleAlpha = ta.getFloat(R.styleable.RippleView_rippleAlpha,
  mRippleAlpha);
 mRippleTime = ta.getInt(R.styleable.RippleView_rippleTime, mRippleTime);
 ta.recycle();
 initLast();
 }
 
 // 初始化方法
 private void init() {
 mRippleColor = Color.BLACK;
 mMaskAlpha = 0.4f;
 mRippleAlpha = 0.8f;
 mRippleTime = 800;
 
 mPath = new Path();
 mMaskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 mRipplePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 }
 
 // 初始化
 private void initLast() {
 mMaskPaint.setColor(mRippleColor);
 mRipplePaint.setColor(mRippleColor);
 mMaskPaint.setAlpha((int) (mMaskAlpha * 255));
 mRipplePaint.setAlpha((int) (mRippleAlpha * 255));
 }
 
 // 初始化動(dòng)畫(huà)
 private void initAnim() {
 mRippleAnim = ObjectAnimator.ofFloat(this, "radius", 0, mMaxRadius);
 mRippleAnim.setInterpolator(new AccelerateDecelerateInterpolator());
 mRippleAnim.setDuration(mRippleTime);
 mRippleAnim.addListener(new Animator.AnimatorListener() {
  @Override
  public void onAnimationStart(Animator animator) {
  mIsAnimating = true;
  }
 
  @Override
  public void onAnimationEnd(Animator animator) {
  setRadius(0);
  mIsMask = false;
  mIsAnimating = false;
  }
 
  @Override
  public void onAnimationCancel(Animator animator) {
 
  }
 
  @Override
  public void onAnimationRepeat(Animator animator) {
 
  }
 });
 }
 
 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
 super.onSizeChanged(w, h, oldw, oldh);
 // 獲取最大半徑
 mMaxRadius = (float) Math.sqrt(w * w + h * h);
 // 獲取該類布局范圍
 mRect = new RectF(0f, 0f, getMeasuredWidth() * 1.0f,
  getMeasuredHeight() * 1.0f);
 // 初始化動(dòng)畫(huà)
 initAnim();
 }
 
 @Override
 public boolean onTouchEvent(MotionEvent event) {
 // 按下事件
 if (event.getAction() == MotionEvent.ACTION_DOWN) {
  mIsMask = true;
  invalidate();
 } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
  invalidate();
 }
 // 抬起事件
 else if (event.getAction() == MotionEvent.ACTION_UP) {
  mDownX = event.getX();
  mDownY = event.getY();
  if (mIsAnimating) {
  mRippleAnim.cancel();
  }
  boolean isInView = mRect.contains(mDownX, mDownY);
  if (isInView) {
  mRippleAnim.start();
  } else {
  mIsMask = false;
  invalidate();
  }
 
 }
 
 return true;
 }
 
 @Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 // 繪制遮掩
 if (mIsMask) {
  canvas.save(Canvas.CLIP_SAVE_FLAG);
  mPath.reset();
  mPath.addRect(mRect, Path.Direction.CW);
  canvas.clipPath(mPath);
  canvas.drawRect(mRect, mMaskPaint);
  canvas.restore();
 
 }
 
 // 繪制水波
 canvas.save(Canvas.CLIP_SAVE_FLAG);
 mPath.reset();
 mPath.addCircle(mDownX, mDownY, mRadius, Path.Direction.CW);
 canvas.clipPath(mPath);
 canvas.drawCircle(mDownX, mDownY, mRadius, mRipplePaint);
 canvas.restore();
 
 }
 
 // 屬性動(dòng)畫(huà)回調(diào)的方法
 public void setRadius(final float radius) {
 mRadius = radius;
 invalidate();
 }
}

界面布局代碼

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  xmlns:ripple="http://schemas.android.com/apk/res/com.example.rippleview"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="#000000" >
 
  <com.example.rippleview.RippleView
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:layout_centerInParent="true"
    android:background="#ffffff"
    android:clickable="true"
    ripple:rippleColor="#ababab" >
 
    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_centerInParent="true"
      android:text="click me"
      android:textSize="18sp" />
  </com.example.rippleview.RippleView>
 
</RelativeLayout>

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android編程中activity的完整生命周期實(shí)例詳解

    Android編程中activity的完整生命周期實(shí)例詳解

    這篇文章主要介紹了Android編程中activity的完整生命周期,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android編程中activity的原理與具體用法,需要的朋友可以參考下
    2015-12-12
  • Android實(shí)現(xiàn)自動(dòng)提取短信驗(yàn)證碼功能

    Android實(shí)現(xiàn)自動(dòng)提取短信驗(yàn)證碼功能

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)自動(dòng)提取短信驗(yàn)證碼功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-01-01
  • Android 自定義通用的loadingview實(shí)現(xiàn)代碼

    Android 自定義通用的loadingview實(shí)現(xiàn)代碼

    本篇文章主要介紹了Android 自定義通用的loadingview實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-01-01
  • Android ViewModel的作用深入講解

    Android ViewModel的作用深入講解

    這篇文章主要介紹了Android ViewModel的作用,ViewModel類旨在以注重生命周期的方式存儲(chǔ)和管理界面相關(guān)數(shù)據(jù),ViewModel類讓數(shù)據(jù)可在發(fā)生屏幕旋轉(zhuǎn)等配置更改后繼續(xù)留存,需要詳細(xì)了解可以參考下文
    2023-05-05
  • Android EditText限制輸入字?jǐn)?shù)的方法

    Android EditText限制輸入字?jǐn)?shù)的方法

    這篇文章主要介紹了Android EditText限制輸入字?jǐn)?shù)的方法,涉及Android針對(duì)EditText文本與字符串操作相關(guān)技巧,需要的朋友可以參考下
    2016-01-01
  • Android編程實(shí)現(xiàn)手機(jī)震動(dòng)功能的方法

    Android編程實(shí)現(xiàn)手機(jī)震動(dòng)功能的方法

    這篇文章主要介紹了Android編程實(shí)現(xiàn)手機(jī)震動(dòng)功能的方法,結(jié)合實(shí)例形式分析了Android實(shí)現(xiàn)手機(jī)震動(dòng)功能的核心代碼與權(quán)限控制操作技巧,需要的朋友可以參考下
    2017-06-06
  • 使用OkHttp包在Android中進(jìn)行HTTP頭處理的教程

    使用OkHttp包在Android中進(jìn)行HTTP頭處理的教程

    HTTP頭部處理是HTTP網(wǎng)絡(luò)編程中的基本操作,安卓中使用OkHttp包(github.com/square/okhttp)進(jìn)行相關(guān)操作當(dāng)然也是得心應(yīng)手,這里我們就來(lái)看一下使用OkHttp包在Android中進(jìn)行HTTP頭處理的教程
    2016-07-07
  • Flutter?WebView?預(yù)加載實(shí)現(xiàn)方法(Http?Server)

    Flutter?WebView?預(yù)加載實(shí)現(xiàn)方法(Http?Server)

    這篇文章主要介紹了Flutter?WebView?預(yù)加載實(shí)現(xiàn)方法,包括資源的配置,資源的下載和存儲(chǔ),版本的管理,如何根據(jù)實(shí)際url獲取對(duì)應(yīng)HttpServer?bind的url等,需要的朋友可以參考下
    2022-05-05
  • Android使用shape繪制陰影圖層陰影效果示例

    Android使用shape繪制陰影圖層陰影效果示例

    本篇文章主要介紹了Android使用shape繪制陰影圖層陰影效果示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • android閱讀器長(zhǎng)按選擇文字功能實(shí)現(xiàn)代碼

    android閱讀器長(zhǎng)按選擇文字功能實(shí)現(xiàn)代碼

    本篇文章主要介紹了android閱讀器長(zhǎng)按選擇文字功能實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-07-07

最新評(píng)論

巫溪县| 会泽县| 七台河市| 中超| 丹棱县| 尼勒克县| 安国市| 连城县| 仙桃市| 化州市| 衡阳市| 徐闻县| 集安市| 贵南县| 汝城县| 延吉市| 临江市| 司法| 二手房| 英吉沙县| 铜川市| 江安县| 宁远县| 沧源| 日喀则市| 丹棱县| 集安市| 利川市| 兴海县| 定襄县| 南澳县| 吐鲁番市| 鹤峰县| 石林| 澄城县| 光泽县| 佛学| 上杭县| 郴州市| 堆龙德庆县| 玉溪市|