Android项目背景动效-Kotlin

1.建立空的kotlin项目

具体的操作过程不赘述。

在build.gradle里面添加如下代码,开启databinding

复制代码
  buildFeatures {
        compose = true
        dataBinding = true
    }

2.放置资源

准备一张静态的图,和一张动图mp4播放

我放置的文件夹位置可供参考

3.编码部分

首先,承载动图的view是VideoView,为了长宽和我们设备相同以达到全屏的效果。所以我们需要自己写一个类继承VideoView然后重写onMeasure方法

java 复制代码
public class CustomerVideoView extends VideoView {

    public CustomerVideoView(Context context) {
        super(context);
    }

    public CustomerVideoView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomerVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 其实就是在这里做了一些处理。
        int width = getDefaultSize(0, widthMeasureSpec);
        int height = getDefaultSize(0, heightMeasureSpec);
        setMeasuredDimension(width, height);
    }
}

然后在activity里面

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<layout>
    <androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
        <com.dfl.kotlinhello.view.CustomerVideoView
            android:id="@+id/video_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentTop="true"
            android:layout_alignParentBottom="true"
            android:layout_gravity="center" />

        <ImageView
            android:id="@+id/layer_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

CustomerVideoView就是拿来承载全屏的动图的,ImageView是静态图。

在MainActivity里面:

Kotlin 复制代码
class MainActivity : ComponentActivity() {
    private lateinit var binding: MainActivityBinding
    private val layerImage: ImageView by lazy {
        findViewById(R.id.layer_image)
    }
    private var videoPath = ""
    private val videoView: VideoView by lazy {
        findViewById(R.id.video_view)
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = MainActivityBinding.inflate(layoutInflater)
        setContentView(binding.root)

        initView()
    }

    private fun initView() {
        initVideoView()
    }

    private fun initVideoView() {
        videoPath = Uri.parse("android.resource://" + packageName + "/" + R.raw.firefly).toString()
        binding.layerImage.setBackgroundResource(R.drawable.firefly)
        videoView.setAudioFocusRequest(AudioManager.AUDIOFOCUS_NONE);
        startVideo()
        videoView.setOnPreparedListener { mp ->
            mp.setOnInfoListener { mp1, what, extra ->
                if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
                    videoView.setBackgroundColor(Color.TRANSPARENT)
                    layerImage.visibility = View.GONE
                }
                true
            }
            mp.start()
            mp.isLooping = true
        }
        videoView.setOnCompletionListener {
            videoView.setVideoPath(videoPath)
            videoView.start()
        }
    }

    private fun startVideo() {
        if (videoPath.isEmpty()) {
            return
        }
        videoView.setVideoPath(videoPath)
        videoView.start()
    }

}

这边主要做的就是视频路径设置与初始化 ‌--->音频焦点管理

因为不需要它播放所以要设置音频焦点为None

视频预加载与渲染监听

  • OnPreparedListener中设置OnInfoListener来监测视频渲染状态
  • 当检测到MEDIA_INFO_VIDEO_RENDERING_START时,将VideoView背景设为透明并隐藏静态图片层,实现平滑过渡

播放控制配置

  • 视频准备完成后自动开始播放
  • 设置isLooping = true启用循环播放模式

播放完成处理

  • 通过OnCompletionListener在视频播放结束时重新设置路径并重启播放,确保无缝循环

setLooping(true)负责主要的自动循环,而OnCompletionListener中的重新设置路径和启动操作确保了即使内置循环失效,视频也能继续播放

相关推荐
草莓熊Lotso3 小时前
Linux 文件描述符与重定向实战:从原理到 minishell 实现
android·linux·运维·服务器·数据库·c++·人工智能
傻乐u兔3 小时前
C语言进阶————指针4
c语言·开发语言
大模型玩家七七3 小时前
基于语义切分 vs 基于结构切分的实际差异
java·开发语言·数据库·安全·batch
历程里程碑3 小时前
Linux22 文件系统
linux·运维·c语言·开发语言·数据结构·c++·算法
恋猫de小郭3 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
牛奔4 小时前
Go 如何避免频繁抢占?
开发语言·后端·golang
寻星探路8 小时前
【深度长文】万字攻克网络原理:从 HTTP 报文解构到 HTTPS 终极加密逻辑
java·开发语言·网络·python·http·ai·https
工程师老罗10 小时前
如何在Android工程中配置NDK版本
android
lly20240610 小时前
Bootstrap 警告框
开发语言
2601_9491465310 小时前
C语言语音通知接口接入教程:如何使用C语言直接调用语音预警API
c语言·开发语言