Не работает вывод видеороликов добавленных в избранное
Пишу курсовой и не совсем понимаю, как правильно вывести видеоролики, добавленные в избранное. В базу они заносятся и вроде как нормально. Вывод обычных видео на главную страницу работает.
Нерабочая часть:
class LikeFragment : Fragment() {
private lateinit var videoArrayList: ArrayList<ModelVideo>
private lateinit var adapterVideo: AdapterVideo
private lateinit var firebaseAuth: FirebaseAuth
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_like, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
firebaseAuth = FirebaseAuth.getInstance()
val videosR: RecyclerView = view.findViewById(R.id.likeRecyclerView)
adapterVideo = AdapterVideo(requireContext(), ArrayList(), firebaseAuth)
videosR.adapter = adapterVideo
loadFavoriteVideosFromFirebase()
}
private fun loadFavoriteVideosFromFirebase() {
videoArrayList = ArrayList()
val userId = firebaseAuth.currentUser?.uid
userId?.let { uid ->
val ref = FirebaseDatabase.getInstance()
.getReference("Users/$uid/Videos")
ref.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
videoArrayList.clear()
for (ds in snapshot.children) {
val modelVideo = ds.getValue(ModelVideo::class.java)
modelVideo?.let { video ->
if (video.isFavorite) {
videoArrayList.add(video)
}
}
}
adapterVideo.notifyDataSetChanged()
adapterVideo = AdapterVideo(requireContext(), videoArrayList, firebaseAuth)
val videosR: RecyclerView = view!!.findViewById(R.id.likeRecyclerView)
videosR.adapter = adapterVideo
}
override fun onCancelled(error: DatabaseError) {
Toast.makeText(context, "Database error: " + error.message, Toast.LENGTH_SHORT).show()
}
})
}
}
}
Рабочая часть:
class HomeFragment : Fragment() {
private lateinit var videoArrayList: ArrayList<ModelVideo>
private lateinit var adapterVideo: AdapterVideo
private lateinit var firebaseAuth: FirebaseAuth
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_home, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
firebaseAuth = FirebaseAuth.getInstance()
loadVideosFromFirebase()
}
private fun loadVideosFromFirebase() {
videoArrayList = ArrayList()
val ref = FirebaseDatabase.getInstance().getReference("Videos")
ref.addValueEventListener(object : ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
videoArrayList.clear()
for (ds in snapshot.children){
val modelVideo = ds.getValue(ModelVideo::class.java)
videoArrayList.add(modelVideo!!)
}
adapterVideo = AdapterVideo(requireContext(), videoArrayList, firebaseAuth)
val videosRv: RecyclerView = view!!.findViewById(R.id.videosRv)
videosRv.adapter = adapterVideo
}
override fun onCancelled(error: DatabaseError) {
Toast.makeText(context, "Database error: " + error.message, Toast.LENGTH_SHORT).show()
}
})
}
private fun toggleFavorite(videoModel: ModelVideo) {
videoModel.isFavorite = !videoModel.isFavorite
}
}
Сама модель вроде тоже правильная:
class ModelVideo {
var id: String? = null
var title: String? = null
var timestamp: String? = null
var videoUri: String? = null
var isFavorite: Boolean = false // Новое поле для отслеживания избранного
constructor(){
}
constructor(id: String?,title: String?, timestamp: String?, videoUri: String?){
this.id = id
this.title = title
this.timestamp = timestamp
this.videoUri = videoUri
this.isFavorite = isFavorite
}
}
А вот в адаптере не уверен, хотя в базу всё добавляет:
class AdapterVideo(
private var context: Context,
private var videoArrayList: ArrayList<ModelVideo>?,
private val firebaseAuth: FirebaseAuth
) :RecyclerView.Adapter<AdapterVideo.HolderVideo>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HolderVideo {
val view = LayoutInflater.from(context).inflate(R.layout.row_video,parent,false)
return HolderVideo(view)
}
override fun onBindViewHolder(holder: HolderVideo, position: Int){
val modelVideo = videoArrayList!![position]
val id: String? = modelVideo.id
val title: String? = modelVideo.title
val timestamp: String? = modelVideo.timestamp
val videoUri: String? = modelVideo.videoUri
val isFavorite = modelVideo.isFavorite
val calendar = Calendar.getInstance()
calendar.timeInMillis = timestamp!!.toLong()
val formattedDateInterval = android.text.format.DateFormat.format("dd/MM/yyyy K:mm a", calendar).toString()
holder.titleTv.text = title
holder.timeTv.text = formattedDateInterval
setVideoUrl(modelVideo, holder)
// Обработчик нажатия на кнопку избранного
holder.favoriteBtn.isSelected = isFavorite
holder.favoriteBtn.setOnClickListener {
val userId = firebaseAuth.currentUser?.uid
userId?.let { uid ->
// Обновление состояния избранного в базе данных
toggleFavorite(uid, id, !isFavorite)
}
}
}
private fun setVideoUrl(modelVideo: ModelVideo, holder: HolderVideo) {
holder.progressBar.visibility = View.VISIBLE
val videoUrl: String? = modelVideo.videoUri
val mediaController = MediaController(context)
mediaController.setAnchorView(holder.videoView)
val videoUri = Uri.parse(videoUrl)
holder.videoView.setMediaController(mediaController)
holder.videoView.setVideoURI(videoUri)
holder.videoView.requestFocus()
holder.videoView.setOnPreparedListener{mediaPlayer ->
mediaPlayer.start()
}
holder.videoView.setOnInfoListener(MediaPlayer.OnInfoListener{mp, what, extra->
when(what){
MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START ->{
holder.progressBar.visibility = View.GONE
return@OnInfoListener true
}
MediaPlayer.MEDIA_INFO_BUFFERING_START -> {
holder.progressBar.visibility = View.GONE
return@OnInfoListener true
}
MediaPlayer.MEDIA_INFO_BUFFERING_END -> {
holder.progressBar.visibility = View.GONE
return@OnInfoListener true
}
}
false
})
holder.videoView.setOnCompletionListener { mediaPlayer ->
mediaPlayer.start()
}
}
override fun getItemCount(): Int {
return videoArrayList!!.size
}
class HolderVideo(itemView: View) : RecyclerView.ViewHolder(itemView){
var videoView:VideoView = itemView.findViewById(R.id.videoView)
var titleTv:TextView = itemView.findViewById(R.id.titleTv)
var timeTv:TextView = itemView.findViewById(R.id.timeTv)
var progressBar:ProgressBar = itemView.findViewById(R.id.progressBar)
var favoriteBtn: ImageButton = itemView.findViewById(R.id.favoriteBtn)
}
interface FavoriteToggleListener {
fun onFavoriteToggle(videoId: String, isFavorite: Boolean)
}
private fun toggleFavorite(userId: String, videoId: String?, isFavorite: Boolean) {
val databaseRef =
FirebaseDatabase.getInstance().getReference("Users/$userId/Videos/$videoId")
databaseRef.child("isFavorite").setValue(isFavorite)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
val listener = context as? FavoriteToggleListener
listener?.onFavoriteToggle(videoId!!, isFavorite)
} else {
// Обработка ошибки
Toast.makeText(context, "Failed to update favorite status", Toast.LENGTH_SHORT).show()
}
}
}
}
База для хранения избранного выглядит так:
Сколько уже сижу, не могу вдуплить как правильно это написать.
В Logcat нашёл такую ошибку:
No setter/field for isFavorite found on class com.example.videohost.ModelVideo
Could not find layer id -1
Источник: Stack Overflow на русском