个性装扮展示完成

This commit is contained in:
2025-06-09 09:14:47 +08:00
parent 53ade75f84
commit aa865a69b3
10 changed files with 824 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
package com.qxcm.moduleutil.bean;
import lombok.Data;
/**
*@author qx
*@data 2025/6/7
*@description: 装扮类型表
*/
@Data
public class PersonaltyBean {
private String id;
private String name;
}

View File

@@ -0,0 +1,39 @@
package com.qxcm.moduleutil.bean;
/**
*@author qx
*@data 2025/6/7
*@description:
*/
public class SvgaModel {
public static final int TYPE_GIFT = 0;
public static final int TYPE_JUE = 1;
public static final int TYPE_JUE_AND_APPROACH = 2;
public static final int TYPE_APPROACH = 3;
public String url;
public int type;
public String approachUrl;
public String userName;
public String nobilityName;
public SvgaModel() {
}
public SvgaModel(String url) {
this.type=TYPE_GIFT;
this.url = url;
}
public SvgaModel(String url, int type) {
this.url = url;
this.type = type;
}
public SvgaModel(String url, int type, String approachUrl, String userName, String nobilityName) {
this.url = url;
this.type = type;
this.approachUrl = approachUrl;
this.userName = userName;
this.nobilityName=nobilityName;
}
}

View File

