Files
yusheng-android/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/ExpressionImgView.java

131 lines
5.1 KiB
Java
Raw Normal View History

2025-06-09 17:43:01 +08:00
package com.qxcm.moduleutil.widget;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.vectordrawable.graphics.drawable.Animatable2Compat;
import com.bumptech.glide.integration.webp.decoder.WebpDrawable;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;
import com.qxcm.moduleutil.bean.FaceBean;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ExpressionImgView extends AppCompatImageView {
private Context mContext;
private Runnable goneCmd = new Runnable() {
@Override
public void run() {
setVisibility(GONE);
}
};
public ExpressionImgView(Context context) {
this(context, null);
}
public ExpressionImgView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ExpressionImgView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
}
public void addData(FaceBean faceBean) {
setVisibility(VISIBLE);
removeCallbacks(goneCmd);
if (faceBean.getType() == 1) {
String url = faceBean.getFace_spectial();
if (TextUtils.isEmpty(url)) {
return;
}
GlideApp.with(mContext).load(url).listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
postDelayed(goneCmd, faceBean.getMillTime() == 0 ? 3000 : Math.max(faceBean.getMillTime(), 1000));
return false;
}
}).skipMemoryCache(true).into(this);
} else {
GlideApp.with(mContext).load(String.format("http://soundriver.oss-cn-hangzhou.aliyuncs.com/custom/random%ss.webp", faceBean.getNumber())).into(new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable drawable, @Nullable Transition<? super Drawable> transition) {
if (drawable instanceof WebpDrawable) {
ExpressionImgView.this.setImageDrawable(drawable);
((WebpDrawable) drawable).start();
((WebpDrawable) drawable).setLoopCount(1);
((WebpDrawable) drawable).registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
@Override
public void onAnimationEnd(Drawable drawable) {
super.onAnimationEnd(drawable);
postDelayed(goneCmd, 500);
}
});
}
}
});
}
}
private int getWebpPlayTime(Drawable resource) {
WebpDrawable webpDrawable = (WebpDrawable) resource;
try {
Field gifStateField = WebpDrawable.class.getDeclaredField("state");
gifStateField.setAccessible(true);
Class gifStateClass = Class.forName("com.bumptech.glide.integration.webp.decoder.WebpDrawable$WebpState");
Field gifFrameLoaderField = gifStateClass.getDeclaredField("frameLoader");
gifFrameLoaderField.setAccessible(true);
Class gifFrameLoaderClass = Class.forName("com.bumptech.glide.integration.webp.decoder.WebpFrameLoader");
Field gifDecoderField = gifFrameLoaderClass.getDeclaredField("webpDecoder");
gifDecoderField.setAccessible(true);
Class gifDecoderClass = Class.forName("com.bumptech.glide.integration.webp.decoder.WebpDecoder");
Object gifDecoder = gifDecoderField.get(gifFrameLoaderField.get(gifStateField.get(resource)));
Method getDelayMethod = gifDecoderClass.getDeclaredMethod("getDelay", int.class);
getDelayMethod.setAccessible(true);
// 设置只播放一次
// 获得总帧数
int count = webpDrawable.getFrameCount();
int delay = 0;
for (int i = 0; i < count; i++) {
// 计算每一帧所需要的时间进行累加
delay += (int) getDelayMethod.invoke(gifDecoder, i);
}
return delay;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
public void remove() {
setVisibility(GONE);
}
}