diff options
author | ByteHamster <info@bytehamster.com> | 2022-05-08 10:55:05 +0200 |
---|---|---|
committer | ByteHamster <info@bytehamster.com> | 2022-05-08 11:18:53 +0200 |
commit | 03220d07748d0908c4cf4e6b260ce828dc5ebaac (patch) | |
tree | 720174ef3c0e09e19841cdfbbc47ed5257d78a83 | |
parent | 7c0d084ffcc6a17ccac043a76f6640c89dea6272 (diff) | |
download | AntennaPod-03220d07748d0908c4cf4e6b260ce828dc5ebaac.zip |
Show correct total number for lazy loaded items
9 files changed, 72 insertions, 5 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/EpisodeItemListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/EpisodeItemListAdapter.java index 8fb4a6314..088caf70a 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/EpisodeItemListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/EpisodeItemListAdapter.java @@ -195,8 +195,8 @@ public class EpisodeItemListAdapter extends SelectableAdapter<EpisodeItemViewHol setSelected(0, longPressedPosition, true); return true; } else if (item.getItemId() == R.id.select_all_below) { - setSelected(longPressedPosition + 1, getItemCount(), true); shouldSelectLazyLoadedItems = true; + setSelected(longPressedPosition + 1, getItemCount(), true); return true; } return false; diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SelectableAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/SelectableAdapter.java index 55669596b..70d00cbff 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/SelectableAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/SelectableAdapter.java @@ -15,12 +15,14 @@ import java.util.HashSet; /** * Used by Recyclerviews that need to provide ability to select items. */ -abstract class SelectableAdapter<T extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<T> { +public abstract class SelectableAdapter<T extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<T> { + public static final int COUNT_AUTOMATICALLY = -1; private ActionMode actionMode; private final HashSet<Long> selectedIds = new HashSet<>(); private final Activity activity; private OnSelectModeListener onSelectModeListener; boolean shouldSelectLazyLoadedItems = false; + private int totalNumberOfItems = COUNT_AUTOMATICALLY; public SelectableAdapter(Activity activity) { this.activity = activity; @@ -155,9 +157,17 @@ abstract class SelectableAdapter<T extends RecyclerView.ViewHolder> extends Recy if (actionMode == null) { return; } + int totalCount = getItemCount(); + int selectedCount = selectedIds.size(); + if (totalNumberOfItems != COUNT_AUTOMATICALLY) { + totalCount = totalNumberOfItems; + if (shouldSelectLazyLoadedItems) { + selectedCount += (totalNumberOfItems - getItemCount()); + } + } actionMode.setTitle(activity.getResources() .getQuantityString(R.plurals.num_selected_label, selectedIds.size(), - selectedIds.size(), getItemCount())); + selectedCount, totalCount)); } public void setOnSelectModeListener(OnSelectModeListener onSelectModeListener) { @@ -174,6 +184,14 @@ abstract class SelectableAdapter<T extends RecyclerView.ViewHolder> extends Recy return shouldSelectLazyLoadedItems; } + /** + * Sets the total number of items that could be lazy-loaded. + * Can also be set to {@link #COUNT_AUTOMATICALLY} to simply use {@link #getItemCount} + */ + public void setTotalNumberOfItems(int totalNumberOfItems) { + this.totalNumberOfItems = totalNumberOfItems; + } + public interface OnSelectModeListener { void onStartSelectMode(); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java index 853e7d6f7..2627da3d9 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java @@ -105,4 +105,9 @@ public class AllEpisodesFragment extends EpisodesListFragment { protected List<FeedItem> loadMoreData() { return DBReader.getRecentlyPublishedEpisodes((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE, feedItemFilter); } + + @Override + protected int loadTotalItemCount() { + return DBReader.getTotalEpisodeCount(feedItemFilter); + } } 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 55134cbfa..e47599e3b 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java @@ -5,6 +5,7 @@ import android.os.Bundle; import android.view.ContextMenu; import android.view.KeyEvent; import androidx.annotation.NonNull; +import androidx.core.util.Pair; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.SimpleItemAnimator; @@ -25,6 +26,7 @@ import android.widget.Toast; import com.google.android.material.snackbar.Snackbar; import com.leinardi.android.speeddial.SpeedDialView; import de.danoeh.antennapod.adapter.EpisodeItemListAdapter; +import de.danoeh.antennapod.adapter.SelectableAdapter; import de.danoeh.antennapod.event.FeedListUpdateEvent; import de.danoeh.antennapod.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.event.PlayerStatusEvent; @@ -447,14 +449,15 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt if (disposable != null) { disposable.dispose(); } - disposable = Observable.fromCallable(this::loadData) + disposable = Observable.fromCallable(() -> new Pair<>(loadData(), loadTotalItemCount())) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(data -> { progLoading.setVisibility(View.GONE); loadingMoreView.setVisibility(View.GONE); hasMoreItems = true; - episodes = data; + episodes = data.first; + listAdapter.setTotalNumberOfItems(data.second); onFragmentLoaded(episodes); if (getParentFragment() instanceof PagedToolbarFragment) { ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this); @@ -475,4 +478,11 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt */ @NonNull protected abstract List<FeedItem> loadMoreData(); + + /** + * Returns the total number of items that would be returned if {@link #loadMoreData} was called often enough. + */ + protected int loadTotalItemCount() { + return SelectableAdapter.COUNT_AUTOMATICALLY; + } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java index 33aba3b54..56b2b433f 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java @@ -12,6 +12,7 @@ import android.view.View; import android.view.ViewGroup; import de.danoeh.antennapod.activity.MainActivity; +import de.danoeh.antennapod.model.feed.FeedItemFilter; import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder; import org.greenrobot.eventbus.Subscribe; @@ -101,4 +102,9 @@ public class FavoriteEpisodesFragment extends EpisodesListFragment { protected List<FeedItem> loadMoreData() { return DBReader.getFavoriteItemsList((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE); } + + @Override + protected int loadTotalItemCount() { + return DBReader.getTotalEpisodeCount(new FeedItemFilter(FeedItemFilter.IS_FAVORITE)); + } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java index 5063da9a4..14bfe2951 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java @@ -119,4 +119,9 @@ public class InboxFragment extends EpisodesListFragment implements Toolbar.OnMen protected List<FeedItem> loadMoreData() { return DBReader.getNewItemsList((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE); } + + @Override + protected int loadTotalItemCount() { + return DBReader.getTotalEpisodeCount(new FeedItemFilter(FeedItemFilter.NEW)); + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java index a55aed9df..cffcbf32f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java @@ -402,6 +402,19 @@ public final class DBReader { } } + public static int getTotalEpisodeCount(FeedItemFilter filter) { + PodDBAdapter adapter = PodDBAdapter.getInstance(); + adapter.open(); + try (Cursor cursor = adapter.getTotalEpisodeCountCursor(filter)) { + if (cursor.moveToFirst()) { + return cursor.getInt(0); + } + return -1; + } finally { + adapter.close(); + } + } + /** * Loads the playback history from the database. A FeedItem is in the playback history if playback of the correpsonding episode * has been completed at least once. diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/PodDBAdapter.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/PodDBAdapter.java index 3f361eb89..41c8e051a 100644 --- a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/PodDBAdapter.java +++ b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/PodDBAdapter.java @@ -1052,6 +1052,14 @@ public class PodDBAdapter { return db.rawQuery(query, null); } + public final Cursor getTotalEpisodeCountCursor(FeedItemFilter filter) { + String filterQuery = FeedItemFilterQuery.generateFrom(filter); + String whereClause = "".equals(filterQuery) ? "" : " WHERE " + filterQuery; + final String query = "SELECT count(" + TABLE_NAME_FEED_ITEMS + "." + KEY_ID + ") FROM " + TABLE_NAME_FEED_ITEMS + + JOIN_FEED_ITEM_AND_MEDIA + whereClause; + return db.rawQuery(query, null); + } + public Cursor getDownloadedItemsCursor() { final String query = SELECT_FEED_ITEMS_AND_MEDIA + "WHERE " + TABLE_NAME_FEED_MEDIA + "." + KEY_DOWNLOADED + " > 0"; diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemFilterQuery.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemFilterQuery.java index 1728a905f..6c78af50c 100644 --- a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemFilterQuery.java +++ b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemFilterQuery.java @@ -34,6 +34,8 @@ public class FeedItemFilterQuery { statements.add(keyRead + " = 1 "); } else if (filter.showUnplayed) { statements.add(" NOT " + keyRead + " = 1 "); // Match "New" items (read = -1) as well + } else if (filter.showNew) { + statements.add(keyRead + " = -1 "); } if (filter.showPaused) { statements.add(" (" + keyPosition + " NOT NULL AND " + keyPosition + " > 0 " + ") "); |