Skip to content

Commit

Permalink
Merge pull request #1452 from cemrich/bugfix/1232-inaccurate-scroll-bar
Browse files Browse the repository at this point in the history
Fix inaccurate scroll bar due to lazy loading #1232
  • Loading branch information
David-Development authored Oct 16, 2024
2 parents 025f049 + cf6c3c7 commit 09c2e95
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package de.luhmer.owncloudnewsreader

import android.content.Context
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlin.math.roundToInt

class LazyLoadingLinearLayoutManager(
context: Context?,
@RecyclerView.Orientation orientation: Int,
reverseLayout: Boolean,
) : LinearLayoutManager(context, orientation, reverseLayout) {
var totalItemCount: Int = 0

override fun computeVerticalScrollRange(state: RecyclerView.State): Int {
if (state.itemCount == 0) {
return 0
}

return (super.computeVerticalScrollRange(state) / state.itemCount.toFloat() * totalItemCount).roundToInt()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
binding = FragmentNewsreaderDetailBinding.inflate(inflater, container, false);

binding.list.setHasFixedSize(true);
binding.list.setLayoutManager(new LinearLayoutManager(mActivity, RecyclerView.VERTICAL, false));
binding.list.setLayoutManager(new LazyLoadingLinearLayoutManager(mActivity, RecyclerView.VERTICAL, false));
binding.list.setItemAnimator(new DefaultItemAnimator());

ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new NewsReaderItemTouchHelperCallback());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
Expand All @@ -22,6 +21,7 @@
import java.util.ArrayList;
import java.util.List;

import de.luhmer.owncloudnewsreader.LazyLoadingLinearLayoutManager;
import de.luhmer.owncloudnewsreader.NewsReaderListActivity;
import de.luhmer.owncloudnewsreader.SettingsActivity;
import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm;
Expand Down Expand Up @@ -57,7 +57,6 @@ public class NewsListRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.V
private final PostDelayHandler pDelayHandler;
private final FragmentActivity activity;

private int totalItemCount = 0;
private int cachedPages = 1;

private final IPlayPausePodcastClicked playPausePodcastClicked;
Expand All @@ -68,6 +67,8 @@ public class NewsListRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.V
private final int visibleThreshold = 5;
private final SharedPreferences mPrefs;

private LazyLoadingLinearLayoutManager layoutManager = null;

public NewsListRecyclerAdapter(FragmentActivity activity, RecyclerView recyclerView, IPlayPausePodcastClicked playPausePodcastClicked, PostDelayHandler postDelayHandler, SharedPreferences prefs) {
this.activity = activity;
this.playPausePodcastClicked = playPausePodcastClicked;
Expand All @@ -82,7 +83,8 @@ public NewsListRecyclerAdapter(FragmentActivity activity, RecyclerView recyclerV

EventBus.getDefault().register(this);

if (recyclerView.getLayoutManager() instanceof LinearLayoutManager linearLayoutManager) {
if (recyclerView.getLayoutManager() instanceof LazyLoadingLinearLayoutManager lm) {
layoutManager = lm;

recyclerView
.addOnScrollListener(new RecyclerView.OnScrollListener() {
Expand All @@ -91,13 +93,14 @@ public void onScrolled(@NonNull RecyclerView recyclerView,
int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);

int adapterTotalItemCount = linearLayoutManager.getItemCount();
int lastVisibleItem = linearLayoutManager
int adapterItemCount = layoutManager.getItemCount();
int adapterTotalItemCount = layoutManager.getTotalItemCount();
int lastVisibleItem = layoutManager
.findLastVisibleItemPosition();
if (!loading &&
adapterTotalItemCount <= (lastVisibleItem + visibleThreshold) &&
adapterTotalItemCount < totalItemCount &&
adapterTotalItemCount > 0) {
adapterItemCount <= (lastVisibleItem + visibleThreshold) &&
adapterItemCount < adapterTotalItemCount &&
adapterItemCount > 0) {
loading = true;

Log.v(TAG, "start load more task...");
Expand All @@ -122,15 +125,20 @@ public void onScrolled(@NonNull RecyclerView recyclerView,
}

public int getTotalItemCount() {
return totalItemCount;
if (this.layoutManager != null) {
return this.layoutManager.getTotalItemCount();
}
return 0;
}

public int getCachedPages() {
return cachedPages;
}

public void setTotalItemCount(int totalItemCount) {
this.totalItemCount = totalItemCount;
if (this.layoutManager != null) {
this.layoutManager.setTotalItemCount(totalItemCount);
}
}

public void setCachedPages(int cachedPages) {
Expand Down Expand Up @@ -348,7 +356,6 @@ public int getItemViewType(int position) {

@Override
public int getItemCount() {
//return totalItemCount;
return lazyList != null ? lazyList.size() : 0;
}

Expand Down Expand Up @@ -384,7 +391,7 @@ public void updateAdapterData(List<RssItem> rssItems) {
//}
//new ReloadAdapterAsyncTask().execute();

totalItemCount = ((Long) dbConn.getCurrentRssItemViewCount()).intValue();
setTotalItemCount(((Long) dbConn.getCurrentRssItemViewCount()).intValue());

lazyList = rssItems;
notifyDataSetChanged();
Expand Down Expand Up @@ -492,9 +499,9 @@ protected CurrentRssViewDataHolder doInBackground(Void... params) {
@Override
protected void onPostExecute(CurrentRssViewDataHolder holder) {
lazyList = holder.rssItems;
totalItemCount = holder.maxCount.intValue();
setTotalItemCount(holder.maxCount.intValue());
cachedPages = 1;
notifyDataSetChanged();
}
}
}
}

0 comments on commit 09c2e95

Please sign in to comment.