Fixed
Status Update
Comments
d....@gmail.com <d....@gmail.com> #2
Hi,
We have passed this defect on to the development team and will update this issue with more information as it becomes available.
Thanks
We have passed this defect on to the development team and will update this issue with more information as it becomes available.
Thanks
am...@google.com <am...@google.com> #3
Thought I should mention for posterity, a temporary workaround is:
mStaggeredGridLayoutManager.setItemPrefetchEnabled(false);
mStaggeredGridLayoutManager.setItemPrefetchEnabled(false);
an...@gmail.com <an...@gmail.com> #4
[Comment deleted]
am...@google.com <am...@google.com> #5
The bug is reproduced on physical device.
1. RecyclerView with GridLayoutManager (3 column)
2. All items has span = 3 (grid look like simple list)
3. Scrolling up and down is working fine
4. Insert items in the middle of the list (All inserted items has span 3 too)
5. call to notifyDataChanged()
6. Grid is expanded with animation
6. Scrolling up and down is failed.
Problem is found after adding android:animateLayoutChanges="true" into a parent layout.
Bug reproducing is stable.
1. RecyclerView with GridLayoutManager (3 column)
2. All items has span = 3 (grid look like simple list)
3. Scrolling up and down is working fine
4. Insert items in the middle of the list (All inserted items has span 3 too)
5. call to notifyDataChanged()
6. Grid is expanded with animation
6. Scrolling up and down is failed.
Problem is found after adding android:animateLayoutChanges="true" into a parent layout.
Bug reproducing is stable.
d....@gmail.com <d....@gmail.com> #6
Bug reproduced id add "android:animateLayoutChanges="true" to list item layout:
RecycleView
--Root Item view layout is: RelativeLayout
----LinearLayout
--------ViewPager
----------Page0: is <LinearLayout... "android:animateLayoutChanges="true".../> <-- this attr is the bug reason
RecycleView
--Root Item view layout is: RelativeLayout
----LinearLayout
--------ViewPager
----------Page0: is <LinearLayout... "android:animateLayoutChanges="true".../> <-- this attr is the bug reason
d....@gmail.com <d....@gmail.com> #7
You cannot use android:animateLayoutChanges with RecyclerView.
It will try to animate children of the RecyclerView and conflict with the ItemAnimator.
You can still use TransitionManager directly (which that attribute uses) but make sure to exclude RecyclerView's children.
It will try to animate children of the RecyclerView and conflict with the ItemAnimator.
You can still use TransitionManager directly (which that attribute uses) but make sure to exclude RecyclerView's children.
am...@google.com <am...@google.com> #8
Hi, original reporter here. I did not use animateLayoutChanges. See example project in original report.
d....@gmail.com <d....@gmail.com> #9
sorry for the confusion, i've re-opened the ticket.
do...@gmail.com <do...@gmail.com> #10
I face same problem , no solution till now ?
gi...@gmail.com <gi...@gmail.com> #11
it is fixed internally, so in the next release it should be fine.
tw...@gmail.com <tw...@gmail.com> #12
public class MyStaggerLayoutManager extends StaggeredGridLayoutManager {
public MyStaggerLayoutManager(int spanCount, int orientation) {
super(spanCount, orientation);
}
public MyStaggerLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void collectAdjacentPrefetchPositions(int dx, int dy, RecyclerView.State state, LayoutPrefetchRegistry layoutPrefetchRegistry) {
try {
super.collectAdjacentPrefetchPositions(dx, dy, state, layoutPrefetchRegistry);
} catch (IllegalArgumentException e) {
LogUtils.e("catch IllegalArgumentException");
}
}
}
i fixed it by using custom LayoutManager
public MyStaggerLayoutManager(int spanCount, int orientation) {
super(spanCount, orientation);
}
public MyStaggerLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void collectAdjacentPrefetchPositions(int dx, int dy, RecyclerView.State state, LayoutPrefetchRegistry layoutPrefetchRegistry) {
try {
super.collectAdjacentPrefetchPositions(dx, dy, state, layoutPrefetchRegistry);
} catch (IllegalArgumentException e) {
LogUtils.e("catch IllegalArgumentException");
}
}
}
i fixed it by using custom LayoutManager
mr...@gmail.com <mr...@gmail.com> #13
We have the same problem with version 25.1.0 and made the decision to go back to 25.0.1
[Deleted User] <[Deleted User]> #14
Issue has been fixed and released in 25.1.1 support lib
[Deleted User] <[Deleted User]> #15
Version 25.1.1 doesn't seem to solve the issue for me.
My use case could be a little different (maybe easier) from OP's.
1. StaggeredGridLayoutManager with multiple columns (eg. 2)
2. Single item view type - ImageView wrapped in CardView (both layout_width="match_parent", layout_height="wrap_content", ImageView:adjustViewBounds="true")
3. Load 1,000 items, performs image loading with Glide (All images stored on device storage)
4. Flinging the list up and down.
Same exception will be thrown randomly.
PS: As OP suggested, I do StaggeredGridLayoutManager.setItemPrefetchEnabled(false); to prevent the issue from happening.
My use case could be a little different (maybe easier) from OP's.
1. StaggeredGridLayoutManager with multiple columns (eg. 2)
2. Single item view type - ImageView wrapped in CardView (both layout_width="match_parent", layout_height="wrap_content", ImageView:adjustViewBounds="true")
3. Load 1,000 items, performs image loading with Glide (All images stored on device storage)
4. Flinging the list up and down.
Same exception will be thrown randomly.
PS: As OP suggested, I do StaggeredGridLayoutManager.setItemPrefetchEnabled(false); to prevent the issue from happening.
[Deleted User] <[Deleted User]> #16
We still have the problem with 25.1.1 using RecyclerView
java.lang.IllegalArgumentException: Pixel distance must be non-negative
at android.support.v7.widget.GapWorker$LayoutPrefetchRegistryImpl.addPosition(GapWorker.java:110) at android.support.v7.widget.LinearLayoutManager.collectPrefetchPositionsForLayoutState(LinearLayoutManager.java:1202) at android.support.v7.widget.LinearLayoutManager.collectAdjacentPrefetchPositions(LinearLayoutManager.java:1300)
at android.support.v7.widget.GapWorker$LayoutPrefetchRegistryImpl.collectPrefetchPositionsFromView(GapWorker.java:94)
at android.support.v7.widget.GapWorker.buildTaskList(GapWorker.java:213)
at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:343)
at android.support.v7.widget.GapWorker.run(GapWorker.java:370)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
java.lang.IllegalArgumentException: Pixel distance must be non-negative
at android.support.v7.widget.GapWorker$LayoutPrefetchRegistryImpl.addPosition(GapWorker.java:110) at android.support.v7.widget.LinearLayoutManager.collectPrefetchPositionsForLayoutState(LinearLayoutManager.java:1202) at android.support.v7.widget.LinearLayoutManager.collectAdjacentPrefetchPositions(LinearLayoutManager.java:1300)
at android.support.v7.widget.GapWorker$LayoutPrefetchRegistryImpl.collectPrefetchPositionsFromView(GapWorker.java:94)
at android.support.v7.widget.GapWorker.buildTaskList(GapWorker.java:213)
at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:343)
at android.support.v7.widget.GapWorker.run(GapWorker.java:370)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
[Deleted User] <[Deleted User]> #17
Reopening to investigate repros in 25.1.1
Description
Version used: 25.1.0
Theme used: Theme.AppCompat.Light.DarkActionBar
Devices/Android versions reproduced on: every devices I tested on, for example : Sony Xperia Z3 tablet, Samsung Galaxy Tab S2.
It seems related to other issues being reported about fragment replace transactions, but this one does not use the replace method.
Steps to reproduce :
- Add a fragment with a simple transaction :
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
.add(R.id.fragment_container, new TestFragment())
.commit()
- Remove the fragment using a simple remove, and just after start a new activity :
final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (fragment != null) {
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
.remove(fragment)
.commit();
startActivity(new Intent(this, MainActivity.class));
}
- Go back to the old activity
What should happen : the fragment that was added should not be here anymore.
What happens : the fragment is still here. But the thing is it's only some sort of "ghost view" : it's impossible to reach it in debug using the view hierarchy. I even tried to activate the debug option "show layout bounds", which does not shows the bound on the fragment view. The view is not clickable, if I call removeAllViews() on the container it's still here.
Another thing : even with this view still here, if I re-add a fragment it will be added below the "ghost view". Everything works, but the old view is still here.
I attached a sample project to reproduce this issue. The "remove fragment" button is just here to validate the behaviour without starting another activity. You can see the bug using :
- "Add fragment"
- "Remove fragment and start activity"
- Press the back button
The old fragment is still here. If you press the add fragment button, another fragment will appear behing the old fragment, which should not be possible.
If you use the "show layout bounds" option, the bug is really visible :
- Start from scratch (kill the app)
- "Add fragment"
- Enable the "show layout bounds" option.
- "Remove fragment and start activity"
- Press the back button
Here everything seems normal except for the fragment still being here. But if you disable the "show layout bounds" option, the fragment view will stay unchanged, with layout bounds displayed. As if it were a cached view not recognized by the system.
I also attached a screenshot of this behavior. You can see the "show layout bounds" option is disabled, but it still shows on the fragment view.
All this does not happen with support lib 25.0.1.