<file_sep>package com.example.movieslillbox.presentation.detail

import androidx.lifecycle.ViewModel

class DetailMovieViewModel : ViewModel() {
    // TODO: Implement the ViewModel
}<file_sep>package com.example.movieslillbox.presentation.main

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.movieslillbox.data.api.MovieRetrofitService
import com.example.movieslillbox.data.models.Movie
import com.example.movieslillbox.utils.BASE_URL
import com.google.gson.Gson
import kotlinx.coroutines.launch
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

class MainViewModel : ViewModel() {

    val movieListData: MutableLiveData<List<Movie>> = MutableLiveData()

    init {
        val retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create(Gson()))
            .build()
        val api = retrofit.create(MovieRetrofitService::class.java)

        viewModelScope.launch {
            val result = api.getPopularMovie()
            result.body()?.movies.let {
                movieListData.postValue(it)
            }
        }
    }

}<file_sep>package com.example.movieslillbox.utils

import android.widget.ImageView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import com.bumptech.glide.Glide
import com.example.movieslillbox.R

fun ImageView.downloadAndSetImage(url: String) {
    Glide
        .with(APP_ACTIVITY)
        .load(url)
        .centerCrop()
        .placeholder(R.drawable.placeholder)
        .into(this)
}

fun replaceToFragment(fragment: Fragment) {
    APP_ACTIVITY.supportFragmentManager.beginTransaction()
        .replace(R.id.container_fragment, fragment)
        .addToBackStack(null)
        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
        .commit()
}<file_sep>package com.example.movieslillbox.utils

import com.example.movieslillbox.MainActivity

const val API_KEY = "<KEY>"
const val BASE_URL = "https://api.themoviedb.org/3/"
const val POSTER_BASE_URL = "https://image.tmdb.org/t/p/w342"
lateinit var APP_ACTIVITY:MainActivity<file_sep>"# MovieSkillbox" 
<file_sep>package com.example.movieslillbox.data.models

import com.google.gson.annotations.SerializedName

data class DetailMovie(
    val id: Int,
    val overview: String,
    @SerializedName("poster_path")
    val posterPath: String,
    val runtime: Int,
    val title: String,
    @SerializedName("vote_average")
    val rating: Double
)<file_sep>package com.example.movieslillbox.data.api

import com.example.movieslillbox.data.models.DetailMovie
import com.example.movieslillbox.data.models.MovieResponse
import com.example.movieslillbox.utils.API_KEY
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.Query

interface MovieRetrofitService {
    @GET("movie/popular")
    suspend fun getPopularMovie(@Query("api_key") apiKey:String = API_KEY) : Response<MovieResponse>

    @GET("movie/{movie_id}")
    suspend fun getMovieDetails(@Path("movie_id") id: Int): Response<DetailMovie>
}<file_sep>package com.example.movieslillbox.presentation.detail

import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.example.movieslillbox.R
import com.example.movieslillbox.utils.downloadAndSetImage
import kotlinx.android.synthetic.main.detail_movie_fragment.*

class DetailMovieFragment : Fragment(R.layout.detail_movie_fragment) {

    companion object {
        fun newInstance() = DetailMovieFragment()
    }

    private lateinit var viewModel: DetailMovieViewModel

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProvider(this).get(DetailMovieViewModel::class.java)

        val bundle = this.arguments
        movie_title_textView.text = bundle?.getString("title")
        release_date_textView.text = bundle?.getString("releaseDate")
        vote_average_textView.text = bundle?.getString("voteAverage")
        original_language_text_view.text = bundle?.getString("originalLanguage")
        overview_textView.text = bundle?.getString("overview")

        val posterUrl = bundle?.getString("poster")
        movie_poster_imageView.downloadAndSetImage(posterUrl.toString())
    }
}<file_sep>package com.example.movieslillbox.presentation.main.recyclerView

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.movieslillbox.R
import com.example.movieslillbox.data.models.Movie
import com.example.movieslillbox.presentation.detail.DetailMovieFragment
import com.example.movieslillbox.utils.POSTER_BASE_URL
import com.example.movieslillbox.utils.downloadAndSetImage
import com.example.movieslillbox.utils.replaceToFragment


class MovieAdapter(private val movieList: List<Movie>) :
    RecyclerView.Adapter<MovieAdapter.MovieHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieHolder {
        val view =
            LayoutInflater.from(parent.context).inflate(R.layout.main_fragment_item, parent, false)
        return MovieHolder(view)
    }

    override fun getItemCount(): Int = movieList.size

    override fun onBindViewHolder(holder: MovieHolder, position: Int) {
        holder.bindData(movieList, position)
    }

    class MovieHolder(view: View) : RecyclerView.ViewHolder(view) {
        private val title: TextView = itemView.findViewById(R.id.title_textView)
        private val voteAvg: TextView = itemView.findViewById(R.id.vote_average_textView)
        private val poster: ImageView = itemView.findViewById(R.id.poster_imageView)

        fun bindData(list: List<Movie>, position: Int) {
            val moviePosterURL = POSTER_BASE_URL + list[position].posterPath
            title.text = list[position].title
            voteAvg.text = list[position].voteAverage
            poster.downloadAndSetImage(moviePosterURL)
            itemView.setOnClickListener {
                val bundle = Bundle()
                bundle.putString("title", list[position].title)
                bundle.putString("releaseDate", list[position].releaseDate)
                bundle.putString("originalLanguage", list[position].originalLanguage)
                bundle.putString("overview", list[position].overview)
                bundle.putString("voteAverage", list[position].voteAverage)
                bundle.putString("poster", moviePosterURL)
                val detailMovieFragment = DetailMovieFragment()
                detailMovieFragment.arguments = bundle

                replaceToFragment(detailMovieFragment)
            }
        }
    }
}


<file_sep>package com.example.movieslillbox.presentation.main

import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.example.movieslillbox.R
import com.example.movieslillbox.presentation.main.recyclerView.GridAutofitLayoutManager
import com.example.movieslillbox.presentation.main.recyclerView.MovieAdapter
import com.example.movieslillbox.utils.APP_ACTIVITY
import kotlinx.android.synthetic.main.main_fragment.*

class MainFragment : Fragment(R.layout.main_fragment) {

    companion object {
        fun newInstance() = MainFragment()
    }

    private lateinit var viewModel: MainViewModel

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
        initRecyclerView()
    }

    private fun initRecyclerView() {
        val columnWidth = APP_ACTIVITY.resources.getDimension(R.dimen.poster_width).toInt()
        val recyclerList = main_recycler_view.apply {
            setHasFixedSize(true)
            layoutManager =
                GridAutofitLayoutManager(
                    APP_ACTIVITY,
                    columnWidth
                )
        }
        viewModel.movieListData.observe(viewLifecycleOwner, Observer {
            recyclerList?.adapter = MovieAdapter(it)
        })
    }

}<file_sep>package com.example.movieslillbox

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.example.movieslillbox.presentation.main.MainFragment
import com.example.movieslillbox.utils.APP_ACTIVITY


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)
        APP_ACTIVITY = this
        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                .replace(R.id.container_fragment, MainFragment.newInstance())
                .commitNow()
        }
    }
}