上篇動畫實現方式對比說過要將實現的動畫效果在本篇敘述,說着說着這就來總結一下了。先看下圖效果:
直接切入正題,本人的實現方式是將其分爲兩步去實現:
第一步:實現人臉的收縮成爲一個圓
第二部:實現圓圈的轉動看到相應圖片部分,類似放大鏡效果
先上佈局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".image.LoaderActivity">
<!--底部黑色背景-->
<ImageView
android:id="@+id/bg_iv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black" />
<!--實現放大鏡效果自定義view-->
<com.xxx.frame.image.BitmapShaderView
android:id="@+id/iv_shader"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!--收縮人像-->
<ImageView
android:id="@+id/iv_crcular_reveal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="@mipmap/bg_shader" />
</android.support.constraint.ConstraintLayout>
實現第一步:
使用ViewAnimationUtils中的createCircularReveal實現收縮成圓的效果,以下是官網描述:
當您顯示或隱藏一組界面元素時,揭露動畫可爲用戶提供視覺連續性。ViewAnimationUtils.createCircularReveal() 方法讓您能夠爲裁剪圓形添加動畫以揭露或隱藏視圖。此動畫在 ViewAnimationUtils 類中提供,適用於 Android 5.0(API 級別 21)及更高版本。
先上代碼:
final DisplayMetrics dm = this.getResources().getDisplayMetrics();
final int centerX = dm.widthPixels / 2;
final int centerY = dm.heightPixels / 2;
iv_circular_reveal.postDelayed(new Runnable() {
@Override
public void run() {
Animator anim = ViewAnimationUtils.createCircularReveal(
iv_circular_reveal,
centerX,
centerY,
(float) Math.hypot(dm.widthPixels, dm.heightPixels), 0);
anim.setDuration(1000);
anim.setInterpolator(new AccelerateDecelerateInterpolator());
anim.start();
anim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
iv_circular_reveal.setVisibility(View.GONE);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
}, 500);
參量 | |
---|---|
view |
View :視圖將被剪切到動畫圓。
|
centerX |
int :動畫圓心相對於的x座標 view 。
|
centerY |
int :動畫圓心的y座標,相對於 view 。
|
startRadius |
float :動畫圓的起始半徑。
|
endRadius |
float :動畫圓的結束半徑。 |
以上就是動畫參數的解釋,這裏我是以屏幕中心爲原點收縮,收縮直到消失(這裏可以收縮到第二步旋轉圓的大小會更好,由於時間問題,當時並沒有這樣做),第一步就完成了。
實現第二步:
這裏使用了BitmapShader(位圖着色器),看似比較不好實現的動畫,其實就是一隻半徑比較大的筆在畫圈而已,關鍵代碼:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!isDraw) return;
if (this.bgBitmap == null) {
this.bgBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.RGB_565);//創建一個新空白位圖
Canvas canvasBg = new Canvas(this.bgBitmap);
canvasBg.drawBitmap(this.bitmap, null, new Rect(0, 0, getWidth(), getHeight()), this.paint);
}
this.paint.setShader(new BitmapShader(this.bgBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));
mDst.reset();
float stop = mLength * mAnimatorValue;
float start = stop - 1;
mPathMeasure.getSegment(start, stop, mDst, true);
canvas.drawPath(mDst, paint);
}
重點代碼:
this.paint.setShader(new BitmapShader(this.bgBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));
BitmapShader(Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)
參量 | |
---|---|
bitmap |
Bitmap :在着色器中使用的位圖此值一定不能爲null 。
|
tileX |
Shader.TileMode :x的平鋪模式以繪製位圖。此值不得爲null 。
|
tileY |
Shader.TileMode :y的平鋪模式繪製位圖。此值不得爲null 。 |
這樣我們的Paint也就擁有了我們的圖,使用這隻Paint去畫圓也就實現上動畫效果。
更多相關知識大家可以看篇末的相關鏈接,這裏就是我實現動畫的全部思路,如果大家還有更多更好的實現思路歡迎留言,共同學習。
相關鏈接:
https://developer.android.com/reference/android/graphics/BitmapShader