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() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { return false; } @Override public boolean onResourceReady(Drawable resource, Object model, Target 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() { @Override public void onResourceReady(@NonNull Drawable drawable, @Nullable Transition 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); } }