Skip to content
This repository has been archived by the owner. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions HomeWorkNetwork/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ plugins {
android {
compileSdk 31

Properties localProperties = new Properties()
localProperties.load(project.rootProject.file('local.properties').newDataInputStream())

defaultConfig {

buildConfigField "String", "API_BASE_URL", '"api.themoviedb.org"'
buildConfigField "String", "API_KEY", '"/*ваш ap_key*/"'
buildConfigField "String", "API_BASE_URL", '"api.themoviedb.org/3"'
/* API_KEY защищен в local.properties */
buildConfigField "String", "API_KEY", "\"${localProperties.getProperty('TMDB_API_KEY')}\""
buildConfigField "String", "API_IMAGE_BASE_URL", '"https://image.tmdb.org/t/p/w500"'

applicationId "com.pg.homeworknetwork"
Expand Down Expand Up @@ -46,4 +50,15 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'

//ktor
def ktor_version = "1.6.8"
implementation "io.ktor:ktor-client-core:$ktor_version"
implementation "io.ktor:ktor-client-android:$ktor_version"
implementation "io.ktor:ktor-client-serialization:$ktor_version"
implementation "io.ktor:ktor-client-logging:$ktor_version"
implementation "ch.qos.logback:logback-classic:1.2.3"

//serialization
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.0"
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.pg.homeworknetwork
package com.pg.homeworknetwork.adapter

import android.view.LayoutInflater
import android.view.View
Expand All @@ -12,6 +12,9 @@ import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.transform.RoundedCornersTransformation
import com.pg.homeworknetwork.BuildConfig
import com.pg.homeworknetwork.R
import com.pg.homeworknetwork.model.Movie

internal class MovieItemAdapter : ListAdapter<Movie, MovieItemAdapter.ViewHolder>(MOVIE_COMPARATOR) {
private var clickListener: IOnItemClick? = null
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.pg.homeworknetwork.fragment

import android.os.Bundle
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.activity.OnBackPressedCallback
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import coil.load
import coil.transform.RoundedCornersTransformation
import com.pg.homeworknetwork.BuildConfig
import com.pg.homeworknetwork.R
import com.pg.homeworknetwork.model.Movie
import com.pg.homeworknetwork.repo.TmdbRepo
import kotlinx.coroutines.*

class MovieDetailFragment : Fragment(R.layout.fragment_movie_preview) {
lateinit var poster: ImageView
private lateinit var originalTitle: TextView
lateinit var overview: TextView
private lateinit var popularity: TextView
private lateinit var releaseDate: TextView

private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
with(view) {
poster = findViewById(R.id.poster)
originalTitle = findViewById(R.id.originalTitle)
overview = findViewById(R.id.overview)
popularity = findViewById(R.id.popularity)
releaseDate = findViewById(R.id.releaseDate)
}

val movieId = arguments?.getInt(ARG_ID) ?: 550

scope.launch {
TmdbRepo.getMovie(movieId)?.let {
poster.load("${BuildConfig.API_IMAGE_BASE_URL}${it.posterPath}") {
transformations(RoundedCornersTransformation(16f))
}
originalTitle.text = it.originalTitle
overview.text = it.overview
popularity.text = it.popularity.toString()
releaseDate.text = it.releaseDate
}
}

activity?.onBackPressedDispatcher?.addCallback(
this.viewLifecycleOwner,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
val manager: FragmentManager = parentFragmentManager
val transaction: FragmentTransaction = manager.beginTransaction()
transaction.replace(R.id.mainFragment, MovieListFragment())
transaction.commit()
}
})
}

companion object {
const val TAG = "MovieDetailFragment"
const val ARG_ID = "MovieDetailFragment_Arguments_Movie_Id"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.pg.homeworknetwork
package com.pg.homeworknetwork.fragment

import android.os.Bundle
import android.view.View
Expand All @@ -7,16 +7,24 @@ import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.pg.homeworknetwork.R
import com.pg.homeworknetwork.adapter.MovieItemAdapter
import com.pg.homeworknetwork.model.Movie
import com.pg.homeworknetwork.repo.TmdbRepo
import kotlinx.coroutines.*

class MovieListFragment : Fragment(R.layout.fragment_movie_list) {
lateinit var recycler: RecyclerView

private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)

private val goToDetails = object : MovieItemAdapter.IOnItemClick {
override fun onItemClick(movie: Movie) {
val manager: FragmentManager = parentFragmentManager
val transaction: FragmentTransaction = manager.beginTransaction()
val detailsFragment = MovieDetailFragment()
detailsFragment.arguments = Bundle().apply { putInt(MovieDetailFragment.ARG_ID, movie.id) }
detailsFragment.arguments =
Bundle().apply { putInt(MovieDetailFragment.ARG_ID, movie.id) }
transaction.replace(R.id.mainFragment, detailsFragment)
transaction.commit()
}
Expand All @@ -31,8 +39,13 @@ class MovieListFragment : Fragment(R.layout.fragment_movie_list) {
}
}
val adapter = (recycler.adapter as MovieItemAdapter)
val movies = //получаем фильмы
adapter.submitList(movies)

scope.launch {
TmdbRepo.getMovies()?.let {
adapter.submitList(it.results)
}
}

super.onViewCreated(view, savedInstanceState)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.pg.homeworknetwork.model

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

/**
* Класс для описание фильма
*/
@Serializable
data class Movie(
val id: Int = 0,
val title: String = "",
@SerialName("original_title")
val originalTitle: String = "",
@SerialName("poster_path")
val posterPath: String? = null,
val overview: String? = null,
val popularity: Double = 0.0,
@SerialName("release_date")
val releaseDate: String = ""
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.pg.homeworknetwork.model

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

/**
* Класс для формирования ответа с сервера (/movies/popular)
*/
@Serializable
data class MoviesResponse(
val page: Int = 0,
val results: List<Movie> = emptyList(),
@SerialName("total_results")
val totalResults: Int = 0,
@SerialName("total_pages")
val totalPages: Int = 0
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.pg.homeworknetwork.network

import com.pg.homeworknetwork.BuildConfig
import io.ktor.client.*
import io.ktor.client.features.*
import io.ktor.client.features.json.*
import io.ktor.client.features.json.serializer.*
import io.ktor.client.features.logging.*
import io.ktor.client.request.*
import io.ktor.http.*
import kotlinx.serialization.json.Json

/**
* Ktor клиент
*/
object KtorClient {
private val json = Json {
encodeDefaults = true
ignoreUnknownKeys = true
}

val httpClient = HttpClient {
install(JsonFeature) {
serializer = KotlinxSerializer(json)
}

install(Logging) {
logger = object : Logger {
override fun log(message: String) {
if (message.contains("api_key"))
println(message.replaceAfter("api_key=", "api_key"))
else println(message)
}
}
level = LogLevel.ALL
}

defaultRequest {
host = BuildConfig.API_BASE_URL
url {
protocol = URLProtocol.HTTPS
}
parameter("api_key", BuildConfig.API_KEY)
contentType(ContentType.Application.Json)
accept(ContentType.Application.Json)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.pg.homeworknetwork.repo

import com.pg.homeworknetwork.model.Movie
import com.pg.homeworknetwork.model.MoviesResponse
import com.pg.homeworknetwork.network.KtorClient.httpClient
import io.ktor.client.features.*
import io.ktor.client.request.*

/**
* Repo для запросов
*/
object TmdbRepo {

/** Получает список фильмов [MoviesResponse] */
suspend fun getMovies(): MoviesResponse? =
try {
httpClient.get(path = "movie/popular")
} catch (e: ResponseException) {
println(e.response.status.description)
null
}

/** Получает фильм [Movie] по идентификатору [id] */
suspend fun getMovie(id: Int): Movie? =
try {
httpClient.get(path = "/movie/$id")
} catch (e: ResponseException) {
println(e.response.status.description)
null
}
}
2 changes: 1 addition & 1 deletion HomeWorkNetwork/app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<androidx.fragment.app.FragmentContainerView
android:id="@+id/mainFragment"
android:name="com.pg.homeworknetwork.MovieListFragment"
android:name="com.pg.homeworknetwork.fragment.MovieListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />

Expand Down