Reverted to loading behavior of #7638 and improved it

The previous/reverted behavior caused unwanted data transmission:
* Removed loading via handleResults/loadMoreItems-callback because the RecyclerView is apparently not immediately updated in the UI when the data is set which causes one load of data to much.
This commit is contained in:
litetex 2022-01-16 19:05:51 +01:00
parent d3cd3d62b4
commit ff7cfe4715
3 changed files with 68 additions and 80 deletions

View File

@ -312,12 +312,72 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
}); });
itemsList.clearOnScrollListeners(); itemsList.clearOnScrollListeners();
itemsList.addOnScrollListener(new OnScrollBelowItemsListener() {
/*
* Add initial scroll listener - which tries to load more items when not enough
* are in the view (not scrollable) and more are available.
*
* Note: This method only works because "This callback will also be called if visible
* item range changes after a layout calculation. In that case, dx and dy will be 0."
* - which might be unexpected because no actual scrolling occurs...
*
* This listener will be replaced by DefaultItemListOnScrolledDownListener when
* * the view was actually scrolled
* * the view is scrollable
* * No more items can be loaded
*/
itemsList.addOnScrollListener(new DefaultItemListOnScrolledDownListener() {
@Override
public void onScrolled(final RecyclerView recyclerView, final int dx, final int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy != 0) {
log("Vertical scroll occurred");
useNormalScrollListener();
return;
}
if (isLoading.get()) {
log("Still loading data -> Skipping");
return;
}
if (!hasMoreItems()) {
log("No more items to load");
useNormalScrollListener();
return;
}
if (itemsList.canScrollVertically(1)
|| itemsList.canScrollVertically(-1)) {
log("View is scrollable");
useNormalScrollListener();
return;
}
log("Loading more data");
loadMoreItems();
}
private void useNormalScrollListener() {
log("Unregistering and using normal listener");
itemsList.removeOnScrollListener(this);
itemsList.addOnScrollListener(new DefaultItemListOnScrolledDownListener());
}
private void log(final String msg) {
if (DEBUG) {
Log.d(TAG, "itemListInitScrollListener - " + msg);
}
}
});
}
class DefaultItemListOnScrolledDownListener extends OnScrollBelowItemsListener {
@Override @Override
public void onScrolledDown(final RecyclerView recyclerView) { public void onScrolledDown(final RecyclerView recyclerView) {
onScrollToBottom(); onScrollToBottom();
} }
});
} }
private void onStreamSelected(final StreamInfoItem selectedItem) { private void onStreamSelected(final StreamInfoItem selectedItem) {
@ -407,66 +467,7 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I>
// Load and handle // Load and handle
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
/** protected abstract void loadMoreItems();
* If more items are loadable and the itemList is not scrollable -> load more data.
* <br/>
* Should be called once the initial items inside {@link #startLoading(boolean)}
* has been loaded and added to the {@link #itemsList}.
* <br/>
* Otherwise the loading indicator is always shown but no data can be loaded
* because the view is not scrollable; see also #1974.
*/
protected void ifMoreItemsLoadableLoadUntilScrollable() {
ifMoreItemsLoadableLoadUntilScrollable(0);
}
/**
* If more items are loadable and the itemList is not scrollable -> load more data.
*
* @param recursiveCallCount Amount of recursive calls that occurred
* @see #ifMoreItemsLoadableLoadUntilScrollable()
*/
protected void ifMoreItemsLoadableLoadUntilScrollable(final int recursiveCallCount) {
// Try to prevent malfunction / stackoverflow
if (recursiveCallCount > 100) {
Log.w(TAG, "loadEnoughInitialData - Too many recursive calls - Aborting");
return;
}
if (!hasMoreItems()) {
if (DEBUG) {
Log.d(TAG, "loadEnoughInitialData - OK: No more items to load");
}
return;
}
if (itemsList.canScrollVertically(1)
|| itemsList.canScrollVertically(-1)) {
if (DEBUG) {
Log.d(TAG, "loadEnoughInitialData - OK: itemList is scrollable");
}
return;
}
if (DEBUG) {
Log.d(TAG, "loadEnoughInitialData - View is not scrollable "
+ "but it could load more items -> Loading more");
}
loadMoreItems(() ->
ifMoreItemsLoadableLoadUntilScrollable(recursiveCallCount + 1));
}
/**
* Loads more items.
* @param initialDataLoadCallback
* Callback used in {@link #ifMoreItemsLoadableLoadUntilScrollable()}.
* <br/>
* Execute it once the data was loaded and added to the {@link #itemsList}.
* <br/>
* Might be <code>null</code>.
*/
protected abstract void loadMoreItems(@Nullable Runnable initialDataLoadCallback);
protected void loadMoreItems() {
loadMoreItems(null);
}
protected abstract boolean hasMoreItems(); protected abstract boolean hasMoreItems();

View File

@ -6,7 +6,6 @@ import android.util.Log;
import android.view.View; import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.error.UserAction;
@ -146,7 +145,6 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
currentInfo = result; currentInfo = result;
currentNextPage = result.getNextPage(); currentNextPage = result.getNextPage();
handleResult(result); handleResult(result);
ifMoreItemsLoadableLoadUntilScrollable();
}, throwable -> }, throwable ->
showError(new ErrorInfo(throwable, errorUserAction, showError(new ErrorInfo(throwable, errorUserAction,
"Start loading: " + url, serviceId))); "Start loading: " + url, serviceId)));
@ -162,7 +160,7 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
protected abstract Single<ListExtractor.InfoItemsPage> loadMoreItemsLogic(); protected abstract Single<ListExtractor.InfoItemsPage> loadMoreItemsLogic();
@Override @Override
protected void loadMoreItems(@Nullable final Runnable initialDataLoadCallback) { protected void loadMoreItems() {
isLoading.set(true); isLoading.set(true);
if (currentWorker != null) { if (currentWorker != null) {
@ -178,9 +176,6 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
.subscribe(infoItemsPage -> { .subscribe(infoItemsPage -> {
isLoading.set(false); isLoading.set(false);
handleNextItems(infoItemsPage); handleNextItems(infoItemsPage);
if (initialDataLoadCallback != null) {
initialDataLoadCallback.run();
}
}, (@NonNull Throwable throwable) -> }, (@NonNull Throwable throwable) ->
dynamicallyShowErrorPanelOrSnackbar(new ErrorInfo(throwable, dynamicallyShowErrorPanelOrSnackbar(new ErrorInfo(throwable,
errorUserAction, "Loading more items: " + url, serviceId))); errorUserAction, "Loading more items: " + url, serviceId)));

View File

@ -868,15 +868,12 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.doOnEvent((searchResult, throwable) -> isLoading.set(false)) .doOnEvent((searchResult, throwable) -> isLoading.set(false))
.subscribe(result -> { .subscribe(this::handleResult, this::onItemError);
handleResult(result);
ifMoreItemsLoadableLoadUntilScrollable();
}, this::onItemError);
} }
@Override @Override
protected void loadMoreItems(@Nullable final Runnable initialDataLoadCallback) { protected void loadMoreItems() {
if (!Page.isValid(nextPage)) { if (!Page.isValid(nextPage)) {
return; return;
} }
@ -894,12 +891,7 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.doOnEvent((nextItemsResult, throwable) -> isLoading.set(false)) .doOnEvent((nextItemsResult, throwable) -> isLoading.set(false))
.subscribe(itemsPage -> { .subscribe(this::handleNextItems, this::onItemError);
handleNextItems(itemsPage);
if (initialDataLoadCallback != null) {
initialDataLoadCallback.run();
}
}, this::onItemError);
} }
@Override @Override