Не работает вывод видеороликов добавленных в избранное

Рейтинг: 0Ответов: 1Опубликовано: 22.05.2023

Пишу курсовой и не совсем понимаю, как правильно вывести видеоролики, добавленные в избранное. В базу они заносятся и вроде как нормально. Вывод обычных видео на главную страницу работает.

Нерабочая часть:

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

Ответы

▲ 0

Уверен, это не самое идеальное решение, но мало ли кому-то пригодится:

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() {
    val favoriteVideoIds = ArrayList<String>()
    videoArrayList = ArrayList()

    val userId = firebaseAuth.currentUser?.uid
    userId?.let { uid ->
        val favoriteRef =
            FirebaseDatabase.getInstance()
                .getReference("Users/$uid/Favorites")
        favoriteRef.addValueEventListener(object : ValueEventListener {
            override fun onDataChange(snapshot: DataSnapshot) {
                favoriteVideoIds.clear()
                for (ds in snapshot.children) {
                    val videoId = ds.key.toString() // Получаем идентификаторы видео
                    favoriteVideoIds.add(videoId)
                }

                // Запрос для получения списка видео из основной коллекции и их фильтрация по идентификаторам
                val videosRef =
                    FirebaseDatabase.getInstance()
                        .getReference("Videos")
                videosRef.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 (favoriteVideoIds.contains(ds.key.toString())) {
                                    videoArrayList.add(video)
                                }
                            }
                        }
                        adapterVideo.videoArrayList = videoArrayList
                        adapterVideo.notifyDataSetChanged()
                    }

                    override fun onCancelled(error: DatabaseError) {
                        Toast.makeText(
                            context,
                            "Database error: " + error.message,
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                })
            }

            override fun onCancelled(error: DatabaseError) {
                Toast.makeText(context, "Database error: " + error.message, Toast.LENGTH_SHORT)
                    .show()
            }
        })
    }
}
}