본문 바로가기

프로그래밍/영화 TMDB API

영화 정보 앱 만들기 - TMDB API 사용, 영화 상세 정보 화면

반응형

영화 상세 정보 화면 이동

 

완성하면 아래 앱이 됩니다.

https://play.google.com/store/apps/details?id=com.enigmah2k.movieinfo

 

영화정보 - Google Play 앱

영화 또는 TV 시리즈 정보를 검색할 수 있습니다. TMDB API를 사용하여 만들었습니다. 한국에 소개되지 않은 컨텐츠를 찾을 수 있습니다.

play.google.com

 

상세 정보 화면을 구성해 보겠습니다.

 

1. Detail 정보를 나타낼 Activity 추가

마우스 오른쪽 클릭을 하여 New > Activity > Empty Activity 를 선택합니다.

Activity Name 을 MovieDetailsActivity 로 입력하고 Finish 합니다.

 

이렇게 Activity를 추가하면 AndroidManifest.xml에 아래 값이 자동으로 추가됩니다.

<activity android:name=".MovieDetailsActivity"></activity>

 

layout 파일인 activity_movie_details.xml 파일도 자동으로 추가됩니다.

 

2. layout 구성 - activity_movie_details.xml 

아래와 같이 구성합니다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

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

        <ImageView
            android:id="@+id/movie_backdrop"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="@+id/backdrop_guideline"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <androidx.cardview.widget.CardView
            android:id="@+id/movie_poster_card"
            android:layout_width="128dp"
            android:layout_height="172dp"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="8dp"
            app:cardCornerRadius="4dp"
            app:layout_constraintBottom_toBottomOf="@+id/backdrop_guideline"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/backdrop_guideline">

            <ImageView
                android:id="@+id/movie_poster"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        </androidx.cardview.widget.CardView>

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/backdrop_guideline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.4" />

        <TextView
            android:id="@+id/movie_title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:textColor="@android:color/white"
            android:textSize="18sp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/movie_poster_card"
            app:layout_constraintTop_toBottomOf="@+id/backdrop_guideline" />

        <TextView
            android:id="@+id/movie_release_date"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#757575"
            android:textSize="12sp"
            app:layout_constraintStart_toStartOf="@+id/movie_title"
            app:layout_constraintTop_toBottomOf="@+id/movie_title" />

        <androidx.constraintlayout.widget.Barrier
            android:id="@+id/movie_poster_title_barrier"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:barrierDirection="bottom"
            app:constraint_referenced_ids="movie_rating,movie_release_date" />

        <TextView
            android:id="@+id/movie_overview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/movie_poster_title_barrier" />

        <RatingBar
            android:id="@+id/movie_rating"
            style="@style/Widget.AppCompat.RatingBar.Small"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            app:layout_constraintEnd_toEndOf="@+id/movie_poster_card"
            app:layout_constraintStart_toStartOf="@+id/movie_poster_card"
            app:layout_constraintTop_toBottomOf="@+id/movie_poster_card" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

 

3. MoviesAdapter 에 setOnClickListener 를 추가합니다.

