微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Android 同时播放动画和视频

如何解决Android 同时播放动画和视频

我正在做一个个人项目,我想要一个信息横幅在一个循环中一个一个显示一系列消息(这部分使用动画来运行)以及显示带有视频的标题(使用原始目录中的 mp4 视频和 VideoView)。

在布局方面,我有以下几点:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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=".ui.home.HomeFragment">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.textview.MaterialTextView
            android:id="@+id/shipping_information"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="?colorOnPrimary"
            app:layout_constraintBottom_toTopOf="@id/latest_products_header"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0" />

        <VideoView
            android:id="@+id/header_video"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            app:layout_constraintTop_toBottomOf="@id/shipping_information"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"/>
    </androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

总而言之,布局相当简单。我的以下部分是片段代码,类似地,它没有什么太复杂的事情(我将跳过视图模型,因为它只包含字符串列表的 LiveData):

@AndroidEntryPoint
class HomeFragment : BaseFragment() {

    private lateinit var binding: FragmentHomeBinding
    private val homeviewmodel: Homeviewmodel by viewmodels()
    override var showToolbar: Boolean = true

    override fun onAttach(context: Context) {
        super.onAttach(context)

        requireActivity().onBackpresseddispatcher.addCallback(
            this,object : OnBackpressedCallback(true) {
                override fun handleOnBackpressed() {
                    AlertDialog.Builder(requireActivity(),R.style.SidemenClothingTheme_Dialog_Alert)
                        .setTitle(R.string.exit_app_confirmation_title)
                        .setMessage(R.string.exit_app_confirmation_message)
                        .setPositiveButton(R.string.close) { _,_ ->
                            requireActivity().finish()
                        }.setNegativeButton(android.R.string.cancel) { _,_ -> }
                        .create().show()
                }
            }
        )
    }

    override fun onPause() {
        super.onPause()
        homeviewmodel.showLoading()
    }

    override fun onCreateView(
        inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?
    ): View? {
        binding = FragmentHomeBinding.inflate(inflater,container,false)

        return binding.root
    }

    override fun onViewCreated(view: View,savedInstanceState: Bundle?) {
        super.onViewCreated(view,savedInstanceState)

        homeviewmodel.setShippinginformation(listof(
            getString(R.string.worldwide_shipping),getString(R.string.free_shipping_international),getString(R.string.free_shipping_uk)
        ))

        homeviewmodel.shippinginformation.observe(viewLifecycleOwner,{ informationList ->
            binding.shippinginformation.startAnimation(animateinformationBanner(informationList))
        })

        setHeaderVideo()
    }

    private fun animateinformationBanner(information: List<String>,start: Int = 0): Animation {
        var index = start
        val animation = AnimationUtils.loadAnimation(
            binding.shippinginformation.context,R.anim.shipping_information_animation
        )
        animation.setAnimationListener(object : Animation.AnimationListener {
            override fun onAnimationStart(animation: Animation?) {
                binding.shippinginformation.text = information[index % information.size]
            }

            override fun onAnimationEnd(animation: Animation?) {
                index++
                binding.shippinginformation.text = null
                binding.shippinginformation.startAnimation(animation)
            }

            override fun onAnimationRepeat(animation: Animation?) {
                Todo("Not yet implemented")
            }
        })

        return animation
    }

    private fun setHeaderVideo() {
        val uri = Uri.parse("android.resource://" + requireActivity().packageName + "/" + R.raw.header_video)
        val mediaController = MediaController(requireActivity())
        mediaController.hide()
        mediaController.setAnchorView(binding.headerVideo)
        binding.headerVideo.setMediaController(mediaController)
        binding.headerVideo.setVideoURI(uri)

        binding.headerVideo.setonPreparedListener { mediaPlayer ->
            binding.headerVideo.layoutParams = ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT,ConstraintLayout.LayoutParams.WRAP_CONTENT)
            binding.headerVideo.requestFocus()
            binding.headerVideo.start()
            mediaPlayer.isLooping = true
        }
        binding.headerVideo.setZOrderOnTop(true)
    }
}

最后,我为 TextView 制作了这个动画:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true">

    <translate
        android:fromXDelta="100%p"
        android:toXDelta="0%p"
        android:duration="2000"/>

    <translate
        android:startOffset="3500"
        android:fromXDelta="0%p"
        android:toXDelta="-100%p"
        android:duration="2000"/>
</set>

你们中的一些人可能已经从经验中看到了我遇到的问题。对于那些不这样做的人,按原样使用代码,我的应用程序只循环播放视频,但不执行 TextView 的动画。如果我删除视频,我只有 TextView 动画。我不是动画和视频方面的专家,但有些事情告诉我,事实上我有两个元素都在不断“播放”,应用程序无法同时执行这两个操作,因此只能执行最新的一个

我倾向于认为使用协程可以解决问题,但我缺乏知道从哪里开始的知识。

感谢任何帮助,谢谢!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。