savepopulation savepopulation - 2 months ago 42
Android Question

RecyclerView + HidingScrollListener + Load More

I use hiding scroll listener with

recyclerview
. When I scroll down
recyclerview
and release scroll, if loads more and add new contents to adapter with item range inserted my rows previously added or new added not responding to click. But when I scroll again a little bit all my click tries works.

Here is my
HidingScrollListener
:

public abstract class HidingScrollListener extends RecyclerView.OnScrollListener {

private static final float HIDE_THRESHOLD = 10;
private static final float SHOW_THRESHOLD = 70;

private int mToolbarOffset = 0;
private boolean mControlsVisible = true;
private int mToolbarHeight;
private int mTotalScrolledDistance;
private int previousTotal = 0;
private boolean loading = true;
private int visibleThreshold = 4;
int firstVisibleItem, visibleItemCount, totalItemCount;
private LinearLayoutManager layoutManager;

public HidingScrollListener(Context context, LinearLayoutManager layoutManager) {
mToolbarHeight = Tools.getFooterHeight(context);
this.layoutManager = layoutManager;
}

@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);

if (newState == RecyclerView.SCROLL_STATE_IDLE) {
if (mTotalScrolledDistance < mToolbarHeight) {
setVisible();
}
else {
if (mControlsVisible) {
if (mToolbarOffset > HIDE_THRESHOLD) {
setInvisible();
}
else {
setVisible();
}
}
else {
if ((mToolbarHeight - mToolbarOffset) > SHOW_THRESHOLD) {
setVisible();
}
else {
setInvisible();
}
}
}
}

}

@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);

clipToolbarOffset();
onMoved(mToolbarOffset);

if ((mToolbarOffset < mToolbarHeight && dy > 0) || (mToolbarOffset > 0 && dy < 0)) {
mToolbarOffset += dy;
}
if (mTotalScrolledDistance < 0) {
mTotalScrolledDistance = 0;
}
else {
mTotalScrolledDistance += dy;
}
// for load more
visibleItemCount = recyclerView.getChildCount();
totalItemCount = layoutManager.getItemCount();
firstVisibleItem = layoutManager.findFirstVisibleItemPosition();

if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
// End has been reached
// Do something

loading = true;
onLoadMore();
}
}

private void clipToolbarOffset() {
if (mToolbarOffset > mToolbarHeight) {
mToolbarOffset = mToolbarHeight;
}
else if (mToolbarOffset < 0) {
mToolbarOffset = 0;
}
}

private void setVisible() {
if (mToolbarOffset > 0) {
onShow();
mToolbarOffset = 0;
}
mControlsVisible = true;
}

private void setInvisible() {
if (mToolbarOffset < mToolbarHeight) {
onHide();
mToolbarOffset = mToolbarHeight;
}
mControlsVisible = false;
}

public abstract void onMoved(int distance);

public abstract void onShow();

public abstract void onHide();

public abstract void onLoadMore();
}


and
onLoadMore()
:

mAdapter.notifyItemRangeInserted(size, data.size());


I cannot figure out why this's happening. It's very strange. Thanks.

Answer

The point is i notify wrong range when i try to use notifyItemRangeChanged() method of my RecyclerViewAdapter.

This causes to block Ui Thread so i cannot get any action onClick before i interrupt the ui thread.

When i set a valid item range for notify adapter, this got fixed.

I hope my answer'll help someone.

Correct call is below:

mAdapter.notifyItemRangeInserted(size+1, data.size());
Comments