Android Studio/ReviewMate

[Android Studio/Kotlin] 영화 스크롤해서 다음페이지보여주기

kangchaewon 2023. 12. 6. 01:17

영화 스크롤해서 다음페이지보여주기

기존: 첫번째 페이지만 영화가 나타남

수정 후: 스크롤로 다음 페이지도 보여짐

중요 코드

 private fun MoviesFetched(movies: List<Movie>) {
        ListMoviesAdapter.appendMovies(movies)
        // 스클롤설정
        **attachListMoviesOnScrollListener()**
    }

    // 스크롤로 페이지 넘김
    private fun **attachListMoviesOnScrollListener**() {
        ListMoviesRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                val totalItemCount = ListMoviesLayoutManager.itemCount
                val visibleItemCount = ListMoviesLayoutManager.childCount
                val firstVisibleItem = ListMoviesLayoutManager.findFirstVisibleItemPosition()

                if (firstVisibleItem + visibleItemCount >= totalItemCount / 2) {
                    ListMoviesRecyclerView.removeOnScrollListener(this)
                    page++
                    getPopularMovies()
                }
            }
        })
    }
package com.example.reviewmate

class ListFragment : Fragment() {
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null

    private lateinit var ListMoviesRecyclerView: RecyclerView
    private lateinit var ListMoviesAdapter: MovieAdapter
    private lateinit var ListMoviesLayoutManager: LinearLayoutManager

    private lateinit var binding : FragmentListBinding
     var page : Int = 1

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onStart() {
        super.onStart()

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?

    ): View? {
        binding = FragmentListBinding.inflate(inflater, container, false)

        // recyclerView Setting
        ListMoviesRecyclerView = binding.root.findViewById(R.id.feedRecyclerView)
        ListMoviesLayoutManager = GridLayoutManager(
            context,
            3, // 열의 개수
            RecyclerView.VERTICAL, // 아이템의 배치 방향 (수직)
            false // 리사이클러뷰 크기가 변하지 않음
        )
        ListMoviesRecyclerView.layoutManager = ListMoviesLayoutManager
        ListMoviesAdapter = MovieAdapter(mutableListOf()){ movie -> showMovieDetails(movie) }
        ListMoviesRecyclerView.adapter = ListMoviesAdapter

        val message = arguments?.getInt("message")
        when(message){
            1 -> {
                getPopularMovies()
                getPopularMovies()
            }
            2 -> {
                getTopRatedMovies()
            }
            3 -> {
                getUpcomingMovies()
            }
        }
        return binding.root

    }
==============================================================
>>>추가 코드
    private fun MoviesFetched(movies: List<Movie>) {
        ListMoviesAdapter.appendMovies(movies)
        // 스클롤설정
        **attachPopularMoviesOnScrollListener()**
    }

    // 스크롤로 페이지 넘김
    private fun **attachPopularMoviesOnScrollListener**() {
        ListMoviesRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                val totalItemCount = ListMoviesLayoutManager.itemCount
                val visibleItemCount = ListMoviesLayoutManager.childCount
                val firstVisibleItem = ListMoviesLayoutManager.findFirstVisibleItemPosition()

                if (firstVisibleItem + visibleItemCount >= totalItemCount / 2) {
                    ListMoviesRecyclerView.removeOnScrollListener(this)
                    page++
                    getPopularMovies()
                }
            }
        })
    }

==============================================================
    private fun showMovieDetails(movie: Movie) {
        val intent = Intent(activity, MovieDetailsActivity::class.java)
        intent.putExtra(MainActivity.MOVIE_BACKDROP, movie.movieBackdrop)
        intent.putExtra(MainActivity.MOVIE_POSTER, movie.moviePoster)
        intent.putExtra(MainActivity.MOVIE_TITLE, movie.movieTitle)
        intent.putExtra(MainActivity.MOVIE_RATING, movie.movieRate)
        intent.putExtra(MainActivity.MOVIE_RELEASE_DATE, movie.movieDate)
        intent.putExtra(MainActivity.MOVIE_OVERVIEW, movie.movieOverview)
        intent.putExtra(MainActivity.MOVIE_ID, movie.movieId)
        startActivity(intent)
    }

    private fun getPopularMovies() {
        MoviesRepository.getPopularMovies(
            page++,
            ::MoviesFetched,
            ::onError
        )

    }

    private fun getTopRatedMovies() {
        MoviesRepository.getTopRatedMovies(
            1,
            ::MoviesFetched,
            ::onError
        )
    }

    private fun getUpcomingMovies() {
        MoviesRepository.getUpcomingMovies(
            1,
            ::MoviesFetched,
            ::onError
        )
    }

    private fun onError() {
        Toast.makeText(activity, "error Movies", Toast.LENGTH_SHORT).show()
    }

}
class MovieAdapter (var movies : MutableList, var onMovieClick:(movie:Movie) -> Unit) : RecyclerView.Adapter(){
    val extraPlus = Movie()
    inner class MovieViewHolder(val binding: ItemMovieBinding) : RecyclerView.ViewHolder(binding.root) {
        private val poster: ImageView = itemView.findViewById(R.id.item_movie_poster)
        fun bind(movie: Movie) {
            Glide.with(itemView)
                .load("<https://image.tmdb.org/t/p/w342${movie.moviePoster}>")
                .transform(CenterCrop())
                .into(poster)
            binding.itemMovieTitle.text = movie.movieTitle

            itemView.setOnClickListener { onMovieClick.invoke(movie) }
            if(movie == extraPlus) {
                binding.itemMoviePoster.setOnClickListener {
                    Log.d("movies", "add movies")
                }
            }

        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieViewHolder {
        val view = LayoutInflater
            .from(parent.context)
            .inflate(R.layout.item_movie, parent, false)
        return MovieViewHolder(ItemMovieBinding.inflate(
            LayoutInflater.from(parent.context),
            parent,
            false // 직접 사용하면 안되기 때문
        ))
    }

    override fun getItemCount(): Int = movies.size

    override fun onBindViewHolder(holder: MovieViewHolder, position: Int) {
        holder.bind(movies[position])
    }

    fun removeMovies(movies: List) {
        this.movies.removeAll(movies)
    }

    fun appendMovies(movies: List) {
        this.movies.addAll(movies)
        notifyItemRangeInserted(
            this.movies.size,
            movies.size - 1
        )
    }
}

 

Untitled.mp4
19.46MB

참고: 영화 정보 앱 만들기 - TMDB API 사용, 인기 영화 정보 가져오기 2 (tistory.com)