Fix header crash while scrolling in a playlist or just after deleting a video in it#12996
Merged
Stypox merged 3 commits intoTeamNewPipe:devfrom Jan 27, 2026
Conversation
... Crash in lists (ViewHolder views not attached) in StatisticsPlaylistFragment Co-Authored-By: j-haldane <200528955+j-haldane@users.noreply.github.com>
Co-Authored-By: j-haldane <200528955+j-haldane@users.noreply.github.com>
7 tasks
80fd46a to
cea5dd4
Compare
7 tasks
Stypox
approved these changes
Jan 27, 2026
Member
There was a problem hiding this comment.
Thank you! I was wondering whether this should be done also for footer, but it turns out that, while the footer View is always set, showFooter is always equal to false in local lists. So I am pushing a commit to add some @Deprecated and calling it a day, since I want to avoid touching code that works.
Here is the path for footer supplier
commit b759c91a147a662d30e938ed39834120cc12e75b
Merge: cea5dd474 f9ef7938b
Author: Stypox <stypox@pm.me>
Date: Tue Jan 27 21:24:06 2026 +0100
On pr12996: Use footerSupplier instead of footer (but useless since footer always invisible anyway)
diff --cc app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java
index 00a721bcf,00a721bcf..af22c814b
--- a/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java
@@@ -138,7 -138,7 +138,7 @@@ public abstract class BaseLocalListFrag
itemListAdapter.setHeaderSupplier(listHeaderSupplier);
}
footerRootBinding = getListFooter();
-- itemListAdapter.setFooter(footerRootBinding.getRoot());
++ itemListAdapter.setFooterSupplier(footerRootBinding::getRoot);
itemsList.setAdapter(itemListAdapter);
}
diff --cc app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java
index 3bb84e2de,3bb84e2de..7e4c78256
--- a/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java
+++ b/app/src/main/java/org/schabi/newpipe/local/LocalItemListAdapter.java
@@@ -90,7 -90,7 +90,7 @@@ public class LocalItemListAdapter exten
private boolean showFooter = false;
private Supplier<View> headerSupplier = null;
-- private View footer = null;
++ private Supplier<View> footerSupplier = null;
private ItemViewMode itemViewMode = ItemViewMode.LIST;
private boolean useItemHandle = false;
@@@ -126,12 -126,12 +126,12 @@@
if (DEBUG) {
Log.d(TAG, "addItems() after > offsetStart = " + offsetStart + ", "
+ "localItems.size() = " + localItems.size() + ", "
-- + "header = " + hasHeader() + ", footer = " + footer + ", "
++ + "header = " + hasHeader() + ", footer = " + hasFooter() + ", "
+ "showFooter = " + showFooter);
}
notifyItemRangeInserted(offsetStart, data.size());
-- if (footer != null && showFooter) {
++ if (hasFooter() && showFooter) {
final int footerNow = sizeConsideringHeader();
notifyItemMoved(offsetStart, footerNow);
@@@ -199,14 -199,14 +199,18 @@@
}
}
-- public void setFooter(final View view) {
-- this.footer = view;
++ public void setFooterSupplier(@Nullable final Supplier<View> footerSupplier) {
++ this.footerSupplier = footerSupplier;
}
protected boolean hasHeader() {
return this.headerSupplier != null;
}
++ protected boolean hasFooter() {
++ return this.footerSupplier != null;
++ }
++
public void showFooter(final boolean show) {
if (DEBUG) {
Log.d(TAG, "showFooter() called with: show = [" + show + "]");
@@@ -241,14 -241,14 +245,14 @@@
if (hasHeader()) {
count++;
}
-- if (footer != null && showFooter) {
++ if (hasFooter() && showFooter) {
count++;
}
if (DEBUG) {
Log.d(TAG, "getItemCount() called, count = " + count + ", "
+ "localItems.size() = " + localItems.size() + ", "
-- + "header = " + hasHeader() + ", footer = " + footer + ", "
++ + "header = " + hasHeader() + ", footer = " + hasFooter() + ", "
+ "showFooter = " + showFooter);
}
return count;
@@@ -266,7 -266,7 +270,7 @@@
} else if (hasHeader()) {
position--;
}
-- if (footer != null && position == localItems.size() && showFooter) {
++ if (hasFooter() && position == localItems.size() && showFooter) {
return FOOTER_TYPE;
}
final LocalItem item = localItems.get(position);
@@@ -326,7 -326,7 +330,7 @@@
case HEADER_TYPE:
return new HeaderFooterHolder(headerSupplier.get());
case FOOTER_TYPE:
-- return new HeaderFooterHolder(footer);
++ return new HeaderFooterHolder(footerSupplier.get());
case LOCAL_PLAYLIST_HOLDER_TYPE:
return new LocalPlaylistItemHolder(localItemBuilder, parent);
case LOCAL_PLAYLIST_GRID_HOLDER_TYPE:
@@@ -381,8 -381,8 +385,8 @@@
} 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;
++ && hasFooter() && showFooter) {
++ ((HeaderFooterHolder) holder).view = footerSupplier.get();
}
}
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is it?
refactorbranchDescription of the changes in your PR
Fully implement Fix header crash in History list view #12214 by reapplying reverted commits 2abe71c and ab73dc1 which were thought not required at that point of time but actually they do fix the issue in local playlist fragment, removing the animation fixed the crash for history view only.
Changes adapted from d3cd3d6 by @j-haldane
Fixes the following issue(s)
APK testing
The APK can be found by going to the "Checks" tab below the title. On the left pane, click on "CI", scroll down to "artifacts" and click "app" to download the zip file which contains the debug APK of this PR. You can find more info and a video demonstration on this wiki page.
Due diligence