Skip to content

Commit

Permalink
Add transition animation
Browse files Browse the repository at this point in the history
  • Loading branch information
Drjacky committed Aug 8, 2020
1 parent 78ffbad commit 2fc51ef
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package app.web.drjackycv.presentation.base.adapter

import android.view.ViewGroup
import android.widget.ImageView
import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.RecyclerView
import app.web.drjackycv.domain.base.RecyclerItem

abstract class BasePagedListAdapter(
vararg types: Cell<RecyclerItem>,
private val onItemClick: (RecyclerItem) -> Unit
private val onItemClick: (RecyclerItem, ImageView) -> Unit
) : PagedListAdapter<RecyclerItem, RecyclerView.ViewHolder>(BASE_DIFF_CALLBACK) {

private val cellTypes: CellTypes<RecyclerItem> = CellTypes(*types)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package app.web.drjackycv.presentation.base.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.annotation.LayoutRes
import androidx.recyclerview.widget.RecyclerView
import app.web.drjackycv.domain.base.RecyclerItem
Expand All @@ -15,7 +16,7 @@ abstract class Cell<T> {
abstract fun bind(
holder: RecyclerView.ViewHolder,
item: T?,
onItemClick: ((RecyclerItem) -> Unit)?
onItemClick: ((RecyclerItem, ImageView) -> Unit)?
)

protected fun ViewGroup.viewOf(@LayoutRes resource: Int): View {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package app.web.drjackycv.presentation.extension

import android.app.Activity
import android.graphics.drawable.Drawable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.annotation.DrawableRes
import androidx.annotation.LayoutRes
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.app.ActivityCompat.startPostponedEnterTransition
import app.web.drjackycv.presentation.R
import app.web.drjackycv.presentation.base.util.GlideApp
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target

fun View.gone() {
visibility = View.GONE
Expand All @@ -28,7 +35,8 @@ fun ViewGroup.inflate(@LayoutRes layoutRes: Int, attachToRoot: Boolean = false):

fun ImageView.load(
url: String,
@DrawableRes placeholderRes: Int = R.drawable.ic_cloud_download
@DrawableRes placeholderRes: Int = R.drawable.ic_cloud_download,
activity: Activity? = null
) {
val safePlaceholderDrawable = AppCompatResources.getDrawable(context, placeholderRes)
val requestOptions = RequestOptions().apply {
Expand All @@ -39,6 +47,33 @@ fun ImageView.load(
.with(context)
.setDefaultRequestOptions(requestOptions)
.load(url)
.dontAnimate()

activity?.let {
glideRequest
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>?,
isFirstResource: Boolean
): Boolean {
startPostponedEnterTransition(it)
return false
}

override fun onResourceReady(
resource: Drawable,
model: Any,
target: Target<Drawable>,
dataSource: DataSource,
isFirstResource: Boolean
): Boolean {
startPostponedEnterTransition(it)
return false
}
})
}

glideRequest.into(this)
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package app.web.drjackycv.presentation.products.entity

import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView
import app.web.drjackycv.domain.base.RecyclerItem
import app.web.drjackycv.domain.products.entity.Beer
import app.web.drjackycv.presentation.R
import app.web.drjackycv.presentation.base.adapter.Cell
import app.web.drjackycv.presentation.products.productlist.BeerMapper
import kotlinx.android.synthetic.main.item_product.view.*

object BeerCell : Cell<RecyclerItem>() {

Expand All @@ -25,13 +27,14 @@ object BeerCell : Cell<RecyclerItem>() {
override fun bind(
holder: RecyclerView.ViewHolder,
item: RecyclerItem?,
onItemClick: ((RecyclerItem) -> Unit)?
onItemClick: ((RecyclerItem, ImageView) -> Unit)?
) {
if (holder is BeerViewHolder && item is Beer) {
val itemUI = BeerMapper().mapToUI(item)

holder.bind(itemUI)
holder.itemView.setOnClickListener {
onItemClick?.run { this(item) }
onItemClick?.run { this(item, holder.itemView.itemProductImv) }
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package app.web.drjackycv.presentation.products.entity

import android.view.View
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.RecyclerView
import app.web.drjackycv.presentation.extension.load
import kotlinx.android.synthetic.main.item_product.view.*

class BeerViewHolder(view: View) : RecyclerView.ViewHolder(view) {

fun bind(beer: BeerUI) = with(itemView) {
ViewCompat.setTransitionName(itemProductImv, beer.id.toString())
itemProductImv.transitionName = beer.id.toString()
itemProductIdTxv.text = beer.id.toString()
itemProductImv.load(beer.imageUrl)
itemProductNameTxv.text = beer.name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.navArgs
import androidx.transition.TransitionInflater
import app.web.drjackycv.presentation.R
import app.web.drjackycv.presentation.extension.load
import dagger.hilt.android.AndroidEntryPoint
Expand All @@ -21,13 +22,22 @@ class ProductDetailFragment : Fragment(R.layout.fragment_product_detail) {
val safeArgs: ProductDetailFragmentArgs by navArgs()
val product = safeArgs.productDetailBeerUI

setSharedElementTransitionOnEnter()
//postponeEnterTransition()

with(product) {
productDetailIdTxv.text = id.toString()
productDetailImv.load(imageUrl)
productDetailImv.transitionName = id.toString()
productDetailImv.load(url = imageUrl, activity = activity)
productDetailNameTxv.text = name
productDetailDescriptionTxv.text = getString(R.string.description, description)
productDetailAbvTxv.text = getString(R.string.abv, abv.toString())
}
}

private fun setSharedElementTransitionOnEnter() {
sharedElementEnterTransition = TransitionInflater.from(context)
.inflateTransition(R.transition.shared_element_transition)
}

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package app.web.drjackycv.presentation.products.productlist

import android.widget.ImageView
import app.web.drjackycv.domain.base.RecyclerItem
import app.web.drjackycv.presentation.base.adapter.BasePagedListAdapter
import app.web.drjackycv.presentation.products.entity.BeerCell

class ProductsListAdapter(onItemClick: (RecyclerItem) -> Unit) : BasePagedListAdapter(
class ProductsListAdapter(onItemClick: (RecyclerItem, ImageView) -> Unit) : BasePagedListAdapter(
BeerCell,
onItemClick = onItemClick
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package app.web.drjackycv.presentation.products.productlist

import android.os.Bundle
import android.view.View
import androidx.core.os.bundleOf
import android.widget.ImageView
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
import androidx.navigation.navOptions
import androidx.paging.PagedList
import app.web.drjackycv.domain.base.Failure
import app.web.drjackycv.domain.base.RecyclerItem
Expand Down Expand Up @@ -38,6 +38,12 @@ class ProductsListFragment : Fragment(R.layout.fragment_product_list) {
private fun setupRecycler() {
itemErrorContainer.gone()
productListRecyclerView.adapter = productsListAdapter
//productListRecyclerView.itemAnimator = null
postponeEnterTransition()
productListRecyclerView.viewTreeObserver.addOnPreDrawListener {
startPostponedEnterTransition()
true
}
}

private fun setupViewModel() {
Expand Down Expand Up @@ -79,17 +85,14 @@ class ProductsListFragment : Fragment(R.layout.fragment_product_list) {
}
}

private fun navigateToProductDetail(item: RecyclerItem) {
val bundle = bundleOf("productDetailBeerUI" to BeerMapper().mapToUI(item as Beer))
val options = navOptions {
anim {
enter = R.anim.enter
exit = R.anim.exit
popEnter = R.anim.enter
popExit = R.anim.exit
}
}
findNavController().navigate(R.id.productDetailFragment, bundle, options)
private fun navigateToProductDetail(item: RecyclerItem, imageView: ImageView) {
val itemUI = BeerMapper().mapToUI(item as Beer)
val action =
ProductsListFragmentDirections.navigateToProductDetailFragment(itemUI)
val extras = FragmentNavigatorExtras(
imageView to itemUI.id.toString()
)
findNavController().navigate(action, extras)
}

}
8 changes: 2 additions & 6 deletions presentation/src/main/res/navigation/main_navigation.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,8 @@
tools:layout="@layout/fragment_product_list">

<action
android:id="@+id/navigateToAlbumDetailFragment"
app:destination="@id/productDetailFragment"
app:enterAnim="@anim/enter"
app:exitAnim="@anim/exit"
app:popEnterAnim="@anim/pop_enter"
app:popExitAnim="@anim/pop_exit" />
android:id="@+id/navigateToProductDetailFragment"
app:destination="@id/productDetailFragment" />

</fragment>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<changeBounds xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/fast_out_slow_in" />

0 comments on commit 2fc51ef

Please sign in to comment.