0
点赞
收藏
分享

微信扫一扫

Java项目:61 ssm基于java的健身房管理系统的设计与实现+vue

戴老师成长记录仪 03-23 13:00 阅读 2
android

看效果

vap动画

代码

   // 腾讯 vap 动画
    implementation "io.github.tencent:vap:2.0.17"

package com.example.appvap

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Environment
import android.util.Log
import com.example.appvap.databinding.ActivityPlayDemoBinding
import com.example.appvap.tool.FileUtil
import com.tencent.qgame.animplayer.inter.IFetchResource
import com.tencent.qgame.animplayer.mix.Resource
import com.tencent.qgame.animplayer.util.ScaleType
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async 
import kotlinx.coroutines.withContext
import java.io.File
import java.util.Random

class PlayDemoActivity : AppCompatActivity() {

    companion object{
        val TAG = "PlayDemoActivity"
    }
    private lateinit var mContext: Context
    private lateinit var binding : ActivityPlayDemoBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mContext = this@PlayDemoActivity

        binding = ActivityPlayDemoBinding.inflate(layoutInflater)
        setContentView(binding.root)

        loadFile()
        initView()


    }

    private fun initView(){
        // 居中(根据父布局按比例居中并裁剪)
        binding.animView.setScaleType(ScaleType.CENTER_CROP)
        binding.btnPlay.setOnClickListener {
            setListener()
            play(videoInfo)
        }
    }

    private fun play(videoInfo: VideoInfo) {
        // 播放前强烈建议检查文件的md5是否有改变
        // 因为下载或文件存储过程中会出现文件损坏,导致无法播放
         CoroutineScope(Dispatchers.IO).async {
            val file = File(dir + "/" + videoInfo.fileName)
            val md5 = FileUtil.getFileMD5(file)
             withContext(Dispatchers.Main){
                 if (videoInfo.md5 == md5) {
                     // 开始播放动画文件
                     binding.animView.startPlay(file)
                 } else {
                     Log.e(TAG, "md5 is not match, error md5=$md5")
                 }
             }

        }

    }

    private var head1Img = true
    private fun setListener(){
        /**
         * 注册资源获取类
         */
        binding.animView.setFetchResource(object : IFetchResource {
            /**
             * 获取图片资源
             * 无论图片是否获取成功都必须回调 result 否则会无限等待资源
             */
            override fun fetchImage(resource: Resource, result: (Bitmap?) -> Unit) {
                /**
                 * srcTag是素材中的一个标记,在制作素材时定义
                 * 解析时由业务读取tag决定需要播放的内容是什么
                 * 比如:一个素材里需要显示多个头像,则需要定义多个不同的tag,表示不同位置,需要显示不同的头像,文字类似
                 */
                val srcTag = resource.tag
                if (srcTag.isNotEmpty()) {
                    val drawableId = if (head1Img) R.drawable.head1 else R.drawable.head2
                    head1Img = !head1Img
                    val options = BitmapFactory.Options()
                    options.inScaled = false
                    result(BitmapFactory.decodeResource(resources, drawableId, options))
                } else {
                    result(null)
                }
            }

            /**
             * 获取文字资源
             */
            override fun fetchText(resource: Resource, result: (String?) -> Unit) {
                val str = "恭喜 No.${1000 + Random().nextInt(8999)}用户 升神"
                val srcTag = resource.tag
                if (srcTag.isNotEmpty()) { // 此tag是已经写入到动画配置中的tag
                    result(str)
                } else {
                    result(null)
                }
            }

            /**
             * 播放完毕后的资源回收
             */
            override fun releaseResource(resources: List<Resource>) {
                resources.forEach {
                    it.bitmap?.recycle()
                }
            }
        })
    }



    // 视频信息
    data class VideoInfo(val fileName: String, val md5: String)
    private val videoInfo = VideoInfo("vapx.mp4", "f981e0f094ead842ad5ae99f1ffaa1a1")

    private val dir by lazy {
        // 存放在sdcard应用缓存文件中
        getExternalFilesDir(null)?.absolutePath ?: Environment.getExternalStorageDirectory().path
    }
    private fun loadFile() {

        CoroutineScope(Dispatchers.IO).async {
            val files = Array(1) {
                videoInfo.fileName
            }
            FileUtil.copyAssetsToStorage(mContext, dir, files) {

            }
        }


    }

}
<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".PlayDemoActivity">


    <com.tencent.qgame.animplayer.AnimView
        android:id="@+id/animView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <Button
        android:id="@+id/btnPlay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="播放"/>

    <Button
        android:id="@+id/btnStop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/btnPlay"
        android:text="停止"/>
</androidx.constraintlayout.widget.ConstraintLayout>

举报

相关推荐

0 条评论