@@ -0,0 +1,296 @@
package com.qxcm.moduleutil.widget;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.net.Uri;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.View;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import com.blankj.utilcode.util.PathUtils;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.ui.PlayerView;
import com.liulishuo.okdownload.DownloadTask;
import com.liulishuo.okdownload.StatusUtil;
import com.liulishuo.okdownload.core.cause.EndCause;
import com.liulishuo.okdownload.core.cause.ResumeFailedCause;
import com.liulishuo.okdownload.core.listener.DownloadListener1;
import com.liulishuo.okdownload.core.listener.assist.Listener1Assist;
import com.opensource.svgaplayer.SVGADrawable;
import com.opensource.svgaplayer.SVGADynamicEntity;
import com.opensource.svgaplayer.SVGAImageView;
import com.opensource.svgaplayer.SVGAParser;
import com.opensource.svgaplayer.SVGAVideoEntity;
import com.qxcm.moduleutil.R;
import com.qxcm.moduleutil.databinding.RoomViewSvgaAnimBinding;
import com.qxcm.moduleutil.utils.Md5Utils;
import com.qxcm.moduleutil.utils.logger.Logger;
import com.tencent.bugly.idasc.crashreport.CrashReport;
import com.tencent.qgame.animplayer.AnimConfig;
import com.tencent.qgame.animplayer.inter.IAnimListener;
import java.io.File;
import java.net.URL;
public class AvatarFrameView extends FrameLayout implements IAnimListener {
@Override
public void onFailed(int i, @Nullable String s) {
}
@Override
public boolean onVideoConfigReady(@NonNull AnimConfig animConfig) {
return true;
}
@Override
public void onVideoStart() {
}
@Override
public void onVideoRender(int i, @Nullable AnimConfig animConfig) {
}
@Override
public void onVideoComplete() {
if (mType == 1) {
mBinding.playView.startPlay(mFile);
}
}
@Override
public void onVideoDestroy() {
}
public enum RenderType {SVGA, MP4}
private RenderType renderType;
private ExoPlayer exoPlayer;
private PlayerView playerView;
private SVGAImageView svgaSurface;
private GLSurfaceView glSurfaceView;
private final Handler mainHandler = new Handler(Looper.getMainLooper());
private ChannelSplitRenderer1 renderer;
private int mType;//1:循环播放 2:播放一次停止播放
private File mFile;
private RoomViewSvgaAnimBinding mBinding;
public AvatarFrameView(@NonNull Context context) {
this(context, null);
}
public AvatarFrameView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public AvatarFrameView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.room_view_svga_anim, this, true);
initViews();
}
private void initViews() {
// 初始化 ExoPlayer View
playerView = new PlayerView(getContext());
playerView.setUseController(false);
playerView.setVisibility(View.GONE);
addView(playerView);
// 初始化 SVGA View
svgaSurface = new SVGAImageView(getContext());
svgaSurface.setVisibility(View.GONE);
addView(svgaSurface);
// // 初始化 GLSurfaceView
// glSurfaceView = new GLSurfaceView(getContext());
// glSurfaceView.setEGLContextClientVersion(2);
// renderer = new ChannelSplitRenderer1();
// glSurfaceView.setRenderer(renderer);
// glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
// glSurfaceView.setVisibility(View.GONE); // 默认隐藏
// addView(glSurfaceView);
// 初始化 ExoPlayer
exoPlayer = new ExoPlayer.Builder(getContext()).build();
playerView.setPlayer(exoPlayer);
mBinding.playView.setAnimListener(this);
}
public void setSource(String url, RenderType type, int type2) {
clearPrevious();
renderType = type;
mType = type2;
switch (type) {
case SVGA:
mBinding.playView.stopPlay();
mBinding.playView.setVisibility(View.GONE);
loadSVGA(url);
break;
case MP4:
// loadMP4(url);
mBinding.playView.setVisibility(View.VISIBLE);
downloadAndPlayMp4(url);
break;
}
}
private void downloadAndPlayMp4(String url) {
DownloadTask task = new DownloadTask.Builder(url, PathUtils.getInternalAppCachePath()
, Md5Utils.getStringMD5(url) + ".mp4")
// the minimal interval millisecond for callback progress
.setMinIntervalMillisCallbackProcess(100)
// do re-download even if the task has already been completed in the past.
.setPassIfAlreadyCompleted(false)
.setAutoCallbackToUIThread(true)
.build();
if (StatusUtil.isCompleted(task)) {
playMp4(task.getFile());
mFile = task.getFile();
} else {
task.enqueue(new DownloadListener1() {
@Override
public void taskStart(@NonNull DownloadTask task, @NonNull Listener1Assist.Listener1Model model) {
Logger.e("taskStart", model);
}
@Override
public void retry(@NonNull DownloadTask task, @NonNull ResumeFailedCause cause) {
Logger.e("retry", cause);
CrashReport.postCatchedException(new RuntimeException("下载文件重试:" + cause == null ? "" : cause.name()));
}
@Override
public void connected(@NonNull DownloadTask task, int blockCount, long currentOffset, long totalLength) {
Logger.e("connected", blockCount);
}
@Override
public void progress(@NonNull DownloadTask task, long currentOffset, long totalLength) {
Logger.e("progress", currentOffset);
}
@Override
public void taskEnd(@NonNull DownloadTask task, @NonNull EndCause cause, @Nullable Exception realCause, @NonNull Listener1Assist.Listener1Model model) {
Logger.e("taskEnd", model);
playMp4(task.getFile());
mFile = task.getFile();
if (cause != null && cause != EndCause.COMPLETED) {
// CrashReport.postCatchedException(new RuntimeException("下载任务结束:" + cause == null ? "" : cause.name() + "_realCause:" + realCause == null ? "" : realCause.getMessage()));
}
}
});
}
}
private void playMp4(File file) {
if (file != null) {
mBinding.playView.startPlay(file);
} else {
// showAnim();
// playMp4(file);
CrashReport.postCatchedException(new RuntimeException("播放MP4失败:File is null"));
}
}
private void loadSVGA(String url) {
svgaSurface.setVisibility(View.VISIBLE);
try {
new SVGAParser(getContext()).parse(new URL(url), new SVGAParser.ParseCompletion() {
@Override
public void onComplete(SVGAVideoEntity videoItem) {
SVGADrawable drawable = new SVGADrawable(videoItem, new SVGADynamicEntity());
svgaSurface.setImageDrawable(drawable);
svgaSurface.startAnimation();
}
@Override
public void onError() {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private void loadMP4(String url) {
svgaSurface.setVisibility(View.GONE);
playerView.setVisibility(View.GONE);
glSurfaceView.setVisibility(View.VISIBLE);
glSurfaceView.onResume();
glSurfaceView.requestRender();
// 使用 post 确保 GLSurfaceView 已完成 layout
glSurfaceView.post(() -> {
Log.d("@@@", "GLSurfaceView size after layout: " + glSurfaceView.getWidth() + "x" + glSurfaceView.getHeight());
glSurfaceView.onResume();
glSurfaceView.requestRender();
renderer.setOnSurfaceTextureReadyListener(surfaceTexture -> {
mainHandler.post(() -> {
Surface surface = new Surface(surfaceTexture);
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(url));
exoPlayer.setMediaItem(mediaItem);
exoPlayer.setVideoSurface(surface);
exoPlayer.prepare();
exoPlayer.play();
Log.d("@@@", "ExoPlayer state after play: " + exoPlayer.getPlaybackState());
});
});
});
}
private void clearPrevious() {
if (exoPlayer != null) {
exoPlayer.stop();
exoPlayer.clearVideoSurface();
}
if (svgaSurface.getDrawable() instanceof SVGADrawable) {
((SVGADrawable) svgaSurface.getDrawable()).stop();
}
if (playerView != null) playerView.setVisibility(View.GONE);
if (svgaSurface != null) svgaSurface.setVisibility(View.GONE);
// if (glSurfaceView != null) glSurfaceView.setVisibility(View.GONE);
mBinding.playView.setVisibility(View.GONE);
}
public void release() {
if (exoPlayer != null) {
exoPlayer.release();
}
if (svgaSurface.getDrawable() instanceof SVGADrawable) {
((SVGADrawable) svgaSurface.getDrawable()).stop();
}
if (glSurfaceView != null) {
glSurfaceView.onPause(); // 必须调用生命周期方法
// glSurfaceView.requestRender();
}
}
}

View File

@@ -0,0 +1,122 @@
package com.qxcm.moduleutil.widget
import android.graphics.SurfaceTexture
import android.opengl.GLES20
import android.opengl.Matrix
class ChannelSplitRenderer {
private val vertexShaderCode = """
attribute vec4 aPosition;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;
void main() {
gl_Position = aPosition;
vTexCoord = aTexCoord;
}
"""
private val fragmentShaderCode = """
precision mediump float;
uniform sampler2D uTexture;
varying vec2 vTexCoord;
void main() {
// 只使用左半部分作为最终颜色
vec2 leftCoord = vec2(vTexCoord.x * 0.5, vTexCoord.y);
vec4 color = texture2D(uTexture, leftCoord);
// 设置 alpha 为 1.0 表示完全不透明,或根据需求设为 0.0 表示全透明
gl_FragColor = vec4(color.rgb, 0.0); // 左通道颜色 + 不透明
}"""
private var program = 0
private var positionHandle = 0
private var texCoordHandle = 0
private var textureHandle = 0
private val projectionMatrix = FloatArray(16)
private val modelMatrix = FloatArray(16)
fun onSurfaceCreated(surface: SurfaceTexture, width: Int, height: Int) {
// 初始化着色器
val vertexShader = ShaderUtils.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode)
val fragmentShader = ShaderUtils.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode)
program = GLES20.glCreateProgram().also {
GLES20.glAttachShader(it, vertexShader)
GLES20.glAttachShader(it, fragmentShader)
GLES20.glLinkProgram(it)
}
positionHandle = GLES20.glGetAttribLocation(program, "aPosition")
texCoordHandle = GLES20.glGetAttribLocation(program, "aTexCoord")
textureHandle = GLES20.glGetUniformLocation(program, "uTexture")
// 初始化矩阵
Matrix.setIdentityM(projectionMatrix, 0)
Matrix.setIdentityM(modelMatrix, 0)
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f)
GLES20.glEnable(GLES20.GL_BLEND)
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA)
}
fun onSurfaceChanged(width: Int, height: Int) {
GLES20.glViewport(0, 0, width, height)
}
fun onDrawFrame(textureId: Int) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
GLES20.glUseProgram(program)
// 定义顶点坐标(全屏)
val vertices = floatArrayOf(
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f
)
// 修改纹理坐标,只映射左半部分视频内容到左侧屏幕
val texCoords = floatArrayOf(
0.0f, 1.0f, // 左下角
0.5f, 1.0f, // 右下角(对应视频中间)
0.0f, 0.0f, // 左上角
0.5f, 0.0f // 右上角
)
val vertexBuffer = ShaderUtils.createFloatBuffer(vertices)
val texBuffer = ShaderUtils.createFloatBuffer(texCoords)
GLES20.glEnableVertexAttribArray(positionHandle)
GLES20.glVertexAttribPointer(
positionHandle, 3,
GLES20.GL_FLOAT, false,
0, vertexBuffer
)
GLES20.glEnableVertexAttribArray(texCoordHandle)
GLES20.glVertexAttribPointer(
texCoordHandle, 2,
GLES20.GL_FLOAT, false,
0, texBuffer
)
// 绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0)
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId)
GLES20.glUniform1i(textureHandle, 0)
// 绘制
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4)
// 清理
GLES20.glDisableVertexAttribArray(positionHandle)
GLES20.glDisableVertexAttribArray(texCoordHandle)
}
fun release() {
GLES20.glDeleteProgram(program)
}
}

