https://juejin.im/post/6844904116351664135
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
//自带 glide + glide的 transform
implementation 'jp.wasabeef:glide-transformations:4.0.1'
//这个必须加---element== null
implementation 'com.github.bumptech.glide:glide:4.10.0'
//加上这个才可以 有 进度
annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
一个大神写的,我转个Java
package com.as.zqfjavasample.formal.customviews;
import android.animation.IntEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import io.reactivex.Completable;
import io.reactivex.CompletableEmitter;
import io.reactivex.CompletableObserver;
import io.reactivex.CompletableOnSubscribe;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.schedulers.Schedulers;
/**
* -----------------------------
* Created by zqf on 2020/9/29.
* ---------------------------
*/
public class MyRotateViewJava extends AppCompatImageView {
private RotateController controller;
public RotateController getController() {
return controller;
}
public void setController(RotateController controller) {
this.controller = controller;
}
public MyRotateViewJava(Context context) {
this(context, null);
}
public MyRotateViewJava(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyRotateViewJava(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
controller = new RotateController(this, context);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return controller.onTouchEvent(event);
}
public interface OnRotateActionListener {
void onSourceReady();
void onClick();
}
public class RotateController implements LifecycleObserver {
private CompositeDisposable disposableHelper = new CompositeDisposable();
private GestureDetector gestureDetector;
private List<String> motorImageList = new ArrayList<>();
private boolean isSourceReady = false;
private Disposable timerDisposable;
private int currentIndex = 0;
//累积播放的帧数
private int accumulate = 0;
private ValueAnimator anim;
private boolean isAutoShow = true;
OnRotateActionListener actionistener;
public void setActionistener(OnRotateActionListener actionistener) {
this.actionistener = actionistener;
}
private MyRotateViewJava myRotateViewJava;
private Context context;
public RotateController(MyRotateViewJava myRotateViewJava, Context context) {
this.myRotateViewJava = myRotateViewJava;
this.context = context;
gestureDetector = new GestureDetector(context, new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
actionistener.onClick();
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (Math.abs(distanceX) < 1f) {
accumulate = 0;
} else if (Math.abs(distanceX) < 3f) {
if (distanceX > 0) {
accumulate = -1;
} else if (distanceX < 0) {
accumulate = 1;
}
} else if (distanceX > 0) {
if (accumulate < 0) {
accumulate = 0;
}
accumulate--;
} else {
if (accumulate > 0) {
accumulate = 0;
}
accumulate++;
}
return true;
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (Math.abs(velocityX) < 150) {
return false;
}
if (velocityX > 0) {
accumulate += 5;
} else {
accumulate -= 5;
}
return true;
}
});
gestureDetector.setIsLongpressEnabled(false);
if (context instanceof AppCompatActivity) {
AppCompatActivity context1 = (AppCompatActivity) context;
context1.getLifecycle().addObserver(this);
}
}
private void addIndex() {
if (isSourceReady) {
currentIndex++;
if (currentIndex >= motorImageList.size()) {
currentIndex = 0;
}
Glide.with(myRotateViewJava).load(motorImageList.get(currentIndex)).dontAnimate()
.placeholder(myRotateViewJava.getDrawable()).into(myRotateViewJava);
}
}
private void reduceIndex() {
if (isSourceReady) {
currentIndex--;
if (currentIndex < 0) {
currentIndex = motorImageList.size() - 1;
}
Glide.with(myRotateViewJava).load(motorImageList.get(currentIndex)).dontAnimate()
.placeholder(myRotateViewJava.getDrawable()).into(myRotateViewJava);
}
}
private Completable getFirstImage(String url) {
CompletableOnSubscribe completableOnSubscribe = new CompletableOnSubscribe() {
@Override
public void subscribe(CompletableEmitter e) throws Exception {
Glide.with(myRotateViewJava)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.DATA)
.into(myRotateViewJava);
e.onComplete();
}
};
return Completable.create(completableOnSubscribe).subscribeOn(AndroidSchedulers.mainThread());
}
private Completable getSingleImage(String url) {
CompletableOnSubscribe completableOnSubscribe = new CompletableOnSubscribe() {
@Override
public void subscribe(CompletableEmitter e) throws Exception {
Glide.with(myRotateViewJava)
.asFile()
.load(url)
.diskCacheStrategy(DiskCacheStrategy.DATA)
.submit();
e.onComplete();
}
};
return Completable.create(completableOnSubscribe).subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io());
}
private void prepareImageSource() {
List<Completable> actionList = new ArrayList<Completable>();
for (int i = 0; i < motorImageList.size(); i++) {
if (i == 0) {
actionList.add(getFirstImage(motorImageList.get(i)));
} else {
actionList.add(getSingleImage(motorImageList.get(i)));
}
}
Completable.merge(actionList)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new CompletableObserver() {
@Override
public void onSubscribe(Disposable d) {
disposableHelper.add(d);
}
@Override
public void onComplete() {
loadComplete();
}
@Override
public void onError(Throwable e) {
}
});
}
private void loadComplete() {
if (actionistener == null) {
return;
}
actionistener.onSourceReady();
if (!isAutoShow) {
isSourceReady = true;
initTimer();
return;
}
anim = ValueAnimator.ofObject(new IntEvaluator(), 1, motorImageList.size());
anim.setDuration(1800);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int animatedValue = (int) animation.getAnimatedValue();
if (currentIndex != animatedValue) {
if (animatedValue >= motorImageList.size()) {
currentIndex = 0;
} else {
currentIndex = animatedValue;
}
Glide.with(myRotateViewJava).load(motorImageList.get(currentIndex)).dontAnimate()
.placeholder(myRotateViewJava.getDrawable()).into(myRotateViewJava);
if (currentIndex == 0) {
isSourceReady = true;
initTimer();
}
}
}
});
anim.start();
}
private void initTimer() {
DisposableObserver<Long> timerDisposable = Observable.interval(40, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<Long>() {
@Override
public void onNext(Long aLong) {
if (accumulate > 0) {
accumulate--;
addIndex();
} else if (accumulate < 0) {
accumulate++;
reduceIndex();
}
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
private void loadSingleImage(String imageUrl) {
myRotateViewJava.setScaleType(ImageView.ScaleType.CENTER_CROP);
Glide.with(myRotateViewJava).load(imageUrl).dontAnimate().into(myRotateViewJava);
}
public void loadImageList(List<String> imageList, boolean isAutoShow) {
this.isAutoShow = isAutoShow;
if (imageList.size() == 0) {
} else if (imageList.size() == 1) {
loadSingleImage(imageList.get(0));
} else {
myRotateViewJava.setScaleType(ImageView.ScaleType.FIT_CENTER);
motorImageList.addAll(imageList);
prepareImageSource();
}
}
private boolean onTouchEvent(MotionEvent event) {
if (event != null) {
if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
accumulate = 0;
}
}
myRotateViewJava.getParent().requestDisallowInterceptTouchEvent(true);
return gestureDetector.onTouchEvent(event);
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void onDestroy() {
disposableHelper.dispose();
timerDisposable.dispose();
anim.removeAllUpdateListeners();
anim.cancel();
}
}
}
List<String> list = new ArrayList<>();
list.add(pic0);
list.add(pic1);
list.add(pic2);
list.add(pic3);
list.add(pic4);
list.add(pic5);
list.add(pic6);
list.add(pic7);
list.add(pic8);
list.add(pic9);
list.add(pic10);
list.add(pic11);
list.add(pic12);
list.add(pic13);
list.add(pic14);
list.add(pic15);
MyRotateViewJava.RotateController controller = mViewBinding.rotateiv.getController();
controller.loadImageList(list, true);
controller.setActionistener(new MyRotateViewJava.OnRotateActionListener() {
@Override
public void onSourceReady() {
}
@Override
public void onClick() {
}
});