1:修改CP特效出现头像不规则的问题
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
package com.xscm.moduleutil.utils.roomview;
|
package com.xscm.moduleutil.utils.roomview;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -28,6 +29,7 @@ import com.tencent.qgame.animplayer.AnimView;
|
|||||||
import com.tencent.qgame.animplayer.inter.IAnimListener;
|
import com.tencent.qgame.animplayer.inter.IAnimListener;
|
||||||
import com.xscm.moduleutil.R;
|
import com.xscm.moduleutil.R;
|
||||||
import com.xscm.moduleutil.utils.ImageUtils;
|
import com.xscm.moduleutil.utils.ImageUtils;
|
||||||
|
import com.xscm.moduleutil.widget.CircularImage;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
@@ -51,79 +53,145 @@ import okhttp3.Response;
|
|||||||
import okhttp3.ResponseBody;
|
import okhttp3.ResponseBody;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 项目名称:羽声语音
|
* 羽声语音房间CP特效视图
|
||||||
|
* 用于显示CP(情侣)相关的动画特效,包括头像、名称和动画效果
|
||||||
|
* 支持MP4和SVGA格式的动画文件
|
||||||
* 时间:2025/11/24 9:50
|
* 时间:2025/11/24 9:50
|
||||||
* 用途:
|
|
||||||
*/
|
*/
|
||||||
public class RoomCPView extends FrameLayout {
|
public class RoomCPView extends FrameLayout {
|
||||||
|
// ==================== 视图组件 ====================
|
||||||
|
/** 动画视图组件 */
|
||||||
private AnimView anim_cp;
|
private AnimView anim_cp;
|
||||||
|
|
||||||
private boolean isLoadEffect = false;
|
/** CP头像组件 */
|
||||||
private boolean isShow = true; // 是否开启特效
|
private CircularImage room_cp_head1, room_cp_head2;
|
||||||
private ReentrantLock lock = new ReentrantLock();
|
|
||||||
private List<String> animationArray = new ArrayList<>();
|
|
||||||
public ExecutorService queue = Executors.newSingleThreadExecutor();
|
|
||||||
private Context mContext;
|
|
||||||
private boolean isOnece;
|
|
||||||
|
|
||||||
private RoundedImageView room_cp_head1;
|
/** CP名称组件 */
|
||||||
private RoundedImageView room_cp_head2;
|
|
||||||
private TextView room_cp_name1, room_cp_name2;
|
private TextView room_cp_name1, room_cp_name2;
|
||||||
|
|
||||||
|
/** 头像容器 */
|
||||||
private LinearLayout avatarContainer1;
|
private LinearLayout avatarContainer1;
|
||||||
|
|
||||||
|
/** 头像父容器 */
|
||||||
private ConstraintLayout avatarsParentContainer;
|
private ConstraintLayout avatarsParentContainer;
|
||||||
|
|
||||||
// 动画队列和锁机制
|
// ==================== 状态控制 ====================
|
||||||
private final Queue<AnimationTask> animationQueue = new LinkedList<>();
|
/** 是否正在加载特效 */
|
||||||
private boolean isAnimationRunning = false;
|
private boolean isLoadEffect = false;
|
||||||
private final Object animationLock = new Object();
|
|
||||||
|
|
||||||
// 下载任务缓存
|
/** 是否开启特效显示 */
|
||||||
private final Queue<DownloadTask> downloadQueue = new LinkedList<>();
|
private boolean isShow = true;
|
||||||
private boolean isDownloadRunning = false;
|
|
||||||
private final Object downloadLock = new Object();
|
|
||||||
|
|
||||||
|
/** 是否仅播放一次 */
|
||||||
|
private boolean isOnece;
|
||||||
|
|
||||||
|
/** 当前播放的动画路径 */
|
||||||
private String currPlayPath = "";
|
private String currPlayPath = "";
|
||||||
|
|
||||||
|
// ==================== 线程安全 ====================
|
||||||
|
/** 动画数组锁 */
|
||||||
|
private ReentrantLock lock = new ReentrantLock();
|
||||||
|
|
||||||
|
/** 动画队列锁 */
|
||||||
|
private final Object animationLock = new Object();
|
||||||
|
|
||||||
|
/** 下载队列锁 */
|
||||||
|
private final Object downloadLock = new Object();
|
||||||
|
|
||||||
|
// ==================== 数据存储 ====================
|
||||||
|
/** 动画路径列表 */
|
||||||
|
private List<String> animationArray = new ArrayList<>();
|
||||||
|
|
||||||
|
/** 动画任务队列 */
|
||||||
|
private final Queue<AnimationTask> animationQueue = new LinkedList<>();
|
||||||
|
|
||||||
|
/** 下载任务队列 */
|
||||||
|
private final Queue<DownloadTask> downloadQueue = new LinkedList<>();
|
||||||
|
|
||||||
|
// ==================== 状态标志 ====================
|
||||||
|
/** 是否有动画正在运行 */
|
||||||
|
private boolean isAnimationRunning = false;
|
||||||
|
|
||||||
|
/** 是否有下载任务正在运行 */
|
||||||
|
private boolean isDownloadRunning = false;
|
||||||
|
|
||||||
|
// ==================== 线程池 ====================
|
||||||
|
/** 任务执行线程池 */
|
||||||
|
public ExecutorService queue = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
|
// ==================== 其他 ====================
|
||||||
|
/** 上下文对象 */
|
||||||
|
private Context mContext;
|
||||||
|
|
||||||
|
/** 播放完成监听器列表 */
|
||||||
|
private List<OnPlaybackCompleteListener> playbackCompleteListeners = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置线程池
|
||||||
|
* @param queue 线程池
|
||||||
|
*/
|
||||||
public void setQueue(ExecutorService queue) {
|
public void setQueue(ExecutorService queue) {
|
||||||
this.queue = queue;
|
this.queue = queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基本构造函数
|
||||||
|
* @param context 上下文
|
||||||
|
*/
|
||||||
public RoomCPView(@NonNull Context context) {
|
public RoomCPView(@NonNull Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
this.mContext = context;
|
this.mContext = context;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 带属性集的构造函数
|
||||||
|
* @param context 上下文
|
||||||
|
* @param attrs 属性集
|
||||||
|
*/
|
||||||
public RoomCPView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
public RoomCPView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
this.mContext = context;
|
this.mContext = context;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 带属性集和样式属性的构造函数
|
||||||
|
* @param context 上下文
|
||||||
|
* @param attrs 属性集
|
||||||
|
* @param defStyleAttr 默认样式属性
|
||||||
|
*/
|
||||||
public RoomCPView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
public RoomCPView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, defStyleAttr);
|
super(context, attrs, defStyleAttr);
|
||||||
this.mContext = context;
|
this.mContext = context;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 完整构造函数
|
||||||
|
* @param context 上下文
|
||||||
|
* @param attrs 属性集
|
||||||
|
* @param defStyleAttr 默认样式属性
|
||||||
|
* @param defStyleRes 默认样式资源
|
||||||
|
*/
|
||||||
public RoomCPView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
public RoomCPView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
this.mContext = context;
|
this.mContext = context;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化视图和状态
|
||||||
|
*/
|
||||||
private void init() {
|
private void init() {
|
||||||
isLoadEffect = false;
|
isLoadEffect = false;
|
||||||
|
|
||||||
initView();
|
initView();
|
||||||
|
|
||||||
// 设置动画监听器
|
|
||||||
setupAnimListener();
|
setupAnimListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置动画监听器
|
* 设置动画监听器
|
||||||
|
* 为动画视图设置各种状态回调,包括开始、完成、失败等事件
|
||||||
*/
|
*/
|
||||||
private void setupAnimListener() {
|
private void setupAnimListener() {
|
||||||
if (anim_cp != null) {
|
if (anim_cp != null) {
|
||||||
@@ -149,9 +217,28 @@ public class RoomCPView extends FrameLayout {
|
|||||||
if (isOnece) {
|
if (isOnece) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加延迟,确保当前动画完全结束
|
||||||
|
postDelayed(() -> {
|
||||||
|
// 使用动画队列锁确保线程安全
|
||||||
|
synchronized (animationLock) {
|
||||||
|
// 重置播放状态
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
isLoadEffect = false;
|
||||||
|
// 标记动画已停止运行
|
||||||
|
isAnimationRunning = false;
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
// 通知播放完成
|
// 通知播放完成
|
||||||
notifyPlaybackComplete();
|
notifyPlaybackComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 继续播放下一个动画
|
||||||
loadStartAnimation();
|
loadStartAnimation();
|
||||||
|
}, 100); // 添加100毫秒的延迟
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -177,6 +264,7 @@ public class RoomCPView extends FrameLayout {
|
|||||||
// startAvatarFloatAnimation();
|
// startAvatarFloatAnimation();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/**************** c361dac4fe23498d925fba2efe376ca8 ****************/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onVideoConfigReady(@NonNull AnimConfig animConfig) {
|
public boolean onVideoConfigReady(@NonNull AnimConfig animConfig) {
|
||||||
@@ -192,6 +280,20 @@ public class RoomCPView extends FrameLayout {
|
|||||||
// 动画失败,隐藏视图
|
// 动画失败,隐藏视图
|
||||||
setVisibility(View.GONE);
|
setVisibility(View.GONE);
|
||||||
anim_cp.setVisibility(View.GONE);
|
anim_cp.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
// 使用动画队列锁确保线程安全
|
||||||
|
synchronized (animationLock) {
|
||||||
|
// 重置播放状态
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
isLoadEffect = false;
|
||||||
|
// 标记动画已停止运行
|
||||||
|
isAnimationRunning = false;
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 继续播放下一个
|
// 继续播放下一个
|
||||||
loadStartAnimation();
|
loadStartAnimation();
|
||||||
});
|
});
|
||||||
@@ -200,55 +302,90 @@ public class RoomCPView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化视图组件
|
||||||
|
* 加载布局文件并获取各个视图组件的引用
|
||||||
|
*/
|
||||||
private void initView() {
|
private void initView() {
|
||||||
|
// 加载布局文件
|
||||||
LayoutInflater.from(getContext()).inflate(R.layout.room_cp_vip_view, this, true);
|
LayoutInflater.from(getContext()).inflate(R.layout.room_cp_vip_view, this, true);
|
||||||
|
|
||||||
|
// 获取动画视图组件
|
||||||
anim_cp = findViewById(R.id.anim_cp);
|
anim_cp = findViewById(R.id.anim_cp);
|
||||||
|
|
||||||
|
// 获取头像组件
|
||||||
room_cp_head1 = findViewById(R.id.room_cp_head1);
|
room_cp_head1 = findViewById(R.id.room_cp_head1);
|
||||||
room_cp_head2 = findViewById(R.id.room_cp_head2);
|
room_cp_head2 = findViewById(R.id.room_cp_head2);
|
||||||
|
|
||||||
|
// 获取名称组件
|
||||||
room_cp_name1 = findViewById(R.id.room_cp_name1);
|
room_cp_name1 = findViewById(R.id.room_cp_name1);
|
||||||
room_cp_name2 = findViewById(R.id.room_cp_name2);
|
room_cp_name2 = findViewById(R.id.room_cp_name2);
|
||||||
|
|
||||||
// 获取头像的父布局
|
// 获取头像容器
|
||||||
avatarContainer1 = findViewById(R.id.ll_head);
|
avatarContainer1 = findViewById(R.id.ll_head);
|
||||||
|
|
||||||
// 获取包含两个头像的父 LinearLayout
|
// 获取包含两个头像的父容器
|
||||||
avatarsParentContainer = (ConstraintLayout) avatarContainer1.getParent();
|
avatarsParentContainer = (ConstraintLayout) avatarContainer1.getParent();
|
||||||
|
|
||||||
// // 初始状态隐藏头像和名称
|
// 注释:初始状态隐藏头像和名称(如需要可取消注释)
|
||||||
// room_cp_head1.setVisibility(View.GONE);
|
// room_cp_head1.setVisibility(View.GONE);
|
||||||
// room_cp_head2.setVisibility(View.GONE);
|
// room_cp_head2.setVisibility(View.GONE);
|
||||||
// room_cp_name1.setVisibility(View.GONE);
|
// room_cp_name1.setVisibility(View.GONE);
|
||||||
// room_cp_name2.setVisibility(View.GONE);
|
// room_cp_name2.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置CP信息数据
|
||||||
|
* @param room_head1 第一个用户头像URL
|
||||||
|
* @param room_head2 第二个用户头像URL
|
||||||
|
* @param room_cp_name1 第一个用户名称
|
||||||
|
* @param room_cp_name2 第二个用户名称
|
||||||
|
*/
|
||||||
public void setCPTextData(String room_head1, String room_head2, String room_cp_name1, String room_cp_name2) {
|
public void setCPTextData(String room_head1, String room_head2, String room_cp_name1, String room_cp_name2) {
|
||||||
|
// 加载用户头像
|
||||||
ImageUtils.loadHead(room_head1, room_cp_head1);
|
ImageUtils.loadHead(room_head1, room_cp_head1);
|
||||||
ImageUtils.loadHead(room_head2, room_cp_head2);
|
ImageUtils.loadHead(room_head2, room_cp_head2);
|
||||||
|
|
||||||
|
// 设置用户名称
|
||||||
this.room_cp_name1.setText(room_cp_name1);
|
this.room_cp_name1.setText(room_cp_name1);
|
||||||
this.room_cp_name2.setText(room_cp_name2);
|
this.room_cp_name2.setText(room_cp_name2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载并开始播放动画
|
||||||
|
* 从动画队列中取出下一个动画进行播放
|
||||||
|
*/
|
||||||
private void loadStartAnimation() {
|
private void loadStartAnimation() {
|
||||||
|
// 检查是否开启特效
|
||||||
if (!isShow) {
|
if (!isShow) {
|
||||||
// isshow 为是否开启特效 如果未开启则return
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用动画队列锁确保线程安全
|
||||||
|
synchronized (animationLock) {
|
||||||
|
// 如果已经有动画在运行,则直接返回,等待当前动画完成后再处理下一个
|
||||||
|
if (isAnimationRunning) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String animationPath = null;
|
String animationPath = null;
|
||||||
|
|
||||||
// list加锁
|
// 对动画列表加锁
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
// 如果list长度大于0
|
// 检查动画队列是否为空
|
||||||
if (!animationArray.isEmpty()) {
|
if (!animationArray.isEmpty()) {
|
||||||
// 动画路径则赋值,取list中的第一个数据
|
// 获取队列中的第一个动画路径
|
||||||
animationPath = animationArray.get(0);
|
animationPath = animationArray.get(0);
|
||||||
// 移除list的第一条数据
|
// 从队列中移除已获取的动画
|
||||||
animationArray.remove(0);
|
animationArray.remove(0);
|
||||||
|
|
||||||
|
// 设置状态标记
|
||||||
isLoadEffect = true;
|
isLoadEffect = true;
|
||||||
|
isAnimationRunning = true;
|
||||||
} else {
|
} else {
|
||||||
|
// 队列为空,重置状态并释放资源
|
||||||
isLoadEffect = false;
|
isLoadEffect = false;
|
||||||
// 队列为空,释放资源但不销毁视图
|
|
||||||
post(() -> {
|
post(() -> {
|
||||||
destroyEffectView();
|
destroyEffectView();
|
||||||
});
|
});
|
||||||
@@ -258,6 +395,7 @@ public class RoomCPView extends FrameLayout {
|
|||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果有动画需要播放
|
||||||
if (isLoadEffect && animationPath != null && !TextUtils.isEmpty(animationPath)) {
|
if (isLoadEffect && animationPath != null && !TextUtils.isEmpty(animationPath)) {
|
||||||
String finalAnimationPath = animationPath;
|
String finalAnimationPath = animationPath;
|
||||||
post(new Runnable() {
|
post(new Runnable() {
|
||||||
@@ -268,12 +406,11 @@ public class RoomCPView extends FrameLayout {
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(String localPath) {
|
public void onSuccess(String localPath) {
|
||||||
post(() -> {
|
post(() -> {
|
||||||
// 设置MP4动画文件
|
// 设置当前播放路径
|
||||||
currPlayPath = localPath;
|
currPlayPath = localPath;
|
||||||
// 启动从底部弹起动画
|
// 启动从底部弹起动画
|
||||||
startBottomUpAnimation();
|
startBottomUpAnimation();
|
||||||
|
// 设置播放次数为1次
|
||||||
// 开始播放动画
|
|
||||||
anim_cp.setLoop(1);
|
anim_cp.setLoop(1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -283,12 +420,18 @@ public class RoomCPView extends FrameLayout {
|
|||||||
LogUtils.e("MP4下载或播放失败: " + error);
|
LogUtils.e("MP4下载或播放失败: " + error);
|
||||||
// 处理失败情况,继续播放下一个
|
// 处理失败情况,继续播放下一个
|
||||||
post(() -> {
|
post(() -> {
|
||||||
|
// 使用动画队列锁确保线程安全
|
||||||
|
synchronized (animationLock) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
|
// 重置状态标记
|
||||||
isLoadEffect = false;
|
isLoadEffect = false;
|
||||||
|
isAnimationRunning = false;
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// 尝试播放下一个动画
|
||||||
loadStartAnimation();
|
loadStartAnimation();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -297,29 +440,31 @@ public class RoomCPView extends FrameLayout {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CP特效进来
|
* 显示CP特效
|
||||||
* @param room_head1 头像1
|
* 设置CP信息并添加动画到队列中播放
|
||||||
* @param room_head2 头像2
|
* @param room_head1 第一个用户头像URL
|
||||||
* @param room_name1 名称1
|
* @param room_head2 第二个用户头像URL
|
||||||
* @param room_name2 名称2
|
* @param room_name1 第一个用户名称
|
||||||
* @param mp4Path MP4动画文件路径
|
* @param room_name2 第二个用户名称
|
||||||
|
* @param mp4Path 动画文件路径(支持mp4和svga格式)
|
||||||
*/
|
*/
|
||||||
public void displayEffectView(String room_head1, String room_head2, String room_name1, String room_name2, String mp4Path) {
|
public void displayEffectView(String room_head1, String room_head2, String room_name1, String room_name2, String mp4Path) {
|
||||||
// 确保视图已初始化
|
// 确保视图已初始化
|
||||||
reinitView();
|
reinitView();
|
||||||
|
|
||||||
// 设置CP数据,但不显示头像
|
// 设置CP数据
|
||||||
setCPTextData(room_head1, room_head2, room_name1, room_name2);
|
setCPTextData(room_head1, room_head2, room_name1, room_name2);
|
||||||
|
|
||||||
// 确保头像初始为隐藏状态
|
// 注释:确保头像初始为隐藏状态(如需要可取消注释)
|
||||||
// room_cp_head1.setVisibility(View.GONE);
|
// room_cp_head1.setVisibility(View.GONE);
|
||||||
// room_cp_head2.setVisibility(View.GONE);
|
// room_cp_head2.setVisibility(View.GONE);
|
||||||
// room_cp_name1.setVisibility(View.GONE);
|
// room_cp_name1.setVisibility(View.GONE);
|
||||||
// room_cp_name2.setVisibility(View.GONE);
|
// room_cp_name2.setVisibility(View.GONE);
|
||||||
|
|
||||||
// 确保视图可见
|
// 确保视图可见
|
||||||
setVisibility(View.VISIBLE);
|
setVisibility(View.VISIBLE);
|
||||||
@@ -329,32 +474,32 @@ public class RoomCPView extends FrameLayout {
|
|||||||
queue = Executors.newSingleThreadExecutor();
|
queue = Executors.newSingleThreadExecutor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 在后台线程中处理动画
|
||||||
queue.execute(new Runnable() {
|
queue.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// 如果mp4Path不存在return
|
// 检查动画路径是否有效
|
||||||
if (mp4Path == null || mp4Path.isEmpty()) {
|
if (mp4Path == null || mp4Path.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将mp4Path链接转为小写
|
// 获取文件扩展名并转为小写
|
||||||
String playImage = mp4Path;
|
String playImage = mp4Path;
|
||||||
String pathExtension = getFileExtension(playImage).toLowerCase();
|
String pathExtension = getFileExtension(playImage).toLowerCase();
|
||||||
|
|
||||||
// 判定礼物的后缀是否为svga或者mp4如果非这两种 则return
|
// 检查文件格式是否支持(仅支持svga和mp4)
|
||||||
if (!("svga".equals(pathExtension) || "mp4".equals(pathExtension))) {
|
if (!("svga".equals(pathExtension) || "mp4".equals(pathExtension))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 锁住list
|
// 对动画列表加锁
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
// 添加动画数据进list
|
// 将动画路径添加到队列
|
||||||
animationArray.add(playImage);
|
animationArray.add(playImage);
|
||||||
|
|
||||||
// 如果没有在加载则开始加载
|
// 如果当前没有动画在加载,则开始加载新动画
|
||||||
if (!isLoadEffect) {
|
if (!isLoadEffect) {
|
||||||
// 更改加载状态标记
|
|
||||||
isLoadEffect = true;
|
isLoadEffect = true;
|
||||||
loadStartAnimation();
|
loadStartAnimation();
|
||||||
}
|
}
|
||||||
@@ -420,7 +565,6 @@ public class RoomCPView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 添加成员变量
|
// 添加成员变量
|
||||||
private List<OnPlaybackCompleteListener> playbackCompleteListeners = new ArrayList<>();
|
|
||||||
|
|
||||||
// 添加监听器管理方法
|
// 添加监听器管理方法
|
||||||
public void addOnPlaybackCompleteListener(OnPlaybackCompleteListener listener) {
|
public void addOnPlaybackCompleteListener(OnPlaybackCompleteListener listener) {
|
||||||
@@ -658,14 +802,18 @@ public class RoomCPView extends FrameLayout {
|
|||||||
setVisibility(View.GONE);
|
setVisibility(View.GONE);
|
||||||
|
|
||||||
// 清空动画队列
|
// 清空动画队列
|
||||||
|
synchronized (animationLock) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
animationArray.clear();
|
animationArray.clear();
|
||||||
isLoadEffect = false;
|
isLoadEffect = false;
|
||||||
|
// 重置动画运行状态
|
||||||
|
isAnimationRunning = false;
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从底部弹起动画
|
* 从底部弹起动画
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<com.makeramen.roundedimageview.RoundedImageView
|
<com.xscm.moduleutil.widget.CircularImage
|
||||||
android:id="@+id/room_cp_head1"
|
android:id="@+id/room_cp_head1"
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
android:layout_height="40dp"
|
android:layout_height="40dp"
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<com.makeramen.roundedimageview.RoundedImageView
|
<com.xscm.moduleutil.widget.CircularImage
|
||||||
android:id="@+id/room_cp_head2"
|
android:id="@+id/room_cp_head2"
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
android:layout_height="40dp"
|
android:layout_height="40dp"
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
android:id="@+id/tv_gift_name"
|
android:id="@+id/tv_gift_name"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/dp_5"
|
||||||
tools:text="礼物名称"
|
tools:text="礼物名称"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:textColor="@color/color_FF333333"
|
android:textColor="@color/color_FF333333"
|
||||||
|
|||||||
Reference in New Issue
Block a user