View File

@@ -0,0 +1,200 @@
package com.qxcm.moduleutil.widget;
import android.graphics.SurfaceTexture;
import android.opengl.EGL14;
import android.opengl.EGLConfig;
import android.opengl.EGLContext;
import android.opengl.EGLDisplay;
import android.opengl.EGLSurface;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.view.Surface;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
public class ChannelSplitRenderer1 implements GLSurfaceView.Renderer {
private static final String VERTEX_SHADER =
"uniform mat4 uMVPMatrix;\n" +
"uniform mat4 uSTMatrix;\n" +
"attribute vec4 aPosition;\n" +
"attribute vec4 aTextureCoord;\n" +
"varying vec2 vTextureCoord;\n" +
"void main() {\n" +
" gl_Position = uMVPMatrix * aPosition;\n" +
" vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
"}\n";
private static final String FRAGMENT_SHADER =
"#extension GL_OES_EGL_image_external : require\n" +
"precision mediump float;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform samplerExternalOES sTexture;\n" +
"void main() {\n" +
" vec2 uv = vTextureCoord;\n" +
" // 左边部分的 UV 坐标范围 (0.0, 0.1) 到 (0.6, 0.9)\n" +
" if (uv.x >= 0.0 && uv.x <= 0.6 && uv.y >= 0.1 && uv.y <= 0.9) {\n" +
" // 居中显示\n" +
" vec2 newUV = vec2(uv.x * (1.0 / 0.6), uv.y); // 水平方向拉伸\n" +
" gl_FragColor = texture2D(sTexture, newUV);\n" +
" } else {\n" +
" gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); // 设置为完全透明\n" +
" }\n" +
"}\n";
private int mProgram;
private int maPositionHandle;
private int maTextureHandle;
private int muMVPMatrixHandle;
private int muSTMatrixHandle;
private float[] mMVPMatrix = new float[16];
private float[] mSTMatrix = new float[16];
private SurfaceTexture surfaceTexture;
private int externalTextureId = -1;
private final float[] mTriangleVerticesData = {
// X, Y, Z, U, V
-1.0f, -1.0f, 0, 0.f, 0.f,
1.0f, -1.0f, 0, 1.f, 0.f,
-1.0f, 1.0f, 0, 0.f, 1.f,
1.0f, 1.0f, 0, 1.f, 1.f,
};
private FloatBuffer mTriangleVertices;
public ChannelSplitRenderer1() {
mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mTriangleVertices.put(mTriangleVerticesData).position(0);
Matrix.setIdentityM(mSTMatrix, 0);
}
public interface OnSurfaceTextureReadyListener {
void onSurfaceTextureReady(SurfaceTexture surfaceTexture);
}
private OnSurfaceTextureReadyListener surfaceTextureReadyListener;
public void setOnSurfaceTextureReadyListener(OnSurfaceTextureReadyListener listener) {
this.surfaceTextureReadyListener = listener;
}
@Override
public void onSurfaceCreated(GL10 gl, javax.microedition.khronos.egl.EGLConfig config) {
Log.d("@@@@", "onDrawFrame called");
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
GLES20.glDisable(GLES20.GL_STENCIL_TEST);
GLES20.glDisable(GLES20.GL_BLEND);
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 设置透明背景
int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
externalTextureId = textures[0];
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, externalTextureId);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
surfaceTexture = new SurfaceTexture(externalTextureId);
mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
if (surfaceTextureReadyListener != null) {
surfaceTextureReadyListener.onSurfaceTextureReady(surfaceTexture);
}
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
private long lastTimestamp = -1;
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
if (surfaceTexture != null) {
surfaceTexture.updateTexImage();
long timestamp = surfaceTexture.getTimestamp();
if (timestamp != lastTimestamp) {
Log.d("@@@", "New frame received, timestamp: " + timestamp);
lastTimestamp = timestamp;
}
surfaceTexture.getTransformMatrix(mSTMatrix);
} else {
Log.e("@@@", "SurfaceTexture is null in onDrawFrame");
}
GLES20.glUseProgram(mProgram);
Matrix.setIdentityM(mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
mTriangleVertices.position(0);
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 20, mTriangleVertices);
GLES20.glEnableVertexAttribArray(maPositionHandle);
mTriangleVertices.position(3);
GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, 20, mTriangleVertices);
GLES20.glEnableVertexAttribArray(maTextureHandle);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, externalTextureId);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
public SurfaceTexture getSurfaceTexture() {
return surfaceTexture;
}
private int loadShader(int shaderType, String source) {
int shader = GLES20.glCreateShader(shaderType);
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);
int[] compiled = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == 0) {
return 0;
}
return shader;
}
private int createProgram(String vertexSource, String fragmentSource) {
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
int program = GLES20.glCreateProgram();
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, pixelShader);
GLES20.glLinkProgram(program);
int[] linkStatus = new int[1];
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
if (linkStatus[0] != GLES20.GL_TRUE) {
return 0;
}
return program;
}
}

