2025-10-24 17:55:15 +08:00
|
|
|
|
package com.xscm.moduleutil.widget;
|
|
|
|
|
|
|
|
|
|
|
|
import android.content.Context;
|
|
|
|
|
|
import android.text.TextUtils;
|
|
|
|
|
|
import android.util.AttributeSet;
|
|
|
|
|
|
import android.view.View;
|
|
|
|
|
|
import android.widget.FrameLayout;
|
|
|
|
|
|
|
|
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
|
|
|
|
|
|
|
|
import com.blankj.utilcode.util.LogUtils;
|
|
|
|
|
|
import com.tencent.qgame.animplayer.AnimConfig;
|
|
|
|
|
|
import com.tencent.qgame.animplayer.AnimView;
|
|
|
|
|
|
import com.tencent.qgame.animplayer.inter.IAnimListener;
|
|
|
|
|
|
import com.xscm.moduleutil.bean.GiftBean;
|
|
|
|
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
|
|
|
import java.util.concurrent.locks.ReentrantLock;
|
|
|
|
|
|
|
2025-12-19 18:41:16 +08:00
|
|
|
|
import lombok.Getter;
|
2025-12-08 19:00:15 +08:00
|
|
|
|
import lombok.Setter;
|
2025-10-24 17:55:15 +08:00
|
|
|
|
import okhttp3.Call;
|
|
|
|
|
|
import okhttp3.Callback;
|
|
|
|
|
|
import okhttp3.OkHttpClient;
|
|
|
|
|
|
import okhttp3.Request;
|
|
|
|
|
|
import okhttp3.Response;
|
|
|
|
|
|
import okhttp3.ResponseBody;
|
|
|
|
|
|
|
|
|
|
|
|
public class GiftAnimView extends FrameLayout implements GiftSvgaView.OnAnimationListener {
|
|
|
|
|
|
private AnimView playerMp4View;
|
|
|
|
|
|
private GiftSvgaView svgaView;
|
|
|
|
|
|
private GiftBean playModel;
|
|
|
|
|
|
private boolean isLoadEffect = false;
|
|
|
|
|
|
private boolean isShow = true;//是否开启特效
|
|
|
|
|
|
private ReentrantLock lock = new ReentrantLock();
|
|
|
|
|
|
private List<String> giftArray = new ArrayList<>();
|
2025-12-08 19:00:15 +08:00
|
|
|
|
@Setter
|
2025-12-19 18:41:16 +08:00
|
|
|
|
@Getter
|
2025-12-08 19:00:15 +08:00
|
|
|
|
public ExecutorService queue;
|
2025-10-24 17:55:15 +08:00
|
|
|
|
private Context mContext;
|
|
|
|
|
|
private boolean isOnece;
|
|
|
|
|
|
// 添加带Context参数的构造函数
|
|
|
|
|
|
|
|
|
|
|
|
// 添加带Context和AttributeSet参数的构造函数(解决XML inflate问题的关键)
|
|
|
|
|
|
public GiftAnimView(Context context, @Nullable AttributeSet attrs) {
|
|
|
|
|
|
super(context, attrs);
|
|
|
|
|
|
this.mContext = context;
|
|
|
|
|
|
init();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加带Context、AttributeSet和 defStyleAttr 参数的构造函数(更完整的实现)
|
|
|
|
|
|
public GiftAnimView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
|
|
|
|
|
super(context, attrs, defStyleAttr);
|
|
|
|
|
|
this.mContext = context;
|
|
|
|
|
|
init();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public GiftAnimView(Context context) {
|
|
|
|
|
|
super(context);
|
|
|
|
|
|
this.mContext = context;
|
|
|
|
|
|
init();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void init() {
|
|
|
|
|
|
isLoadEffect = false;
|
2025-12-08 19:01:09 +08:00
|
|
|
|
// setBackgroundColor(getResources().getColor(R.color.colorBlack45));
|
2025-10-24 17:55:15 +08:00
|
|
|
|
// 初始化SVGA视图
|
|
|
|
|
|
svgaView = new GiftSvgaView(getContext());
|
|
|
|
|
|
addView(svgaView);
|
|
|
|
|
|
playerMp4View = new AnimView(getContext());
|
|
|
|
|
|
addView(playerMp4View);
|
|
|
|
|
|
|
|
|
|
|
|
// 设置布局参数 - 在Android中通常使用LayoutParams
|
|
|
|
|
|
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
|
|
|
|
|
playerMp4View.setLoop(1);
|
|
|
|
|
|
playerMp4View.setLayoutParams(params);
|
|
|
|
|
|
playerMp4View.setAnimListener(new IAnimListener() {
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onVideoDestroy() {
|
|
|
|
|
|
LogUtils.e("onVideoDestroy");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onVideoComplete() {
|
|
|
|
|
|
LogUtils.e("onVideoComplete");
|
|
|
|
|
|
post(() -> {
|
|
|
|
|
|
if (playerMp4View!=null) {
|
|
|
|
|
|
playerMp4View.setVisibility(View.GONE);
|
|
|
|
|
|
if (isOnece){
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 通知播放完成
|
|
|
|
|
|
notifyPlaybackComplete();
|
|
|
|
|
|
loadStartSVGAPlayer();
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onVideoRender(int i, @Nullable AnimConfig animConfig) {
|
|
|
|
|
|
// LogUtils.e("onVideoRender", i, animConfig);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onVideoStart() {
|
|
|
|
|
|
LogUtils.e("onVideoStart");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public boolean onVideoConfigReady(@NonNull AnimConfig animConfig) {
|
|
|
|
|
|
LogUtils.e("onVideoConfigReady", animConfig);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onFailed(int i, @Nullable String s) {
|
|
|
|
|
|
LogUtils.e("onFailed", s);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
svgaView.setDidFinishedDisplay(this);
|
|
|
|
|
|
svgaView.setDidStartAnimation(this);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void displayEffectView1(List<String> stringList){
|
|
|
|
|
|
queue.execute(new Runnable() {
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void run() {
|
|
|
|
|
|
/// 如果play_image不存在return
|
|
|
|
|
|
if (stringList == null || stringList.isEmpty()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
/// 锁住list
|
|
|
|
|
|
lock.lock();
|
|
|
|
|
|
try {
|
|
|
|
|
|
/// 添加礼物进list
|
|
|
|
|
|
giftArray.addAll(stringList);
|
|
|
|
|
|
|
|
|
|
|
|
/// 如果没有在加载则开始加载
|
|
|
|
|
|
if (!isLoadEffect) {
|
|
|
|
|
|
/// 更改加载状态标记
|
|
|
|
|
|
isLoadEffect = true;
|
|
|
|
|
|
loadStartSVGAPlayer();
|
|
|
|
|
|
}
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
/// 解锁
|
|
|
|
|
|
lock.unlock();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 礼物特效进来 gift为礼物实体类
|
|
|
|
|
|
public void displayEffectView(final String gift) {
|
|
|
|
|
|
queue.execute(new Runnable() {
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void run() {
|
|
|
|
|
|
/// 如果play_image不存在return
|
|
|
|
|
|
if (gift == null || gift.isEmpty()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 将play_image链接转为小写
|
|
|
|
|
|
String playImage = gift;
|
|
|
|
|
|
String pathExtension = getFileExtension(playImage).toLowerCase();
|
|
|
|
|
|
|
|
|
|
|
|
/// 判定礼物的后缀是否为svga或者mp4如果非这两种 则return
|
|
|
|
|
|
if (!("svga".equals(pathExtension) || "mp4".equals(pathExtension))) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 锁住list
|
|
|
|
|
|
lock.lock();
|
|
|
|
|
|
try {
|
|
|
|
|
|
/// 添加礼物进list
|
|
|
|
|
|
giftArray.add(gift);
|
|
|
|
|
|
|
|
|
|
|
|
/// 如果没有在加载则开始加载
|
|
|
|
|
|
if (!isLoadEffect) {
|
|
|
|
|
|
/// 更改加载状态标记
|
|
|
|
|
|
isLoadEffect = true;
|
|
|
|
|
|
loadStartSVGAPlayer();
|
|
|
|
|
|
}
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
/// 解锁
|
|
|
|
|
|
lock.unlock();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void previewEffectWith(String playImage){
|
|
|
|
|
|
this.isOnece=true;
|
|
|
|
|
|
if (playImage.endsWith("mp4")) {
|
|
|
|
|
|
downloadAndPlay(getContext(), playImage, new DownloadCallback() {
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onSuccess(File file) {
|
|
|
|
|
|
post(() -> {
|
|
|
|
|
|
playerMp4View.setVisibility(View.VISIBLE);
|
|
|
|
|
|
svgaView.setVisibility(View.GONE);
|
|
|
|
|
|
playerMp4View.startPlay(file);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onFailure(Exception e) {
|
|
|
|
|
|
LogUtils.e("MP4下载或播放失败: " + e.getMessage());
|
|
|
|
|
|
// 处理失败情况,继续播放下一个
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
} else if (playImage.endsWith("svga")) {
|
|
|
|
|
|
// File file = downloadAndPlay(getContext(), playImage);
|
|
|
|
|
|
post(() -> {
|
|
|
|
|
|
playerMp4View.setVisibility(View.GONE);
|
|
|
|
|
|
svgaView.setVisibility(View.VISIBLE);
|
|
|
|
|
|
svgaView.loadSVGAPlayerWith(playImage, false);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void openOrCloseEffectViewWith(boolean isShow) {
|
|
|
|
|
|
this.isShow = isShow;
|
|
|
|
|
|
removeSvgaQueueData();
|
2025-12-16 17:10:04 +08:00
|
|
|
|
if(playerMp4View!=null) {
|
|
|
|
|
|
playerMp4View.stopPlay();
|
|
|
|
|
|
playerMp4View.setVisibility(View.GONE);
|
|
|
|
|
|
}
|
2025-10-24 17:55:15 +08:00
|
|
|
|
setVisibility(isShow ? View.VISIBLE : View.GONE);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void stopPlay() {
|
|
|
|
|
|
removeSvgaQueueData();
|
2025-12-16 17:10:04 +08:00
|
|
|
|
if(playerMp4View!=null) {
|
|
|
|
|
|
playerMp4View.stopPlay();
|
|
|
|
|
|
playerMp4View.setVisibility(View.GONE);
|
|
|
|
|
|
}
|
2025-10-24 17:55:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void loadStartSVGAPlayer() {
|
|
|
|
|
|
if (!isShow) {
|
|
|
|
|
|
/// isshow 为是否开启特效 如果未开启则return
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String giftModel = null;
|
|
|
|
|
|
|
|
|
|
|
|
/// list加锁
|
|
|
|
|
|
lock.lock();
|
|
|
|
|
|
try {
|
|
|
|
|
|
/// 如果list长度大于0
|
|
|
|
|
|
if (!giftArray.isEmpty()) {
|
|
|
|
|
|
/// gift的实体类则赋值,取list中的第一个数据
|
|
|
|
|
|
giftModel = giftArray.get(0);
|
|
|
|
|
|
/// 移除list的第一条数据
|
|
|
|
|
|
giftArray.remove(0);
|
|
|
|
|
|
isLoadEffect = true;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
isLoadEffect = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
/// 解锁
|
|
|
|
|
|
lock.unlock();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (isLoadEffect && giftModel != null && !TextUtils.isEmpty(giftModel)) {
|
|
|
|
|
|
String finalGiftModel = giftModel;
|
2025-12-12 23:15:30 +08:00
|
|
|
|
post(() -> {
|
|
|
|
|
|
String playImage = finalGiftModel;
|
|
|
|
|
|
if (playImage.endsWith("mp4")) {
|
|
|
|
|
|
downloadAndPlay(getContext(), playImage, new DownloadCallback() {
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onSuccess(File file) {
|
|
|
|
|
|
post(() -> {
|
|
|
|
|
|
playerMp4View.setVisibility(View.VISIBLE);
|
|
|
|
|
|
svgaView.setVisibility(View.GONE);
|
|
|
|
|
|
playerMp4View.startPlay(file);
|
|
|
|
|
|
});
|
2025-10-24 17:55:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-12 23:15:30 +08:00
|
|
|
|
@Override
|
|
|
|
|
|
public void onFailure(Exception e) {
|
|
|
|
|
|
LogUtils.e("MP4下载或播放失败: " + e.getMessage());
|
|
|
|
|
|
// 处理失败情况,继续播放下一个
|
|
|
|
|
|
post(() -> {
|
|
|
|
|
|
lock.lock();
|
|
|
|
|
|
try {
|
|
|
|
|
|
isLoadEffect = false;
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
lock.unlock();
|
|
|
|
|
|
}
|
|
|
|
|
|
loadStartSVGAPlayer();
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
} else if (playImage.endsWith("svga")) {
|
|
|
|
|
|
// File file = downloadAndPlay(getContext(), playImage);
|
|
|
|
|
|
post(() -> {
|
|
|
|
|
|
playerMp4View.setVisibility(View.GONE);
|
|
|
|
|
|
svgaView.setVisibility(View.VISIBLE);
|
|
|
|
|
|
svgaView.loadSVGAPlayerWith(finalGiftModel, false);
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
lock.lock();
|
|
|
|
|
|
try {
|
|
|
|
|
|
isLoadEffect = false;
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
lock.unlock();
|
|
|
|
|
|
}
|
|
|
|
|
|
loadStartSVGAPlayer();
|
|
|
|
|
|
// 直接播放缓存文件
|
2025-10-24 17:55:15 +08:00
|
|
|
|
}
|
2025-12-12 23:15:30 +08:00
|
|
|
|
|
2025-10-24 17:55:15 +08:00
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void downloadAndPlay(Context context, String playImage, DownloadCallback callback) {
|
|
|
|
|
|
String fileName = playImage.substring(playImage.lastIndexOf("/"));
|
|
|
|
|
|
String filePath = context.getCacheDir().getAbsolutePath() + fileName;
|
|
|
|
|
|
|
|
|
|
|
|
LogUtils.e("@@@@@filePath: " + filePath.toString());
|
|
|
|
|
|
|
|
|
|
|
|
File file = new File(filePath);
|
|
|
|
|
|
|
|
|
|
|
|
if (!file.exists()) {
|
|
|
|
|
|
LogUtils.e("无缓存");
|
|
|
|
|
|
// 使用OkHttp进行下载
|
|
|
|
|
|
OkHttpClient client = new OkHttpClient();
|
|
|
|
|
|
Request request = new Request.Builder()
|
|
|
|
|
|
.url(playImage)
|
|
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
|
|
client.newCall(request).enqueue(new Callback() {
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onFailure(Call call, IOException e) {
|
|
|
|
|
|
LogUtils.e("MP4下载失败: " + e.toString());
|
|
|
|
|
|
// 在主线程中回调失败
|
|
|
|
|
|
post(() -> {
|
|
|
|
|
|
if (callback != null) {
|
|
|
|
|
|
callback.onFailure(e);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onResponse(Call call, Response response) throws IOException {
|
|
|
|
|
|
if (response.isSuccessful()) {
|
|
|
|
|
|
try (ResponseBody responseBody = response.body()) {
|
|
|
|
|
|
if (responseBody != null) {
|
|
|
|
|
|
File downloadedFile = new File(filePath);
|
|
|
|
|
|
FileOutputStream fos = new FileOutputStream(downloadedFile);
|
|
|
|
|
|
fos.write(responseBody.bytes());
|
|
|
|
|
|
fos.close();
|
|
|
|
|
|
|
|
|
|
|
|
// 在主线程中回调成功
|
|
|
|
|
|
post(() -> {
|
|
|
|
|
|
if (callback != null) {
|
|
|
|
|
|
callback.onSuccess(downloadedFile);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 在主线程中回调失败
|
|
|
|
|
|
post(() -> {
|
|
|
|
|
|
if (callback != null) {
|
|
|
|
|
|
callback.onFailure(new IOException("Response body is null"));
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
LogUtils.e("MP4文件保存失败: " + e.getMessage());
|
|
|
|
|
|
// 在主线程中回调失败
|
|
|
|
|
|
post(() -> {
|
|
|
|
|
|
if (callback != null) {
|
|
|
|
|
|
callback.onFailure(e);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
LogUtils.e("MP4下载响应失败");
|
|
|
|
|
|
// 在主线程中回调失败
|
|
|
|
|
|
post(() -> {
|
|
|
|
|
|
if (callback != null) {
|
|
|
|
|
|
callback.onFailure(new IOException("Response not successful: " + response.code()));
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 文件已存在,直接回调成功
|
|
|
|
|
|
if (callback != null) {
|
|
|
|
|
|
callback.onSuccess(file);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加回调接口
|
|
|
|
|
|
public interface DownloadCallback {
|
|
|
|
|
|
void onSuccess(File file);
|
|
|
|
|
|
|
|
|
|
|
|
void onFailure(Exception e);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void destroyEffectView() {
|
|
|
|
|
|
removeSvgaQueueData();
|
|
|
|
|
|
svgaView.stopEffectSvgaPlay();
|
|
|
|
|
|
playerMp4View.stopPlay();
|
|
|
|
|
|
// 清理监听器
|
|
|
|
|
|
clearPlaybackCompleteListeners();
|
|
|
|
|
|
removeView(playerMp4View);
|
|
|
|
|
|
removeView(svgaView);
|
|
|
|
|
|
svgaView = null;
|
|
|
|
|
|
playerMp4View = null;
|
|
|
|
|
|
playModel = null;
|
|
|
|
|
|
|
|
|
|
|
|
if (queue != null) {
|
|
|
|
|
|
queue.shutdown();
|
|
|
|
|
|
queue = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void removeSvgaQueueData() {
|
|
|
|
|
|
lock.lock();
|
|
|
|
|
|
try {
|
|
|
|
|
|
giftArray.clear();
|
|
|
|
|
|
isLoadEffect = false;
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
lock.unlock();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private String getFileExtension(String url) {
|
|
|
|
|
|
if (url != null && url.contains(".")) {
|
|
|
|
|
|
return url.substring(url.lastIndexOf(".") + 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
return "";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onStartAnimation(GiftSvgaView view) {
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void onFinishedDisplay(GiftSvgaView view) {
|
|
|
|
|
|
post(() -> {
|
|
|
|
|
|
if (svgaView!=null) {
|
|
|
|
|
|
svgaView.setVisibility(View.GONE);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (isOnece){
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 通知播放完成
|
|
|
|
|
|
notifyPlaybackComplete();
|
|
|
|
|
|
loadStartSVGAPlayer();
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 在 GiftAnimView 类中添加播放完成监听接口
|
|
|
|
|
|
public interface OnPlaybackCompleteListener {
|
|
|
|
|
|
void onPlaybackComplete();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 在 GiftAnimView 类中添加成员变量
|
|
|
|
|
|
private List<OnPlaybackCompleteListener> playbackCompleteListeners = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
|
|
// 在 GiftAnimView 类中添加监听器管理方法
|
|
|
|
|
|
public void addOnPlaybackCompleteListener(OnPlaybackCompleteListener listener) {
|
|
|
|
|
|
if (listener != null && !playbackCompleteListeners.contains(listener)) {
|
|
|
|
|
|
playbackCompleteListeners.add(listener);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void removeOnPlaybackCompleteListener(OnPlaybackCompleteListener listener) {
|
|
|
|
|
|
if (listener != null) {
|
|
|
|
|
|
playbackCompleteListeners.remove(listener);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void clearPlaybackCompleteListeners() {
|
|
|
|
|
|
playbackCompleteListeners.clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 触发播放完成回调的方法
|
|
|
|
|
|
private void notifyPlaybackComplete() {
|
|
|
|
|
|
for (OnPlaybackCompleteListener listener : new ArrayList<>(playbackCompleteListeners)) {
|
|
|
|
|
|
if (listener != null) {
|
|
|
|
|
|
listener.onPlaybackComplete();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|