class MoviesAdapter (var movies: MutableList<Movie>, var onMovieClick: (movie: Movie) -> Unit
                        ) : RecyclerView.Adapter<MoviesAdapter.MovieViewHolder>(){

bind() 함수에 Listener 를 추가합니다.

itemView.setOnClickListener { onMovieClick.invoke(movie) }

 

 

4. MainActivity.kt에 Intent 로 전달할 Extra name을 추가합니다.

    companion object {
        const val MOVIE_BACKDROP = "extra_movie_backdrop"
        const val MOVIE_POSTER = "extra_movie_poster"
        const val MOVIE_TITLE = "extra_movie_title"
        const val MOVIE_RATING = "extra_movie_rating"
        const val MOVIE_RELEASE_DATE = "extra_movie_release_date"
        const val MOVIE_OVERVIEW = "extra_movie_overview"
    }

 

5. MovieDetailsActivity.kt 추가

상세 화면에 표시할 값들을 설정합니다.

MainActivity 에서 Extra 파라메터로 넘어온 값들로 표시합니다.

package com.tmdb.tmdbtest

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ImageView
import android.widget.RatingBar
import android.widget.TextView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.tmdb.tmdbtest.MainActivity.Companion.MOVIE_BACKDROP
import com.tmdb.tmdbtest.MainActivity.Companion.MOVIE_OVERVIEW
import com.tmdb.tmdbtest.MainActivity.Companion.MOVIE_POSTER
import com.tmdb.tmdbtest.MainActivity.Companion.MOVIE_RATING
import com.tmdb.tmdbtest.MainActivity.Companion.MOVIE_RELEASE_DATE
import com.tmdb.tmdbtest.MainActivity.Companion.MOVIE_TITLE

class MovieDetailsActivity : AppCompatActivity() {

    private lateinit var backdrop: ImageView
    private lateinit var poster: ImageView
    private lateinit var title: TextView
    private lateinit var rating: RatingBar
    private lateinit var releaseDate: TextView
    private lateinit var overview: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_movie_details)

        backdrop = findViewById(R.id.movie_backdrop)
        poster = findViewById(R.id.movie_poster)
        title = findViewById(R.id.movie_title)
        rating = findViewById(R.id.movie_rating)
        releaseDate = findViewById(R.id.movie_release_date)
        overview = findViewById(R.id.movie_overview)

        val extras = intent.extras

        if (extras != null) {
            populateDetails(extras)
        } else {
            finish()
        }
    }


    private fun populateDetails(extras: Bundle) {
        extras.getString(MOVIE_BACKDROP)?.let { backdropPath ->
            Glide.with(this)
                .load("https://image.tmdb.org/t/p/w1280$backdropPath")
                .transform(CenterCrop())
                .into(backdrop)
        }

        extras.getString(MOVIE_POSTER)?.let { posterPath ->
            Glide.with(this)
                .load("https://image.tmdb.org/t/p/w342$posterPath")
                .transform(CenterCrop())
                .into(poster)
        }

        title.text = extras.getString(MOVIE_TITLE, "")
        rating.rating = extras.getFloat(MOVIE_RATING, 0f) / 2
        releaseDate.text = extras.getString(MOVIE_RELEASE_DATE, "")
        overview.text = extras.getString(MOVIE_OVERVIEW, "")
    }
}

 

 

6. MovieDetailsActivity 를 실행하는 인텐트 추가 MovieFragment.kt 수정

    private fun showMovieDetails(movie: Movie) {
        val intent = Intent(activity, MovieDetailsActivity::class.java)
        intent.putExtra(MainActivity.MOVIE_BACKDROP, movie.backdrop_path)
        intent.putExtra(MainActivity.MOVIE_POSTER, movie.poster_path)
        intent.putExtra(MainActivity.MOVIE_TITLE, movie.title)
        intent.putExtra(MainActivity.MOVIE_RATING, movie.rating)
        intent.putExtra(MainActivity.MOVIE_RELEASE_DATE, movie.releaseDate)
        intent.putExtra(MainActivity.MOVIE_OVERVIEW, movie.overview)
        startActivity(intent)
    }

 

 

7. Detail Activity 호출 - MovieFragment.kt 수정

Adapter 에 추가한 ClickListener 관련 { movie -> showMovieDetails(movie) } 파라메터를 넘겨줍니다.

 

아래와 같은 형식으로 다섯가지에 모두 추가합니다.

popularMoviesAdapter = MoviesAdapter(mutableListOf()) { movie -> showMovieDetails(movie) }

 

 

영화를 선택하면 상세 화면이 실행되는 것을 확인할 수 있습니다.

 

다음에는 TV정보를 얻어오는 것을 해 보겠습니다.

영화 정보 얻어오는 것과 거의 유사합니다.

 

TMDB API 를 활용한 Android 앱 만들기

https://stockant.tistory.com/530

 

 

반응형