View File

@@ -0,0 +1,40 @@
package com.qxcm.moduleutil.widget;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.opengl.GLES20;
import android.util.Log;
public class ShaderUtils {
private static final String TAG = "ShaderUtils";
// 创建并编译着色器
public static int loadShader(int type, String shaderCode) {
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
int[] compiled = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == 0) {
Log.e(TAG, "Could NOT compile shader: " + GLES20.glGetShaderInfoLog(shader));
GLES20.glDeleteShader(shader);
return 0;
}
return shader;
}
// 创建 FloatBuffer
public static FloatBuffer createFloatBuffer(float[] array) {
ByteBuffer bb = ByteBuffer.allocateDirect(array.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer buffer = bb.asFloatBuffer();
buffer.put(array);
buffer.position(0);
return buffer;
}
}

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- <com.opensource.svgaplayer.SVGAImageView-->
<!-- android:id="@+id/image"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="0dp"-->
<!-- android:scaleType="fitCenter"-->
<!-- app:autoPlay="true"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toTopOf="parent"-->
<!-- app:loopCount="1" />-->
<com.tencent.qgame.animplayer.AnimView
android:id="@+id/play_view"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.opensource.svgaplayer.SVGAImageView
android:id="@+id/iv_approach"
android:layout_width="0dp"
android:layout_height="0dp"
app:autoPlay="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="750:667"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:loopCount="1" />
<com.opensource.svgaplayer.SVGAImageView
android:id="@+id/iv_ripple1"
android:layout_width="0dp"
android:layout_height="0dp"
app:autoPlay="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:loopCount="1" />
</androidx.constraintlayout.widget.ConstraintLayout>