diff --git a/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java b/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java index 90ef8c352b8..00a721bcf88 100644 --- a/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java @@ -28,6 +28,8 @@ import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling; import static org.schabi.newpipe.util.ThemeHelper.getItemViewMode; +import java.util.function.Supplier; + /** * This fragment is design to be used with persistent data such as * {@link org.schabi.newpipe.database.LocalItem}, and does not cache the data contained @@ -100,7 +102,7 @@ private void refreshItemViewMode() { //////////////////////////////////////////////////////////////////////////*/ @Nullable - protected ViewBinding getListHeader() { + protected Supplier getListHeaderSupplier() { return null; } @@ -131,9 +133,9 @@ protected void initViews(final View rootView, final Bundle savedInstanceState) { itemsList = rootView.findViewById(R.id.items_list); refreshItemViewMode(); - headerRootBinding = getListHeader(); - if (headerRootBinding != null) { - itemListAdapter.setHeader(headerRootBinding.getRoot()); + final Supplier listHeaderSupplier = getListHeaderSupplier(); + if (listHeaderSupplier != null) { + itemListAdapter.setHeaderSupplier(listHeaderSupplier); } footerRootBinding = getListFooter(); itemListAdapter.setFooter(footerRootBinding.getRoot()); diff --git a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java index b33619dea7a..3bb84e2de3c 100644 --- a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java @@ -37,6 +37,7 @@ import java.time.format.FormatStyle; import java.util.ArrayList; import java.util.List; +import java.util.function.Supplier; /* * Created by Christian Schabesberger on 01.08.16. @@ -88,7 +89,7 @@ public class LocalItemListAdapter extends RecyclerView.Adapter headerSupplier = null; private View footer = null; private ItemViewMode itemViewMode = ItemViewMode.LIST; private boolean useItemHandle = false; @@ -97,6 +98,7 @@ public LocalItemListAdapter(final Context context) { recordManager = new HistoryRecordManager(context); localItemBuilder = new LocalItemBuilder(context); localItems = new ArrayList<>(); + dateTimeFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT) .withLocale(Localization.getPreferredLocale(context)); } @@ -124,7 +126,7 @@ public void addItems(@Nullable final List data) { if (DEBUG) { Log.d(TAG, "addItems() after > offsetStart = " + offsetStart + ", " + "localItems.size() = " + localItems.size() + ", " - + "header = " + header + ", footer = " + footer + ", " + + "header = " + hasHeader() + ", footer = " + footer + ", " + "showFooter = " + showFooter); } notifyItemRangeInserted(offsetStart, data.size()); @@ -144,7 +146,7 @@ public void removeItem(final LocalItem data) { final int index = localItems.indexOf(data); if (index != -1) { localItems.remove(index); - notifyItemRemoved(index + (header != null ? 1 : 0)); + notifyItemRemoved(index + (hasHeader() ? 1 : 0)); } else { // this happens when // 1) removeItem is called on infoItemDuplicate as in showStreamItemDialog of @@ -189,9 +191,9 @@ public void setUseItemHandle(final boolean useItemHandle) { this.useItemHandle = useItemHandle; } - public void setHeader(final View header) { - final boolean changed = header != this.header; - this.header = header; + public void setHeaderSupplier(@Nullable final Supplier headerSupplier) { + final boolean changed = headerSupplier != this.headerSupplier; + this.headerSupplier = headerSupplier; if (changed) { notifyDataSetChanged(); } @@ -201,6 +203,10 @@ public void setFooter(final View view) { this.footer = view; } + protected boolean hasHeader() { + return this.headerSupplier != null; + } + public void showFooter(final boolean show) { if (DEBUG) { Log.d(TAG, "showFooter() called with: show = [" + show + "]"); @@ -218,11 +224,11 @@ public void showFooter(final boolean show) { } private int adapterOffsetWithoutHeader(final int offset) { - return offset - (header != null ? 1 : 0); + return offset - (hasHeader() ? 1 : 0); } private int sizeConsideringHeader() { - return localItems.size() + (header != null ? 1 : 0); + return localItems.size() + (hasHeader() ? 1 : 0); } public ArrayList getItemsList() { @@ -232,7 +238,7 @@ public ArrayList getItemsList() { @Override public int getItemCount() { int count = localItems.size(); - if (header != null) { + if (hasHeader()) { count++; } if (footer != null && showFooter) { @@ -242,7 +248,7 @@ public int getItemCount() { if (DEBUG) { Log.d(TAG, "getItemCount() called, count = " + count + ", " + "localItems.size() = " + localItems.size() + ", " - + "header = " + header + ", footer = " + footer + ", " + + "header = " + hasHeader() + ", footer = " + footer + ", " + "showFooter = " + showFooter); } return count; @@ -255,9 +261,9 @@ public int getItemViewType(int position) { Log.d(TAG, "getItemViewType() called with: position = [" + position + "]"); } - if (header != null && position == 0) { + if (hasHeader() && position == 0) { return HEADER_TYPE; - } else if (header != null) { + } else if (hasHeader()) { position--; } if (footer != null && position == localItems.size() && showFooter) { @@ -318,7 +324,7 @@ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull final ViewGroup paren } switch (type) { case HEADER_TYPE: - return new HeaderFooterHolder(header); + return new HeaderFooterHolder(headerSupplier.get()); case FOOTER_TYPE: return new HeaderFooterHolder(footer); case LOCAL_PLAYLIST_HOLDER_TYPE: @@ -366,14 +372,14 @@ public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int if (holder instanceof LocalItemHolder) { // If header isn't null, offset the items by -1 - if (header != null) { + if (hasHeader()) { position--; } ((LocalItemHolder) holder) .updateFromItem(localItems.get(position), recordManager, dateTimeFormatter); - } else if (holder instanceof HeaderFooterHolder && position == 0 && header != null) { - ((HeaderFooterHolder) holder).view = header; + } else if (holder instanceof HeaderFooterHolder && position == 0 && hasHeader()) { + ((HeaderFooterHolder) holder).view = headerSupplier.get(); } else if (holder instanceof HeaderFooterHolder && position == sizeConsideringHeader() && footer != null && showFooter) { ((HeaderFooterHolder) holder).view = footer; @@ -387,10 +393,10 @@ public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, fina for (final Object payload : payloads) { if (payload instanceof StreamStateEntity) { ((LocalItemHolder) holder).updateState(localItems - .get(header == null ? position : position - 1), recordManager); + .get(hasHeader() ? position - 1 : position), recordManager); } else if (payload instanceof Boolean) { ((LocalItemHolder) holder).updateState(localItems - .get(header == null ? position : position - 1), recordManager); + .get(hasHeader() ? position - 1 : position), recordManager); } } } else { diff --git a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java index 3302e387ec5..43b7f1c0db2 100644 --- a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java @@ -13,7 +13,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.viewbinding.ViewBinding; import com.evernote.android.state.State; import com.google.android.material.snackbar.Snackbar; @@ -45,6 +44,7 @@ import java.util.Comparator; import java.util.List; import java.util.Objects; +import java.util.function.Supplier; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.disposables.CompositeDisposable; @@ -126,12 +126,12 @@ protected void initViews(final View rootView, final Bundle savedInstanceState) { } @Override - protected ViewBinding getListHeader() { + protected Supplier getListHeaderSupplier() { headerBinding = StatisticPlaylistControlBinding.inflate(activity.getLayoutInflater(), itemsList, false); playlistControlBinding = headerBinding.playlistControl; - return headerBinding; + return headerBinding::getRoot; } @Override diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index d841b44b4b6..ca6ff950253 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -29,7 +29,6 @@ import androidx.appcompat.app.AlertDialog; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.RecyclerView; -import androidx.viewbinding.ViewBinding; import com.evernote.android.state.State; import org.reactivestreams.Subscriber; @@ -67,6 +66,7 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Supplier; import java.util.stream.Collectors; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; @@ -158,14 +158,14 @@ protected void initViews(final View rootView, final Bundle savedInstanceState) { } @Override - protected ViewBinding getListHeader() { + protected Supplier getListHeaderSupplier() { headerBinding = LocalPlaylistHeaderBinding.inflate(activity.getLayoutInflater(), itemsList, - false); + false); playlistControlBinding = headerBinding.playlistControl; headerBinding.playlistTitleView.setSelected(true); - return headerBinding; + return headerBinding::getRoot; } @Override