代码拉取完成,页面将自动刷新
package com.example.rxjava;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.Toast;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class DouYinView extends View {
Paint paint;
int circleRadius = (int) (getResources().getDisplayMetrics().density*20+0.5f);
int overlay = (int) (getResources().getDisplayMetrics().density*10+0.5f);
int currentCount;
float expandRatio;
int[] drawableIds = new int[]{R.drawable.test1, R.drawable.test2, R.drawable.test3, R.drawable.test4, R.drawable.test5, R.drawable.test6};
int count = drawableIds.length;
BitmapShader[] bitmapShaders;
Matrix matrix;
ValueAnimator valueAnimator;
public DouYinView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
bitmapShaders = new BitmapShader[drawableIds.length];
matrix = new Matrix();
valueAnimator = ValueAnimator.ofFloat(0f, 1f);
valueAnimator.setDuration(800);
valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
expandRatio = (Float) animation.getAnimatedValue();
invalidate();
}
});
valueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationRepeat(Animator animation) {
super.onAnimationRepeat(animation);
currentCount++;
}
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
currentCount++;
}
});
valueAnimator.setRepeatMode(ValueAnimator.RESTART);
valueAnimator.setRepeatCount(count - 1);
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
List<Callable<Bitmap>> callables = new ArrayList<>();
Callable<Bitmap> callable;
for (int drawableId : drawableIds) {
callable = new DecodeCallable(drawableId, DouYinView.this, circleRadius * 2, circleRadius * 2);
callables.add(callable);
}
try {
ExecutorService executorService = Executors.newCachedThreadPool();
List<Future<Bitmap>> list = executorService.invokeAll(callables);
BitmapShader shader;
for (int i = 0; i < list.size(); i++) {
shader = new BitmapShader(list.get(i).get(), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
bitmapShaders[i] = shader;
}
executorService.shutdown();
post(new Runnable() {
@Override
public void run() {
Toast.makeText(getContext(), "complete", Toast.LENGTH_SHORT).show();
valueAnimator.start();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
});
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(count * circleRadius * 2 - (count - 1) * overlay, circleRadius * 2);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
for (int i = 0; i < currentCount; i++) {
paint.setShader(bitmapShaders[currentCount - 1 - i]);
if (i == 0) {
canvas.translate(getWidth() - circleRadius, circleRadius);
canvas.save();
canvas.translate(-circleRadius, -circleRadius);
matrix.setScale(expandRatio, expandRatio, circleRadius * 2, circleRadius);
paint.getShader().setLocalMatrix(matrix);
canvas.drawCircle(circleRadius * 2 - circleRadius * expandRatio, circleRadius, circleRadius * expandRatio, paint);
canvas.restore();
} else {
canvas.save();
paint.getShader().setLocalMatrix(null);
canvas.translate(-((i - 1) * (circleRadius * 2 - overlay) + (circleRadius * 2 - overlay) * expandRatio), 0);
canvas.translate(-circleRadius, -circleRadius);
canvas.drawCircle(circleRadius, circleRadius, circleRadius, paint);
canvas.restore();
}
}
canvas.restore();
}
static class DecodeCallable implements Callable<Bitmap> {
int drawableId;
Matrix matrix;
WeakReference<DouYinView> douYinView;
int targetWidth;
int targetHeight;
DecodeCallable(int drawableId, DouYinView douYinView, int targetWidth, int targetHeight) {
this.drawableId = drawableId;
this.douYinView = new WeakReference<>(douYinView);
matrix = new Matrix();
this.targetWidth = targetWidth;
this.targetHeight = targetHeight;
}
@Override
public Bitmap call() {
if (douYinView.get() != null) {
return decodeBitmap(drawableId);
}
return null;
}
private int downSample(int sourceWidth, int sourceHeight, int targetWidth, int targetHeight) {
int sample = 0;
while (true) {
if (sourceWidth / Math.pow(2, sample + 1) > targetWidth && sourceHeight / Math.pow(2, sample + 1) > targetHeight) {
sample++;
} else {
return (int) Math.pow(2, sample);
}
}
}
private Bitmap decodeBitmap(int resourceId) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(douYinView.get().getResources(), resourceId, options);
int sourceWidth = options.outWidth;
int sourceHeight = options.outHeight;
int sample = downSample(sourceWidth, sourceHeight, targetWidth, targetHeight);
options.inJustDecodeBounds = false;
options.inSampleSize = sample;
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeResource(douYinView.get().getResources(), resourceId, options);
sourceWidth = bitmap.getWidth();
sourceHeight = bitmap.getHeight();
//以center_crop模式生成目标图片
float targetWidth = this.targetWidth;
float targetHeight = this.targetHeight;
float wRatio = targetWidth / sourceWidth;
float hRatio = targetHeight / sourceHeight;
float scale = Math.max(wRatio, hRatio);
int startX = 0;
int startY = 0;
if (wRatio > hRatio) {
startY = (int) ((sourceHeight - targetHeight / scale) * 0.5f);
} else if (wRatio < hRatio) {
startX = (int) ((sourceWidth - targetWidth / scale) * 0.5f);
}
matrix.setScale(scale, scale);
bitmap = Bitmap.createBitmap(bitmap, startX, startY, (int) (targetWidth / scale), (int) (targetHeight / scale), matrix, true);
return bitmap;
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。