Skip to content

Commit

Permalink
[Enhancement] Update UI home movie
Browse files Browse the repository at this point in the history
  • Loading branch information
adrie4mac committed Apr 18, 2020
1 parent e0ec6a5 commit 26e1366
Show file tree
Hide file tree
Showing 23 changed files with 184 additions and 109 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@ open class MovieEntity(@SerializedName("vote_count") val voteCount: Int? = null,
@SerializedName("backdrop_path") val backdropPath: String? = null,
@SerializedName("adult") val adult: Boolean? = null,
@SerializedName("overview") val overview: String? = null,
@SerializedName("release_date") val releaseDate: String? = null) {
}
@SerializedName("release_date") val releaseDate: String? = null)
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class TagInjectConstant {
const val APP_INIT_URL = "app_init_url"
const val IS_DEBUG = "is_debug"
const val CONNECTIVITY_INTERCEPTOR = "connectivity_interceptor"
const val CHUCK_INTERCEPTOR = "chuck_interceptor"
const val RETROFIT_DEFAULT = "TagInjectConstant.RETROFIT_DEFAULT"
const val OKHTTP_DEFAULT = "TagInjectConstant.OKHTTP_DEFAULT"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ class NetworkModule {
@Named(TagInjectConstant.OKHTTP_DEFAULT)
fun provideOkHttpClient(certificatePinner: CertificatePinner,
@Named(TagInjectConstant.IS_DEBUG) isDebug: Boolean,
@Named(TagInjectConstant.CONNECTIVITY_INTERCEPTOR) connectivityInterceptor: Interceptor)
@Named(TagInjectConstant.CONNECTIVITY_INTERCEPTOR) connectivityInterceptor: Interceptor,
@Named(TagInjectConstant.CHUCK_INTERCEPTOR) chuckInterceptor: Interceptor)
: OkHttpClient {
return OkHttpClient.Builder()
.defaultBuilder(isDebug)
.defaultBuilder(isDebug, chuckInterceptor)
.certificatePinner(certificatePinner)
.addInterceptor(connectivityInterceptor)
.build()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package com.adriesavana.network.extension

import com.adriesavana.kit.constants.ApiConstant
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import java.util.concurrent.TimeUnit

internal fun OkHttpClient.Builder.defaultBuilder(isDebug: Boolean)
internal fun OkHttpClient.Builder.defaultBuilder(isDebug: Boolean, chuckInterceptor: Interceptor)
: OkHttpClient.Builder {
if (isDebug) {
addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
addInterceptor(chuckInterceptor)
}
connectTimeout(ApiConstant.TIME_OUT_IN_SECONDS, TimeUnit.SECONDS)
readTimeout(ApiConstant.TIME_OUT_IN_SECONDS, TimeUnit.SECONDS)
Expand Down
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ dependencies {
implementation appDependencies.fastAdapterExtension
implementation appDependencies.fastAdapterExtensionExpandable
implementation appDependencies.picasso
implementation appDependencies.chuck

kapt appDependencies.daggerCompiler
kapt appDependencies.daggerAndroidProcessor
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.adriesavana.themoviedb.common.base

import android.databinding.DataBindingUtil
import android.databinding.ViewDataBinding
import android.os.Bundle
import android.support.annotation.CallSuper
import android.support.v4.app.Fragment
Expand All @@ -13,25 +15,26 @@ import javax.inject.Inject

interface ViewModelType

abstract class BaseActivity<VM : ViewModelType> : AppCompatActivity(), HasSupportFragmentInjector {
abstract class BaseActivity<VB : ViewDataBinding, VM : ViewModelType> : AppCompatActivity(), HasSupportFragmentInjector {

@Inject
lateinit var viewModel: VM
@Inject
lateinit var fragmentInjector: DispatchingAndroidInjector<Fragment>
@Inject lateinit var viewModel: VM
@Inject lateinit var fragmentInjector: DispatchingAndroidInjector<Fragment>

protected val compositeDisposable = CompositeDisposable()
protected abstract fun getLayoutRes(): Int
protected val binding by lazy {
DataBindingUtil.setContentView(this, getLayoutRes()) as VB
}

@CallSuper
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
binding.lifecycleOwner = this
bindViewModel()
}

open fun bindViewModel() {

}
open fun bindViewModel() {}

@CallSuper
override fun onDestroy() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ import com.mikepenz.fastadapter.adapters.ItemAdapter
abstract class BaseListFragment<VM : ViewModelType> : BaseFragment<VM>() {

protected var itemAdapter = ItemAdapter<IItem<*, *>>()
protected var fastAdapter: FastAdapter<IItem<*, *>> = FastAdapter.with(itemAdapter)
private var fastAdapter: FastAdapter<IItem<*, *>> = FastAdapter.with(itemAdapter)
protected var loadMoreListItem: LoadMoreListItem = LoadMoreListItem()

protected lateinit var recyclerView: RecyclerView
protected lateinit var swipeRefreshLayout: SwipeRefreshLayout
protected lateinit var staggeredGridLayoutManager: StaggeredGridLayoutManager
private lateinit var recyclerView: RecyclerView
private lateinit var swipeRefreshLayout: SwipeRefreshLayout
private lateinit var staggeredGridLayoutManager: StaggeredGridLayoutManager
protected lateinit var scrollToTop: ImageView
protected var itemPadding: Int = 0
protected var scrollToTopTranslation: Float = 0F
Expand Down Expand Up @@ -81,15 +81,14 @@ abstract class BaseListFragment<VM : ViewModelType> : BaseFragment<VM>() {
}

open fun removeLoadMore() {
if (itemAdapter.adapterItems.contains(loadMoreListItem)) {
itemAdapter.remove(itemAdapter.getAdapterPosition(loadMoreListItem))
itemAdapter.run {
takeIf { it.adapterItems.contains(loadMoreListItem) }
?.remove(getAdapterPosition(loadMoreListItem))
}
}

open fun stopRefreshing() {
if (swipeRefreshLayout.isRefreshing()) {
swipeRefreshLayout.setRefreshing(false);
}
swipeRefreshLayout.takeIf { it.isRefreshing }?.isRefreshing = false
}

open fun bindViewModel() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.adriesavana.kit.constants.TagInjectConstant
import com.adriesavana.themoviedb.BuildConfig
import com.adriesavana.themoviedb.common.base.ConnectivityInterceptor
import com.adriesavana.themoviedb.utils.NetworkUtil
import com.readystatesoftware.chuck.ChuckInterceptor
import dagger.Module
import dagger.Provides
import io.reactivex.Scheduler
Expand Down Expand Up @@ -54,4 +55,12 @@ class AppModule {
@Named(TagInjectConstant.API_KEY)
fun provideAppApiKey() = BuildConfig.API_KEY


@Provides
@Singleton
@Named(TagInjectConstant.CHUCK_INTERCEPTOR)
fun provideChuckInterceptor(app: Application): Interceptor {
return ChuckInterceptor(app.applicationContext)
}

}
25 changes: 13 additions & 12 deletions app/src/main/java/com/adriesavana/themoviedb/movie/MovieActivity.kt
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
package com.adriesavana.themoviedb.movie

import android.graphics.Color
import android.os.Bundle
import com.adriesavana.themoviedb.R
import com.adriesavana.themoviedb.common.adapter.ViewPagerAdapter
import com.adriesavana.themoviedb.common.base.BaseActivity
import kotlinx.android.synthetic.main.activity_movie.*
import com.adriesavana.themoviedb.databinding.ActivityMovieBinding

class MovieActivity : BaseActivity<MovieViewModelType>() {
class MovieActivity : BaseActivity<ActivityMovieBinding, MovieViewModelType>() {

companion object {
const val CATEGORY_POPULAR = "POPULAR"
private const val CATEGORY_TOP_RATED = "TOP RATED"
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_movie)
override fun getLayoutRes(): Int = R.layout.activity_movie

override fun bindViewModel() {
setupViewPager()
super.bindViewModel()
}

private fun setupViewPager() {
val adapter = ViewPagerAdapter(supportFragmentManager)
adapter.apply {
val adapter = ViewPagerAdapter(supportFragmentManager).apply {
addFragment(MovieFragment.newInstance(CATEGORY_POPULAR.toLowerCase()), CATEGORY_POPULAR)
addFragment(MovieFragment.newInstance(CATEGORY_TOP_RATED), CATEGORY_TOP_RATED)
}

viewPager_movie.adapter = adapter
tabs_movie.apply {
setupWithViewPager(viewPager_movie)
setTabTextColors(Color.parseColor("#66ffffff"), Color.parseColor("#FFFFFF"));
with(binding) {
viewPagerMovie.adapter = adapter
tabsMovie.apply {
setupWithViewPager(viewPagerMovie)
setTabTextColors(Color.parseColor("#66ffffff"), Color.parseColor("#FFFFFF"))
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class MovieFragment : BaseListFragment<MovieFragmentViewModelType>(), MovieListI
.subscribe { t: List<MovieListItem>? -> itemAdapter.add(t) }
.disposedBy(compositeDisposable)

viewModel.outputs.showLoadMore.subscribe{t: Boolean? -> itemAdapter.add(loadMoreListItem) }
viewModel.outputs.showLoadMore
.subscribe { itemAdapter.add(loadMoreListItem) }
.disposedBy(compositeDisposable)
}

Expand All @@ -55,15 +56,14 @@ class MovieFragment : BaseListFragment<MovieFragmentViewModelType>(), MovieListI
}

companion object {
const val TAG = "MovieFragment"
private const val EXTRA_CATEGORY = "EXTRA_CATEGORY"

fun newInstance(category: String): MovieFragment {
val fragment = MovieFragment()
val args = Bundle()
args.putString(EXTRA_CATEGORY, category)
fragment.arguments = args
return fragment
val bundle = Bundle()
bundle.putString(EXTRA_CATEGORY, category)
return MovieFragment().apply {
arguments = bundle
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ class MovieListItem(private val eventListener: OnEventClickListener?,
private val movieDetail: MovieDetail)
: AbstractItem<MovieListItem, MovieListItem.ViewHolder>() {

private val voteAverage by lazy {
movieDetail.voteAverage.toString()
}

private val titleMovie by lazy {
"${movieDetail.title} (${movieDetail.releaseDate.take(4)})"
}

override fun getType(): Int = hashCode()

override fun getViewHolder(v: View): ViewHolder = ViewHolder(v)
Expand All @@ -22,6 +30,8 @@ class MovieListItem(private val eventListener: OnEventClickListener?,
holder.binding.apply {
listener = eventListener
movieModel = movieDetail
vote = voteAverage
title = titleMovie
executePendingBindings()
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
package com.adriesavana.themoviedb.moviedetail

import android.databinding.DataBindingUtil
import android.os.Bundle
import com.adriesavana.kit.extension.disposedBy
import com.adriesavana.movie.model.MovieDetail
import com.adriesavana.themoviedb.R
import com.adriesavana.themoviedb.common.base.BaseActivity
import com.adriesavana.themoviedb.databinding.ActivityMovieDetailBinding
import com.adriesavana.themoviedb.utils.toolbarTransparent
import com.android.databinding.library.baseAdapters.BR

class MovieDetailActivity : BaseActivity<MovieDetailViewModelType>() {

lateinit var binding: ActivityMovieDetailBinding
class MovieDetailActivity : BaseActivity<ActivityMovieDetailBinding, MovieDetailViewModelType>() {

companion object {
const val TAG = "MovieDetailActivity"
const val EXTRA_MOVIE = "EXTRA_MOVIE"
}

override fun getLayoutRes(): Int = R.layout.activity_movie_detail

override fun onCreate(savedInstanceState: Bundle?) {
toolbarTransparent()
super.onCreate(savedInstanceState)
binding= DataBindingUtil.setContentView(this, R.layout.activity_movie_detail)

val movieDetail = intent.extras.get(EXTRA_MOVIE) as? MovieDetail
viewModel.inputs.onViewLoaded(movieDetail)
}

override fun bindViewModel() {
super.bindViewModel()

viewModel.outputs.onLoadMovieDetail.subscribe{
viewModel.outputs.onLoadMovieDetail.subscribe {
binding.apply {
setVariable(BR.movieModel, it)
executePendingBindings()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@ import android.arch.lifecycle.ViewModel
import android.arch.lifecycle.ViewModelProvider
import com.adriesavana.movie.model.MovieDetail
import com.adriesavana.movie.model.MovieDetailView
import com.adriesavana.movie.model.MovieList
import com.adriesavana.movie.usecase.GetMovieListUseCase
import com.adriesavana.network.extension.getErrorMessage
import com.adriesavana.themoviedb.common.base.ViewModelType
import io.reactivex.Observable
import io.reactivex.observers.DisposableSingleObserver
import io.reactivex.subjects.PublishSubject
import javax.inject.Inject

Expand Down Expand Up @@ -51,17 +47,14 @@ class MovieDetailViewModel:
}
}

override fun onCleared() {
super.onCleared()
}

class Factory
@Inject constructor() : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MovieDetailViewModel::class.java)) {
return MovieDetailViewModel() as T
if (!modelClass.isAssignableFrom(MovieDetailViewModel::class.java)) {
throw IllegalArgumentException("Unknown ViewModel class")
}
throw IllegalArgumentException("Unknown ViewModel class")

return MovieDetailViewModel() as T
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ package com.adriesavana.themoviedb.utils

import android.app.Activity
import android.content.Intent
import android.os.Build
import android.view.View
import android.view.Window
import android.view.WindowManager

/**
* How to:
Expand All @@ -21,3 +25,16 @@ fun Activity.start(target: Class<*>, requestCode: Int? = null, func: (Intent.()
startActivity(intent)
}
}

fun Activity.toolbarTransparent() {
with(window) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
statusBarColor = 0x00000000 // transparent
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
}
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
}
}
12 changes: 12 additions & 0 deletions app/src/main/res/drawable/layout_rounded_grey.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="90"
android:endColor="@android:color/transparent"
android:centerColor="@android:color/transparent"
android:startColor="@android:color/background_dark"
android:type="linear" />
<corners android:radius="8dp"/>
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
<stroke android:width="0.7dp" android:color="@android:color/transparent"/>
</shape>
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/vector_star.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@android:color/holo_orange_light"
android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/>
</vector>
Loading

0 comments on commit 26e1366

Please sign in to comment.