Skip to content

Commit

Permalink
project ongoing - ...
Browse files Browse the repository at this point in the history
  • Loading branch information
HenryUdorji committed May 31, 2021
1 parent 6524166 commit a407892
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.henryudorji.theater.adapters

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.henryudorji.theater.data.model.Movie
import com.henryudorji.theater.databinding.MovieCustomLayoutBinding
import com.henryudorji.theater.utils.Constants.BASE_URL_IMAGE
import com.squareup.picasso.Picasso

//
// Created by hash on 5/3/2021.
//
class MovieListRecyclerAdapter(): RecyclerView.Adapter<MovieListRecyclerAdapter.MovieViewHolder>() {

inner class MovieViewHolder(val binding: MovieCustomLayoutBinding): RecyclerView.ViewHolder(binding.root)

private val differCallback = object: DiffUtil.ItemCallback<Movie>() {
override fun areItemsTheSame(oldItem: Movie, newItem: Movie): Boolean {
return oldItem.id == newItem.id
}

override fun areContentsTheSame(oldItem: Movie, newItem: Movie): Boolean {
return oldItem == newItem
}
}
val differ = AsyncListDiffer(this, differCallback)

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieViewHolder {
val binding = MovieCustomLayoutBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
return MovieViewHolder(binding)
}

override fun onBindViewHolder(holder: MovieViewHolder, position: Int) {
val movie = differ.currentList[position]

holder.binding.apply {
Picasso.get().load(BASE_URL_IMAGE + movie.posterPath).into(movieImage)
movieTitleText.text = movie.originalTitle
ratingText.text = movie.voteAverage.toString()
}
}

override fun getItemCount(): Int {
return differ.currentList.size
}

private var onItemClickListener: ((id: Int) -> Unit) ? = null

fun setOnItemClickListener(listener: (id: Int) -> Unit) {
onItemClickListener = listener
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
package com.henryudorji.theater.adapters

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.henryudorji.theater.R
import com.henryudorji.theater.data.model.Movie
import com.henryudorji.theater.databinding.MovieCustomLayoutBinding
import com.henryudorji.theater.utils.Constants.BASE_URL_IMAGE
import com.henryudorji.theater.utils.Constants.MOVIE_LIST_FRAG
import com.henryudorji.theater.utils.Constants.OTHER_FRAG
import com.squareup.picasso.Picasso

//
// Created by hash on 5/3/2021.
//
class MovieRecyclerAdapter: RecyclerView.Adapter<MovieRecyclerAdapter.MovieViewHolder>() {
class MovieRecyclerAdapter(private val fromWhichFrag: Int): RecyclerView.Adapter<MovieRecyclerAdapter.MovieViewHolder>() {

inner class MovieViewHolder(val binding: MovieCustomLayoutBinding): RecyclerView.ViewHolder(binding.root)

Expand All @@ -28,7 +32,6 @@ class MovieRecyclerAdapter: RecyclerView.Adapter<MovieRecyclerAdapter.MovieViewH
}
val differ = AsyncListDiffer(this, differCallback)


override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieViewHolder {
val binding = MovieCustomLayoutBinding.inflate(
LayoutInflater.from(parent.context),
Expand All @@ -42,6 +45,12 @@ class MovieRecyclerAdapter: RecyclerView.Adapter<MovieRecyclerAdapter.MovieViewH
val movie = differ.currentList[position]

holder.binding.apply {
when(fromWhichFrag) {
MOVIE_LIST_FRAG -> root.layoutParams =
ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, R.dimen._170sdp)
OTHER_FRAG -> root.layoutParams =
ViewGroup.LayoutParams(R.dimen._120sdp, R.dimen._170sdp)
}
Picasso.get().load(BASE_URL_IMAGE + movie.posterPath).into(movieImage)
movieTitleText.text = movie.originalTitle
ratingText.text = movie.voteAverage.toString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import com.henryudorji.theater.ui.main.MainActivity
import com.henryudorji.theater.utils.ConnectionManager
import com.henryudorji.theater.utils.Constants.BASE_URL_IMAGE
import com.henryudorji.theater.utils.Constants.MOVIE_CATEGORY
import com.henryudorji.theater.utils.Constants.OTHER_FRAG
import com.henryudorji.theater.utils.Constants.POPULAR
import com.henryudorji.theater.utils.Constants.TOP_RATED
import com.henryudorji.theater.utils.Constants.UPCOMING
Expand All @@ -33,7 +34,7 @@ import java.io.IOException
class HomeMoviesFragment: Fragment(R.layout.fragment_home_detail) {
private val TAG = "HomeMoviesFragment"
private lateinit var binding: FragmentHomeDetailBinding
lateinit var movieRepository: MovieRepository
private lateinit var movieRepository: MovieRepository
private lateinit var popularAdapter: MovieRecyclerAdapter
private lateinit var upcomingAdapter: MovieRecyclerAdapter
private lateinit var topRatedAdapter: MovieRecyclerAdapter
Expand Down Expand Up @@ -153,9 +154,9 @@ class HomeMoviesFragment: Fragment(R.layout.fragment_home_detail) {


private fun initViews() {
popularAdapter = MovieRecyclerAdapter()
upcomingAdapter = MovieRecyclerAdapter()
topRatedAdapter = MovieRecyclerAdapter()
popularAdapter = MovieRecyclerAdapter(OTHER_FRAG)
upcomingAdapter = MovieRecyclerAdapter(OTHER_FRAG)
topRatedAdapter = MovieRecyclerAdapter(OTHER_FRAG)

binding.popularRecyclerView.apply {
adapter = popularAdapter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ package com.henryudorji.theater.ui.fragments
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.AbsListView
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.snackbar.Snackbar
import com.henryudorji.theater.R
import com.henryudorji.theater.adapters.MovieRecyclerAdapter
Expand All @@ -14,7 +18,9 @@ import com.henryudorji.theater.data.repository.MovieRepository
import com.henryudorji.theater.databinding.FragmentMovieListBinding
import com.henryudorji.theater.ui.main.MainActivity
import com.henryudorji.theater.utils.ConnectionManager
import com.henryudorji.theater.utils.Constants.MOVIE_LIST_FRAG
import com.henryudorji.theater.utils.Constants.POPULAR
import com.henryudorji.theater.utils.Constants.QUERY_PAGE_SIZE
import com.henryudorji.theater.utils.Constants.TOP_RATED
import com.henryudorji.theater.utils.Constants.UPCOMING
import kotlinx.coroutines.CoroutineScope
Expand All @@ -31,9 +37,10 @@ class MovieListFragment: Fragment(R.layout.fragment_movie_list) {
private lateinit var binding: FragmentMovieListBinding
private lateinit var movieListAdapter: MovieRecyclerAdapter
private lateinit var movieCategory: String
lateinit var movieRepository: MovieRepository
private lateinit var movieRepository: MovieRepository
private val args: MovieListFragmentArgs by navArgs()
private var moviePage = 1
private var dataResponse: MovieResponse? = null

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Expand All @@ -59,11 +66,18 @@ class MovieListFragment: Fragment(R.layout.fragment_movie_list) {
TOP_RATED -> movieRepository.getTopRatedMovies(moviePage)
else -> movieRepository.getPopularMovies(moviePage)
}
//val moviesData = movieRepository.getPopularMovies(moviePage)

if (moviesData.isSuccessful) {
moviesData.body()?.let { movieResponse ->
movieListAdapter.differ.submitList(movieResponse.movies)
moviePage++
if (dataResponse == null) {
dataResponse = movieResponse
}else {
val oldArticles = dataResponse?.movies
val newArticles = movieResponse.movies
oldArticles?.addAll(newArticles)
}
movieListAdapter.differ.submitList(dataResponse?.movies ?: movieResponse.movies)
}
withContext(Dispatchers.Main) {
hideShimmerPlaceHolder()
Expand Down Expand Up @@ -112,7 +126,6 @@ class MovieListFragment: Fragment(R.layout.fragment_movie_list) {
}
}


private fun showNoNetworkSnackBar(message: String) {
Snackbar.make(binding.root, message, Snackbar.LENGTH_INDEFINITE)
.setAction(getString(R.string.retry)) {
Expand All @@ -126,12 +139,51 @@ class MovieListFragment: Fragment(R.layout.fragment_movie_list) {
}

private fun initViews() {
movieListAdapter = MovieRecyclerAdapter()
binding.backBtn.setOnClickListener {
requireActivity().onBackPressed()
}

movieListAdapter = MovieRecyclerAdapter(MOVIE_LIST_FRAG)

binding.movieListRv.apply {
adapter = movieListAdapter
layoutManager = GridLayoutManager(requireContext(), 3)
layoutManager = GridLayoutManager(requireContext(), 2)
addOnScrollListener(this@MovieListFragment.scrollListener)
}
}

// Paginating the recyclerView
var isScrolling = false
var isLoading = false
var isLastPage = false

private val scrollListener = object: RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
isScrolling = true
}
}

override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val layoutManager = binding.movieListRv.layoutManager as LinearLayoutManager
val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
val visibleItemCount = layoutManager.childCount
val totalItemCount = layoutManager.itemCount

val isNotLoadingAndNotAtLastPage = !isLoading && !isLastPage
val isAtLastItem = firstVisibleItemPosition + visibleItemCount >= totalItemCount
val isNotAtBeginning = firstVisibleItemPosition >= 0
val isTotalMoreThanVisible = totalItemCount >= QUERY_PAGE_SIZE

val shouldPaginate = isNotLoadingAndNotAtLastPage && isAtLastItem && isNotAtBeginning
&& isTotalMoreThanVisible && isScrolling

if (shouldPaginate) {
getMoviesData()
isScrolling = false
}
}
}
}
3 changes: 3 additions & 0 deletions app/src/main/java/com/henryudorji/theater/utils/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ object Constants {
const val TOP_RATED = "TOP_RATED"


const val QUERY_PAGE_SIZE = 20
const val SNACKBAR_LENGHT_SHORT = 1
const val SNACKBAR_LENGHT_LONG = 2
const val MOVIE_LIST_FRAG = 1
const val OTHER_FRAG = 2
}
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/ic_back.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M11.67,3.87L9.9,2.1 0,12l9.9,9.9 1.77,-1.77L3.54,12z"/>
</vector>
42 changes: 37 additions & 5 deletions app/src/main/res/layout/fragment_movie_list.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/app_background_color">

<ImageView
android:id="@+id/backBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_back"
android:layout_marginStart="@dimen/_10sdp"
app:layout_constraintTop_toTopOf="@id/searchEdit"
app:layout_constraintBottom_toBottomOf="@id/searchEdit"
app:layout_constraintStart_toStartOf="parent"/>

<EditText
android:id="@+id/searchEdit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="Search..."
android:inputType="text"
android:fontFamily="@font/raleway_regular"
android:textColorHint="@color/white"
android:textColor="@color/white"
android:padding="@dimen/_10sdp"
android:drawableEnd="@drawable/ic_search"
android:layout_margin="@dimen/_10sdp"
android:background="@drawable/edit_bg"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/backBtn"/>

<com.facebook.shimmer.ShimmerFrameLayout
android:id="@+id/shimmerLayout"
android:layout_width="match_parent"
Expand All @@ -13,7 +42,7 @@
android:layout_marginEnd="@dimen/_10sdp"
android:layout_marginTop="@dimen/_5sdp"
android:background="@color/app_background_color"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toBottomOf="@id/searchEdit"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">

Expand Down Expand Up @@ -60,11 +89,14 @@

</com.facebook.shimmer.ShimmerFrameLayout>


<androidx.recyclerview.widget.RecyclerView
android:id="@+id/movieListRv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
android:layout_height="wrap_content"
android:visibility="gone"
android:background="@color/app_background_color"
app:layout_constraintTop_toBottomOf="@id/searchEdit"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
1 change: 1 addition & 0 deletions app/src/main/res/layout/movie_custom_layout.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
android:layout_width="@dimen/_120sdp"
android:layout_margin="@dimen/_5sdp"
android:layout_height="wrap_content"
android:id="@+id/rootLayout"
android:background="@color/app_background_color">

<io.github.florent37.shapeofview.shapes.RoundRectView
Expand Down
Loading

0 comments on commit a407892

Please sign in to comment.