Skip to content

Commit ce9da4f

Browse files
author
andres-seoane-intive
authored
Merge pull request #13 from intive-FDV/troubleshooting/paging_adapter_scrolling_bug
[Fix] scroll bug + column width
2 parents c624ca2 + ffeca9a commit ce9da4f

File tree

10 files changed

+106
-35
lines changed

10 files changed

+106
-35
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.intive.tmdbandroid.common
2+
3+
import androidx.recyclerview.widget.DiffUtil
4+
import com.intive.tmdbandroid.model.TVShow
5+
6+
class TVShowAsyncPagingDataDiffCallback : DiffUtil.ItemCallback<TVShow>() {
7+
override fun areItemsTheSame(oldItem: TVShow, newItem: TVShow): Boolean {
8+
return oldItem.id == newItem.id
9+
}
10+
11+
override fun areContentsTheSame(oldItem: TVShow, newItem: TVShow): Boolean {
12+
return oldItem == newItem
13+
}
14+
}

app/src/main/java/com/intive/tmdbandroid/home/ui/HomeFragment.kt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ import kotlin.math.floor
2828
class HomeFragment : Fragment() {
2929
private val viewModel: HomeViewModel by viewModels()
3030

31-
private lateinit var tvShowPageAdapter: TVShowPageAdapter
31+
private val clickListener = { tvShow: TVShow ->
32+
val action = HomeFragmentDirections.actionHomeFragmentDestToTVShowDetail(tvShow.id)
33+
findNavController().navigate(action)
34+
}
35+
private val tvShowPageAdapter = TVShowPageAdapter(clickListener)
3236

3337
override fun onCreate(savedInstanceState: Bundle?) {
3438
super.onCreate(savedInstanceState)
@@ -122,17 +126,12 @@ class HomeFragment : Fragment() {
122126
private fun initViews(binding: FragmentHomeBinding) {
123127
val rvTopTVShows = binding.rvPopularTVShows
124128

125-
val clickListener = { tvShow: TVShow ->
126-
val action = HomeFragmentDirections.actionHomeFragmentDestToTVShowDetail(tvShow.id)
127-
findNavController().navigate(action)
128-
}
129-
tvShowPageAdapter = TVShowPageAdapter(clickListener)
130-
131129
rvTopTVShows.apply {
132130
val displayMetrics = context.resources.displayMetrics
133131
val dpWidth = displayMetrics.widthPixels / displayMetrics.density
132+
Timber.i("MAS - dpWidth: $dpWidth")
134133

135-
val scaling = 200
134+
val scaling = resources.getInteger(R.integer.screening_width)
136135
val columnCount = floor(dpWidth / scaling).toInt()
137136
Timber.i("MAS - columnCount: $columnCount")
138137

@@ -146,6 +145,8 @@ class HomeFragment : Fragment() {
146145
}
147146
}
148147

148+
tvShowPageAdapter.widthSize = ((floor(dpWidth / columnCount) - resources.getInteger(R.integer.short_padding)) * displayMetrics.density).toInt()
149+
149150
layoutManager = manager
150151
adapter = tvShowPageAdapter
151152
}

app/src/main/java/com/intive/tmdbandroid/home/ui/adapters/TVShowPageAdapter.kt

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,55 +3,83 @@ package com.intive.tmdbandroid.home.ui.adapters
33
import android.content.res.Resources
44
import android.view.LayoutInflater
55
import android.view.ViewGroup
6-
import androidx.paging.PagingDataAdapter
7-
import androidx.recyclerview.widget.DiffUtil
8-
import androidx.recyclerview.widget.LinearLayoutManager
9-
import androidx.recyclerview.widget.RecyclerView
6+
import androidx.paging.AsyncPagingDataDiffer
7+
import androidx.paging.PagingData
8+
import androidx.recyclerview.widget.*
109
import com.intive.tmdbandroid.R
10+
import com.intive.tmdbandroid.common.TVShowAsyncPagingDataDiffCallback
1111
import com.intive.tmdbandroid.databinding.ItemHorizontalListBinding
1212
import com.intive.tmdbandroid.databinding.ItemScreeningBinding
1313
import com.intive.tmdbandroid.databinding.ItemTitleBinding
1414
import com.intive.tmdbandroid.model.TVShow
1515

16-
class TVShowPageAdapter(private val clickListener: ((TVShow) -> Unit)) : PagingDataAdapter<TVShow, RecyclerView.ViewHolder>(COMPARATOR) {
16+
class TVShowPageAdapter(private val clickListener: ((TVShow) -> Unit)) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
1717
companion object {
18-
private val COMPARATOR = object : DiffUtil.ItemCallback<TVShow>() {
19-
override fun areItemsTheSame(oldItem: TVShow, newItem: TVShow): Boolean = (oldItem == newItem)
20-
override fun areContentsTheSame(oldItem: TVShow, newItem: TVShow): Boolean = (oldItem == newItem)
21-
}
22-
2318
private const val HEADER = 0
2419
private const val WATCHLIST = 1
2520
private const val POPULAR = 2
2621
}
2722

23+
var widthSize: Int = 0
24+
val adapterCallback = AdapterListUpdateCallback(this)
25+
26+
private val differ = AsyncPagingDataDiffer(
27+
TVShowAsyncPagingDataDiffCallback(),
28+
object : ListUpdateCallback {
29+
override fun onInserted(position: Int, count: Int) {
30+
adapterCallback.onInserted(position + 1, count)
31+
}
32+
33+
override fun onRemoved(position: Int, count: Int) {
34+
adapterCallback.onRemoved(position + 1, count)
35+
}
36+
37+
override fun onMoved(fromPosition: Int, toPosition: Int) {
38+
adapterCallback.onMoved(fromPosition + 1, toPosition + 1)
39+
}
40+
41+
override fun onChanged(position: Int, count: Int, payload: Any?) {
42+
adapterCallback.onChanged(position + 1, count, payload)
43+
}
44+
}
45+
)
46+
47+
suspend fun submitData(tvShowPagingData: PagingData<TVShow>) {
48+
differ.submitData(tvShowPagingData)
49+
}
50+
2851
private val watchlistAdapter = WatchlistAdapter(clickListener)
2952

53+
override fun getItemCount(): Int {
54+
return differ.itemCount + 3
55+
}
56+
3057
fun refreshWatchlistAdapter(list: List<TVShow>) {
3158
watchlistAdapter.submitList(list)
3259
}
3360

3461
override fun getItemViewType(position: Int): Int {
3562
return when (position) {
36-
0,2 -> HEADER
63+
0, 2 -> HEADER
3764
1 -> WATCHLIST
3865
else -> POPULAR
3966
}
4067
}
4168

4269
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
70+
4371
when (holder) {
4472
is HeaderHolder -> holder.bind(position)
4573
is WatchlistHolder -> holder.bind()
46-
is TVShowHolder -> getItem(position - 3)?.let { holder.bind(it) }
74+
is TVShowHolder -> differ.getItem(position - 3)?.let { holder.bind(it) }
4775
}
4876
}
4977

5078
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
5179
return when (viewType) {
5280
HEADER -> HeaderHolder(ItemTitleBinding.inflate(LayoutInflater.from(parent.context), parent, false))
5381
WATCHLIST -> WatchlistHolder(ItemHorizontalListBinding.inflate(LayoutInflater.from(parent.context), parent, false))
54-
POPULAR -> TVShowHolder(ItemScreeningBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener )
82+
POPULAR -> TVShowHolder(ItemScreeningBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener)
5583
else -> throw Exception("Illegal ViewType")
5684
}
5785
}
@@ -78,6 +106,7 @@ class TVShowPageAdapter(private val clickListener: ((TVShow) -> Unit)) : PagingD
78106
fun bind() {
79107
rvWatchlist.apply {
80108
layoutManager = LinearLayoutManager(itemView.context, LinearLayoutManager.HORIZONTAL, false)
109+
watchlistAdapter.widthSize = widthSize
81110
adapter = watchlistAdapter
82111
}
83112
}

app/src/main/java/com/intive/tmdbandroid/home/ui/adapters/WatchlistAdapter.kt

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ import androidx.recyclerview.widget.DiffUtil
66
import androidx.recyclerview.widget.ListAdapter
77
import com.intive.tmdbandroid.databinding.ItemScreeningBinding
88
import com.intive.tmdbandroid.model.TVShow
9+
import timber.log.Timber
910

1011
class WatchlistAdapter(private val clickListener: ((TVShow) -> Unit)) : ListAdapter<TVShow, TVShowHolder>(COMPARATOR) {
12+
var widthSize: Int = 0
13+
1114
companion object {
1215
private val COMPARATOR = object : DiffUtil.ItemCallback<TVShow>() {
1316
override fun areItemsTheSame(oldItem: TVShow, newItem: TVShow): Boolean = (oldItem == newItem)
@@ -19,8 +22,14 @@ class WatchlistAdapter(private val clickListener: ((TVShow) -> Unit)) : ListAdap
1922
holder.bind(getItem(position))
2023
}
2124

22-
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TVShowHolder = TVShowHolder(
23-
ItemScreeningBinding.inflate(LayoutInflater.from(parent.context), parent, false),
24-
clickListener
25-
)
26-
}
25+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TVShowHolder {
26+
val binding = ItemScreeningBinding.inflate(LayoutInflater.from(parent.context), parent, false)
27+
Timber.i("MAS - width: $widthSize")
28+
binding.screeningContainer.layoutParams.width = widthSize
29+
30+
return TVShowHolder(
31+
binding,
32+
clickListener
33+
)
34+
}
35+
}
10.3 KB
Loading

app/src/main/res/layout/item_screening.xml

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,32 @@
11
<?xml version="1.0" encoding="utf-8"?>
22

33
<androidx.cardview.widget.CardView
4+
android:id="@+id/screening_container"
45
xmlns:android="http://schemas.android.com/apk/res/android"
56
xmlns:app="http://schemas.android.com/apk/res-auto"
67
xmlns:tools="http://schemas.android.com/tools"
7-
android:layout_width="wrap_content"
8+
android:layout_width="match_parent"
89
android:layout_height="wrap_content"
9-
android:layout_marginTop="8dp"
10-
android:layout_marginEnd="8dp"
11-
android:layout_marginStart="8dp"
12-
android:layout_marginBottom="16dp"
10+
android:layout_margin="8dp"
11+
android:paddingBottom="8dp"
1312
app:cardCornerRadius="5dp"
1413
android:elevation="5dp">
1514

1615
<androidx.constraintlayout.widget.ConstraintLayout
17-
android:layout_width="wrap_content"
16+
android:layout_width="match_parent"
1817
android:layout_height="wrap_content"
1918
android:layout_gravity="center">
2019

2120
<androidx.appcompat.widget.AppCompatImageView
2221
android:id="@+id/screening_poster"
23-
android:layout_width="wrap_content"
22+
android:layout_width="match_parent"
2423
android:layout_height="0dp"
25-
android:minWidth="192dp"
2624
app:layout_constraintDimensionRatio="1:1.5"
2725
app:layout_constraintHorizontal_bias="0.0"
2826
app:layout_constraintEnd_toEndOf="parent"
2927
app:layout_constraintStart_toStartOf="parent"
3028
app:layout_constraintTop_toTopOf="parent"
31-
tools:src="@drawable/ic_launcher_foreground" />
29+
tools:src="@drawable/poster_placeholder" />
3230

3331
<androidx.appcompat.widget.AppCompatTextView
3432
android:id="@+id/screening_title"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<integer name="screening_width">100</integer>
4+
<integer name="short_padding">8</integer>
5+
</resources>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<integer name="screening_width">150</integer>
4+
<integer name="short_padding">8</integer>
5+
</resources>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<integer name="screening_width">200</integer>
4+
<integer name="short_padding">8</integer>
5+
</resources>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<integer name="screening_width">250</integer>
4+
<integer name="short_padding">8</integer>
5+
</resources>

0 commit comments

Comments
 (0)