Skip to content

Commit

Permalink
ViewPager2 perf: revert to ViewPager for episodes.
Browse files Browse the repository at this point in the history
This will probably re-introduce bugs when the number of episodes changes
(?), but this is worth the trade-off of much better paging performance.
  • Loading branch information
UweTrottmann committed Jan 12, 2024
1 parent 5b8f1ca commit 6af22f6
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 38 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Version 71
*in development*

* 🔧 Shows: adjust edit time dialog to avoid buttons moving around when changing values.
* 🔧 Shows: faster scrolling between episode pages, again.
* 🔧 Add acknowledgement messages for actions that may take longer (that do network requests), drop
them for actions that complete immediately (e.g. set watched).
* 🔨 Update Metacritic search links.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,67 @@
package com.battlelancer.seriesguide.shows.episodes

import android.annotation.SuppressLint
import android.content.Context
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import com.battlelancer.seriesguide.shows.database.SgEpisode2Numbers
import com.battlelancer.seriesguide.util.TextTools

/**
* Maps [Episode] objects to [EpisodeDetailsFragment] pages.
*/
class EpisodePagerAdapter(
fragmentActivity: FragmentActivity
) : FragmentStateAdapter(fragmentActivity) {
@Suppress("DEPRECATION") // ViewPager2 paging performance is bad, don't need its improvements
@SuppressLint("WrongConstant") // Behavior flag not recognized as valid.
internal class EpisodePagerAdapter(
private val context: Context,
fm: FragmentManager
) : FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {

private val items = ArrayList<SgEpisode2Numbers>()
private val episodes = ArrayList<SgEpisode2Numbers>()

@SuppressLint("NotifyDataSetChanged") // No need for incremental updates/animations.
fun updateItems(list: List<SgEpisode2Numbers>) {
items.clear()
items.addAll(list)
notifyDataSetChanged()
override fun getCount(): Int {
return episodes.size
}

override fun getItem(position: Int): Fragment {
return EpisodeDetailsFragment.newInstance(episodes[position].id)
}

override fun getItemPosition(`object`: Any): Int {
/*
* This breaks the FragmentStatePagerAdapter
* (see https://issuetracker.google.com/issues/36956111),
* so just destroy everything!
* Note: This might be fixed with ViewPager2.
*/
// EpisodeDetailsFragment fragment = (EpisodeDetailsFragment)
// object;
// int episodeId = fragment.getEpisodeId();
// for (int i = 0; i < mEpisodes.size(); i++) {
// if (episodeId == mEpisodes.get(i).episodeId) {
// return i;
// }
// }
return POSITION_NONE
}

fun getItemEpisodeId(position: Int): Long? {
return if (position < items.size) {
items[position].id
return if (position < episodes.size) {
episodes[position].id
} else {
null
}
}

override fun getItemId(position: Int): Long {
return if (position < items.size) {
items[position].id
} else {
RecyclerView.NO_ID
}
override fun getPageTitle(position: Int): CharSequence? {
val episode = episodes[position]
return TextTools.getEpisodeNumber(context, episode.season, episode.episodenumber)
}

override fun containsItem(itemId: Long): Boolean = items.find { it.id == itemId } != null

override fun getItemCount(): Int = items.size

override fun createFragment(position: Int): Fragment =
EpisodeDetailsFragment.newInstance(items[position].id)

fun updateEpisodeList(list: List<SgEpisode2Numbers>) {
episodes.clear()
episodes.addAll(list)
notifyDataSetChanged()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import com.battlelancer.seriesguide.shows.tools.ShowSync
import com.battlelancer.seriesguide.ui.BaseMessageActivity
import com.battlelancer.seriesguide.ui.OverviewActivity
import com.battlelancer.seriesguide.util.ImageTools
import com.battlelancer.seriesguide.util.TextTools
import com.battlelancer.seriesguide.util.ThemeUtils
import com.battlelancer.seriesguide.util.ThemeUtils.setDefaultStyle
import com.google.android.material.shape.MaterialShapeDrawable
Expand Down Expand Up @@ -244,17 +243,18 @@ class EpisodesActivity : BaseMessageActivity() {
val tabsEpisodes = binding.tabsEpisodes
val adapter = episodeDetailsAdapter
if (adapter == null) {
episodeDetailsAdapter = EpisodePagerAdapter(this)
.also { it.updateItems(info.episodes) }
episodeDetailsAdapter = EpisodePagerAdapter(
this,
supportFragmentManager
).also {
it.updateEpisodeList(info.episodes)
}
pagerEpisodes.adapter = episodeDetailsAdapter
} else {
adapter.updateItems(info.episodes)
adapter.updateEpisodeList(info.episodes)
}
// Refresh pager tab decoration.
tabsEpisodes.setViewPager2(pagerEpisodes) { position ->
val episode = info.episodes[position]
TextTools.getEpisodeNumber(this, episode.season, episode.episodenumber)
}
tabsEpisodes.setViewPager(pagerEpisodes)

// Remove page change listener to avoid changing checked episode on sort order changes.
tabsEpisodes.setOnPageChangeListener(null)
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/layout-w1024dp/activity_episodes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<androidx.viewpager2.widget.ViewPager2
<androidx.viewpager.widget.ViewPager
android:id="@+id/pagerEpisodes"
android:layout_width="match_parent"
android:layout_height="0dp"
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/layout-w590dp/activity_episodes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
android:layout_height="wrap_content"
tools:layout_height="48dp" />

<androidx.viewpager2.widget.ViewPager2
<androidx.viewpager.widget.ViewPager
android:id="@+id/pagerEpisodes"
android:layout_width="match_parent"
android:layout_height="0dp"
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/layout/activity_episodes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

<androidx.viewpager2.widget.ViewPager2
<androidx.viewpager.widget.ViewPager
android:id="@+id/pagerEpisodes"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Expand Down

0 comments on commit 6af22f6

Please sign in to comment.