如何解决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 举报,一经查实,本站将立刻删除。