From 59250404c2c4cd3a999f66567d21e8e24d6a2b4d Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Wed, 1 Apr 2020 20:29:48 +0200 Subject: Recycle ViewHolders throughout the app --- .../fragment/CompletedDownloadsFragment.java | 14 +-- .../antennapod/fragment/EpisodesListFragment.java | 111 ++++++--------------- .../antennapod/fragment/FeedItemlistFragment.java | 30 ++---- .../fragment/ItemDescriptionFragment.java | 15 ++- .../fragment/PlaybackHistoryFragment.java | 14 +-- .../danoeh/antennapod/fragment/QueueFragment.java | 43 ++------ .../danoeh/antennapod/fragment/SearchFragment.java | 13 +-- 7 files changed, 65 insertions(+), 175 deletions(-) (limited to 'app/src/main/java/de/danoeh/antennapod/fragment') diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java index d5f8775f1..a3c07721a 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java @@ -13,9 +13,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.EpisodeItemListAdapter; @@ -31,6 +28,7 @@ import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.view.EmptyViewHandler; +import de.danoeh.antennapod.view.EpisodeItemListRecyclerView; import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -55,7 +53,7 @@ public class CompletedDownloadsFragment extends Fragment { private List items = new ArrayList<>(); private CompletedDownloadsListAdapter adapter; - private RecyclerView recyclerView; + private EpisodeItemListRecyclerView recyclerView; private ProgressBar progressBar; private Disposable disposable; private EmptyViewHandler emptyView; @@ -68,10 +66,7 @@ public class CompletedDownloadsFragment extends Fragment { toolbar.setVisibility(View.GONE); recyclerView = root.findViewById(R.id.recyclerView); - LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); - recyclerView.setLayoutManager(layoutManager); - recyclerView.setHasFixedSize(true); - recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).build()); + recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool()); recyclerView.setVisibility(View.GONE); adapter = new CompletedDownloadsListAdapter((MainActivity) getActivity()); recyclerView.setAdapter(adapter); @@ -215,8 +210,7 @@ public class CompletedDownloadsFragment extends Fragment { } @Override - public void onBindViewHolder(EpisodeItemViewHolder holder, int pos) { - super.onBindViewHolder(holder, pos); + public void afterBindViewHolder(EpisodeItemViewHolder holder, int pos) { DeleteActionButton actionButton = new DeleteActionButton(getItem(pos)); actionButton.configure(holder.secondaryActionButton, holder.secondaryActionIcon, getActivity()); } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java index 2a7c1f2b1..189e026a1 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java @@ -1,12 +1,9 @@ package de.danoeh.antennapod.fragment; -import android.content.Context; import android.content.DialogInterface; -import android.content.SharedPreferences; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.SimpleItemAnimator; import android.util.Log; @@ -20,13 +17,12 @@ import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; -import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration; - import de.danoeh.antennapod.adapter.EpisodeItemListAdapter; import de.danoeh.antennapod.core.event.FeedListUpdateEvent; import de.danoeh.antennapod.core.event.PlaybackPositionEvent; import de.danoeh.antennapod.core.event.PlayerStatusEvent; import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent; +import de.danoeh.antennapod.view.EpisodeItemListRecyclerView; import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -61,18 +57,15 @@ import io.reactivex.schedulers.Schedulers; public abstract class EpisodesListFragment extends Fragment { public static final String TAG = "EpisodesListFragment"; - private static final String DEFAULT_PREF_NAME = "PrefAllEpisodesFragment"; - private static final String PREF_SCROLL_POSITION = "scroll_position"; - private static final String PREF_SCROLL_OFFSET = "scroll_offset"; - protected static final int EPISODES_PER_PAGE = 150; - private static final int VISIBLE_EPISODES_SCROLL_THRESHOLD = 5; protected int page = 1; + protected boolean isLoadingMore = false; + protected boolean hasMoreItems = true; - RecyclerView recyclerView; + EpisodeItemListRecyclerView recyclerView; EpisodeItemListAdapter listAdapter; ProgressBar progLoading; - View loadingMore; + View loadingMoreView; EmptyViewHandler emptyView; @NonNull @@ -81,11 +74,10 @@ public abstract class EpisodesListFragment extends Fragment { private volatile boolean isUpdatingFeeds; private boolean isMenuVisible = true; protected Disposable disposable; - private LinearLayoutManager layoutManager; protected TextView txtvInformation; String getPrefName() { - return DEFAULT_PREF_NAME; + return TAG; } @Override @@ -105,7 +97,7 @@ public abstract class EpisodesListFragment extends Fragment { @Override public void onPause() { super.onPause(); - saveScrollPosition(); + recyclerView.saveScrollPosition(getPrefName()); unregisterForContextMenu(recyclerView); } @@ -118,37 +110,6 @@ public abstract class EpisodesListFragment extends Fragment { } } - private void saveScrollPosition() { - int firstItem = layoutManager.findFirstVisibleItemPosition(); - View firstItemView = layoutManager.findViewByPosition(firstItem); - float topOffset; - if (firstItemView == null) { - topOffset = 0; - } else { - topOffset = firstItemView.getTop(); - } - - SharedPreferences prefs = getActivity().getSharedPreferences(getPrefName(), Context.MODE_PRIVATE); - SharedPreferences.Editor editor = prefs.edit(); - editor.putInt(PREF_SCROLL_POSITION, firstItem); - editor.putFloat(PREF_SCROLL_OFFSET, topOffset); - editor.apply(); - } - - private void restoreScrollPosition() { - SharedPreferences prefs = getActivity().getSharedPreferences(getPrefName(), Context.MODE_PRIVATE); - int position = prefs.getInt(PREF_SCROLL_POSITION, 0); - float offset = prefs.getFloat(PREF_SCROLL_OFFSET, 0.0f); - if (position > 0 || offset > 0) { - layoutManager.scrollToPositionWithOffset(position, (int) offset); - // restore once, then forget - SharedPreferences.Editor editor = prefs.edit(); - editor.putInt(PREF_SCROLL_POSITION, 0); - editor.putFloat(PREF_SCROLL_OFFSET, 0.0f); - editor.apply(); - } - } - private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = () -> DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds(); @@ -241,12 +202,9 @@ public abstract class EpisodesListFragment extends Fragment { View root = inflater.inflate(R.layout.all_episodes_fragment, container, false); txtvInformation = root.findViewById(R.id.txtvInformation); - layoutManager = new LinearLayoutManager(getActivity()); recyclerView = root.findViewById(android.R.id.list); - recyclerView.setLayoutManager(layoutManager); - recyclerView.setHasFixedSize(true); - recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).build()); recyclerView.setVisibility(View.GONE); + recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool()); setupLoadMoreScrollListener(); RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator(); @@ -256,7 +214,7 @@ public abstract class EpisodesListFragment extends Fragment { progLoading = root.findViewById(R.id.progLoading); progLoading.setVisibility(View.VISIBLE); - loadingMore = root.findViewById(R.id.loadingMore); + loadingMoreView = root.findViewById(R.id.loadingMore); emptyView = new EmptyViewHandler(getContext()); emptyView.attachToRecyclerView(recyclerView); @@ -272,33 +230,10 @@ public abstract class EpisodesListFragment extends Fragment { private void setupLoadMoreScrollListener() { recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - - /* Total number of episodes after last load */ - private int previousTotalEpisodes = 0; - - /* True if loading more episodes is still in progress */ - private boolean isLoadingMore = true; - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int deltaX, int deltaY) { - super.onScrolled(recyclerView, deltaX, deltaY); - - int visibleEpisodeCount = recyclerView.getChildCount(); - int totalEpisodeCount = recyclerView.getLayoutManager().getItemCount(); - int firstVisibleEpisode = layoutManager.findFirstVisibleItemPosition(); - - /* Determine if loading more episodes has finished */ - if (isLoadingMore) { - if (totalEpisodeCount > previousTotalEpisodes) { - isLoadingMore = false; - previousTotalEpisodes = totalEpisodeCount; - } - } - - /* Determine if the user scrolled to the bottom and loading more episodes is not already in progress */ - if (!isLoadingMore && (totalEpisodeCount - visibleEpisodeCount) - <= (firstVisibleEpisode + VISIBLE_EPISODES_SCROLL_THRESHOLD)) { - + public void onScrolled(@NonNull RecyclerView view, int deltaX, int deltaY) { + super.onScrolled(view, deltaX, deltaY); + if (!isLoadingMore && hasMoreItems && recyclerView.isScrolledToBottom()) { /* The end of the list has been reached. Load more data. */ page++; loadMoreItems(); @@ -312,26 +247,35 @@ public abstract class EpisodesListFragment extends Fragment { if (disposable != null) { disposable.dispose(); } - loadingMore.setVisibility(View.VISIBLE); + isLoadingMore = true; + loadingMoreView.setVisibility(View.VISIBLE); disposable = Observable.fromCallable(this::loadMoreData) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(data -> { - loadingMore.setVisibility(View.GONE); - progLoading.setVisibility(View.GONE); + if (data.size() < EPISODES_PER_PAGE) { + hasMoreItems = false; + } episodes.addAll(data); onFragmentLoaded(episodes); - }, error -> Log.e(TAG, Log.getStackTraceString(error))); + }, error -> Log.e(TAG, Log.getStackTraceString(error)), + () -> { + recyclerView.post(() -> isLoadingMore = false); // Make sure to not always load 2 pages at once + progLoading.setVisibility(View.GONE); + loadingMoreView.setVisibility(View.GONE); + }); } protected void onFragmentLoaded(List episodes) { + boolean restoreScrollPosition = listAdapter.getItemCount() == 0; if (episodes.size() == 0) { createRecycleAdapter(recyclerView, emptyView); } else { listAdapter.updateItems(episodes); } - - restoreScrollPosition(); + if (restoreScrollPosition) { + recyclerView.restoreScrollPosition(getPrefName()); + } if (isMenuVisible && isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) { requireActivity().invalidateOptionsMenu(); } @@ -431,6 +375,7 @@ public abstract class EpisodesListFragment extends Fragment { .observeOn(AndroidSchedulers.mainThread()) .subscribe(data -> { progLoading.setVisibility(View.GONE); + hasMoreItems = true; episodes = data; onFragmentLoaded(episodes); }, error -> Log.e(TAG, Log.getStackTraceString(error))); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java index c9502ae4c..9bfb4d6dc 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java @@ -23,7 +23,6 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; @@ -31,7 +30,6 @@ import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout; import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.widget.IconTextView; -import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.EpisodeItemListAdapter; @@ -66,6 +64,7 @@ import de.danoeh.antennapod.dialog.RenameFeedDialog; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.menuhandler.FeedMenuHandler; import de.danoeh.antennapod.menuhandler.MenuItemUtils; +import de.danoeh.antennapod.view.EpisodeItemListRecyclerView; import de.danoeh.antennapod.view.ToolbarIconTintManager; import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder; import io.reactivex.Observable; @@ -90,7 +89,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem private MoreContentListFooterUtil nextPageLoader; private ProgressBar progressBar; - private RecyclerView recyclerView; + private EpisodeItemListRecyclerView recyclerView; private TextView txtvTitle; private IconTextView txtvFailure; private ImageView imgvBackground; @@ -144,10 +143,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); recyclerView = root.findViewById(R.id.recyclerView); - LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); - recyclerView.setLayoutManager(layoutManager); - recyclerView.setHasFixedSize(true); - recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).build()); + recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool()); recyclerView.setVisibility(View.GONE); progressBar = root.findViewById(R.id.progLoading); @@ -193,16 +189,11 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem }); recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int deltaX, int deltaY) { - super.onScrolled(recyclerView, deltaX, deltaY); - - int visibleEpisodeCount = recyclerView.getChildCount(); - int totalEpisodeCount = recyclerView.getLayoutManager().getItemCount(); - int firstVisibleEpisode = layoutManager.findFirstVisibleItemPosition(); - - boolean isAtBottom = (totalEpisodeCount - visibleEpisodeCount) <= (firstVisibleEpisode + 3); + public void onScrolled(@NonNull RecyclerView view, int deltaX, int deltaY) { + super.onScrolled(view, deltaX, deltaY); boolean hasMorePages = feed != null && feed.isPaged() && feed.getNextPageLink() != null; - nextPageLoader.getRoot().setVisibility((isAtBottom && hasMorePages) ? View.VISIBLE : View.GONE); + nextPageLoader.getRoot().setVisibility( + (recyclerView.isScrolledToBottom() && hasMorePages) ? View.VISIBLE : View.GONE); } }); @@ -556,12 +547,9 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem super(mainActivity); } - @NonNull @Override - public EpisodeItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - EpisodeItemViewHolder viewHolder = super.onCreateViewHolder(parent, viewType); - viewHolder.coverHolder.setVisibility(View.GONE); - return viewHolder; + protected void beforeBindViewHolder(EpisodeItemViewHolder holder, int pos) { + holder.coverHolder.setVisibility(View.GONE); } } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java index 4aac34c60..269c33962 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java @@ -8,12 +8,13 @@ import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.util.playback.PlaybackController; import de.danoeh.antennapod.core.util.playback.Timeline; import de.danoeh.antennapod.view.ShownotesWebView; +import io.reactivex.Maybe; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; @@ -74,7 +75,7 @@ public class ItemDescriptionFragment extends Fragment { if (webViewLoader != null) { webViewLoader.dispose(); } - webViewLoader = Observable.fromCallable(this::loadData) + webViewLoader = Maybe.fromCallable(this::loadData) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(data -> { @@ -84,10 +85,14 @@ public class ItemDescriptionFragment extends Fragment { }, error -> Log.e(TAG, Log.getStackTraceString(error))); } - @NonNull + @Nullable private String loadData() { - Timeline timeline = new Timeline(getActivity(), controller.getMedia()); - return timeline.processShownotes(); + if (controller.getMedia() != null) { + Timeline timeline = new Timeline(getActivity(), controller.getMedia()); + return timeline.processShownotes(); + } else { + return null; + } } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java index 4a7b9603d..dabff7269 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java @@ -16,9 +16,6 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.core.view.MenuItemCompat; import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.EpisodeItemListAdapter; @@ -34,6 +31,7 @@ import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.view.EmptyViewHandler; +import de.danoeh.antennapod.view.EpisodeItemListRecyclerView; import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -51,7 +49,7 @@ public class PlaybackHistoryFragment extends Fragment { private List playbackHistory; private PlaybackHistoryListAdapter adapter; private Disposable disposable; - private RecyclerView recyclerView; + private EpisodeItemListRecyclerView recyclerView; private EmptyViewHandler emptyView; private ProgressBar progressBar; @@ -71,10 +69,7 @@ public class PlaybackHistoryFragment extends Fragment { ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); recyclerView = root.findViewById(R.id.recyclerView); - LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); - recyclerView.setLayoutManager(layoutManager); - recyclerView.setHasFixedSize(true); - recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).build()); + recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool()); recyclerView.setVisibility(View.GONE); adapter = new PlaybackHistoryListAdapter((MainActivity) getActivity()); recyclerView.setAdapter(adapter); @@ -246,8 +241,7 @@ public class PlaybackHistoryFragment extends Fragment { } @Override - public void onBindViewHolder(EpisodeItemViewHolder holder, int pos) { - super.onBindViewHolder(holder, pos); + protected void afterBindViewHolder(EpisodeItemViewHolder holder, int pos) { // played items shouldn't be transparent for this fragment since, *all* items // in this fragment will, by definition, be played. So it serves no purpose and can make // it harder to read. diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java index 0411fd01b..f2a5bdc67 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java @@ -18,11 +18,9 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.ItemTouchHelper; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.SimpleItemAnimator; import com.google.android.material.snackbar.Snackbar; -import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.QueueRecyclerAdapter; @@ -49,6 +47,7 @@ import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.menuhandler.MenuItemUtils; import de.danoeh.antennapod.view.EmptyViewHandler; +import de.danoeh.antennapod.view.EpisodeItemListRecyclerView; import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -71,7 +70,7 @@ public class QueueFragment extends Fragment { public static final String TAG = "QueueFragment"; private TextView infoBar; - private RecyclerView recyclerView; + private EpisodeItemListRecyclerView recyclerView; private QueueRecyclerAdapter recyclerAdapter; private EmptyViewHandler emptyView; private ProgressBar progLoading; @@ -81,16 +80,12 @@ public class QueueFragment extends Fragment { private boolean isUpdatingFeeds = false; private static final String PREFS = "QueueFragment"; - private static final String PREF_SCROLL_POSITION = "scroll_position"; - private static final String PREF_SCROLL_OFFSET = "scroll_offset"; private static final String PREF_SHOW_LOCK_WARNING = "show_lock_warning"; private Disposable disposable; - private LinearLayoutManager layoutManager; private ItemTouchHelper itemTouchHelper; private SharedPreferences prefs; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -112,7 +107,7 @@ public class QueueFragment extends Fragment { @Override public void onPause() { super.onPause(); - saveScrollPosition(); + recyclerView.saveScrollPosition(QueueFragment.TAG); } @Override @@ -159,7 +154,7 @@ public class QueueFragment extends Fragment { case MOVED: return; } - saveScrollPosition(); + recyclerView.saveScrollPosition(QueueFragment.TAG); onFragmentLoaded(false); } @@ -232,30 +227,6 @@ public class QueueFragment extends Fragment { } } - private void saveScrollPosition() { - int firstItem = layoutManager.findFirstVisibleItemPosition(); - View firstItemView = layoutManager.findViewByPosition(firstItem); - float topOffset; - if(firstItemView == null) { - topOffset = 0; - } else { - topOffset = firstItemView.getTop(); - } - - prefs.edit() - .putInt(PREF_SCROLL_POSITION, firstItem) - .putFloat(PREF_SCROLL_OFFSET, topOffset) - .apply(); - } - - private void restoreScrollPosition() { - int position = prefs.getInt(PREF_SCROLL_POSITION, 0); - float offset = prefs.getFloat(PREF_SCROLL_OFFSET, 0.0f); - if (position > 0 || offset > 0) { - layoutManager.scrollToPositionWithOffset(position, (int) offset); - } - } - private void resetViewState() { recyclerAdapter = null; } @@ -480,9 +451,7 @@ public class QueueFragment extends Fragment { if (animator instanceof SimpleItemAnimator) { ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false); } - layoutManager = new LinearLayoutManager(getActivity()); - recyclerView.setLayoutManager(layoutManager); - recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).build()); + recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool()); registerForContextMenu(recyclerView); itemTouchHelper = new ItemTouchHelper( @@ -598,7 +567,7 @@ public class QueueFragment extends Fragment { } if (restoreScrollPosition) { - restoreScrollPosition(); + recyclerView.restoreScrollPosition(QueueFragment.TAG); } // we need to refresh the options menu because it sometimes diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java index 389996b07..1ebf382fe 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SearchFragment.java @@ -1,6 +1,5 @@ package de.danoeh.antennapod.fragment; -import android.content.Context; import android.os.Bundle; import android.util.Log; import android.util.Pair; @@ -18,7 +17,6 @@ import androidx.appcompat.widget.SearchView; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.EpisodeItemListAdapter; @@ -35,6 +33,7 @@ import de.danoeh.antennapod.core.storage.FeedSearcher; import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.view.EmptyViewHandler; +import de.danoeh.antennapod.view.EpisodeItemListRecyclerView; import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -59,8 +58,7 @@ public class SearchFragment extends Fragment { private Disposable disposable; private ProgressBar progressBar; private EmptyViewHandler emptyViewHandler; - private RecyclerView recyclerView; - private RecyclerView recyclerViewFeeds; + private EpisodeItemListRecyclerView recyclerView; private List results; /** @@ -117,15 +115,12 @@ public class SearchFragment extends Fragment { progressBar = layout.findViewById(R.id.progressBar); recyclerView = layout.findViewById(R.id.recyclerView); - LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); - recyclerView.setLayoutManager(layoutManager); - recyclerView.setHasFixedSize(true); - recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).build()); + recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool()); recyclerView.setVisibility(View.GONE); adapter = new EpisodeItemListAdapter((MainActivity) getActivity()); recyclerView.setAdapter(adapter); - recyclerViewFeeds = layout.findViewById(R.id.recyclerViewFeeds); + RecyclerView recyclerViewFeeds = layout.findViewById(R.id.recyclerViewFeeds); LinearLayoutManager layoutManagerFeeds = new LinearLayoutManager(getActivity()); layoutManagerFeeds.setOrientation(RecyclerView.HORIZONTAL); recyclerViewFeeds.setLayoutManager(layoutManagerFeeds); -- cgit v1.2.3