-
Notifications
You must be signed in to change notification settings - Fork 11
PagingWithNetworkSample - PagedList RecyclerView scroll bug #548
Comments
Same issue is here
|
I have solved my issue like this
|
Well, your solution is effective, but if I removed the Header in List(just PagedList+Footer),the list still automatically scrolled to the end of the loaded page when I refresh recyclerView successfully. My answer is that add an empty layout header on top of RecyclerView which can't be seen by user(for example, layout_height = 0.1dp) as static placeholder. the issue was solved but it's not elegant solution in my opinion. 😢 |
@qingmei2 |
I am sorry for I did not explain clearly.
exactly, no, I implement a multi type PagedList with Header and Footer. finally I was able to build it according to this post⬇️: Android RecyclerView + Paging Library 添加头部刷新会自动滚动的问题分析及解决 Briefly summarize,the post author create a proxy class: class AdapterDataObserverProxy extends RecyclerView.AdapterDataObserver {
RecyclerView.AdapterDataObserver adapterDataObserver;
int headerCount;
public ArticleDataObserver(RecyclerView.AdapterDataObserver adapterDataObserver, int headerCount) {
this.adapterDataObserver = adapterDataObserver;
this.headerCount = headerCount;
}
@Override
public void onChanged() {
adapterDataObserver.onChanged();
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount) {
adapterDataObserver.onItemRangeChanged(positionStart + headerCount, itemCount);
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {
adapterDataObserver.onItemRangeChanged(positionStart + headerCount, itemCount, payload);
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
adapterDataObserver.onItemRangeInserted(positionStart + headerCount, itemCount);
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
adapterDataObserver.onItemRangeRemoved(positionStart + headerCount, itemCount);
}
@Override
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
super.onItemRangeMoved(fromPosition + headerCount, toPosition + headerCount, itemCount);
}
} and override the override fun registerAdapterDataObserver(observer: RecyclerView.AdapterDataObserver) {
super.registerAdapterDataObserver(AdapterDataObserverProxy(observer, 1)) // 1 -> headerCount
} This code part just explain how to set up Header, but same to Footer. Emm....in principle, this approach is no different from yours. the difference is just where we deceive the RecyclerView to handle the update position range.😂 the demo code at here(Both header and footer). |
Hey guys @qingmei2 @onlymash , I am still having this problem too and I don't know how to solve it. I fix one part but then I break another. I have this adapter with this three ViewHolders:
If I add this lines to the adapter (the fix from qingmei2), the problem is fixed but I have a problem with the swipe refresh:
When I swipe to refresh I get this:
How can I solve this? |
hi, @lucandr :) I have read your code but not know clearly where was error... I found the codes' logic is managing a dynamic row as Footer in the list, have you try make this row as static instead of dynamic managing this row added or removed( just control it Visibility or Gone)? Maybe it is not best solution but I think it simplify the logic at least, and I always know the number of item's count: override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is HeaderViewHolder -> holder.bindsHeader() // header
is FooterViewHolder -> holder.bindsFooter() // footer
is StudentViewHolder -> holder.bindTo(getStudentItem(position)) // main list
}
}
private fun getStudentItem(position: Int): Student? {
return getItem(position - 1) // position = 1 means fetch first(position 0) student in pagedList.
}
override fun getItemCount(): Int {
return super.getItemCount() + 2 // +2 means static header and static footer
} see detail here :) "just control it Visibility or Gone" maybe like this: class Footer: RecyclerView.ViewHolder {
// .....
fun binds(position:Int){
rootView.visibility = if(position == 0) View.VISIBLE else View.GONE
}
} Can this solve your issue? or you can try to describe your problem in detail. :) |
I got this issue too and is there any perfect way to fix it? Is it a big bug to so hard to do? |
Is there anyone can chekcout this repository?I try to fix it but i faild and it took more than 10 hours. |
自动滚动的原因大概明白了。在 progressbar 也就是 footer 被移除前,添加了新的item,recyclerview 会尽可能的维持当前可见的progressbar 继续可见,于是瞬间在 footer前面插入大量的item就会造成自动滚动的效果 |
假如有一个header,便能避免自动滚动,因为在header 和 footer 之间插入新的item 时 recyclerview 会优先保证 header 的可见性,从而避免了自动滚动 |
所以解决办法是先让footer消失再向适配器发射数据 |
@onlymash 太感谢了。完美!!!! //callback.onResult(this, null, 2) move it after code of `networkState changed`
networkState.postValue(NetworkState.LOADED)
initialLoad.postValue(NetworkState.LOADED)
callback.onResult(this, null, 2) |
I think I had the same issue and solved it by removing all "networkState.postValue()" calls from the "loadInitial()" function. Additionally this gets rid of the overlaying loading indicators. |
I believe this issue is obsolete now with the sample being rewritten in paging3 and having loadState as a built-in concept in the library. If there are any questions about that, happy to answer, but closing this out. |
Hi guys, I found a problem on the scroll when I don't let the data load and go to another activity and then go back to the previous one.
You can see this on this video.
Video showing the problem
Can u help me to solve this?
Cheers!
The text was updated successfully, but these errors were encountered: