How to set setStackFromEnd(true); in GridLayoutManager for Recyclerview? - android

I want Grid layout that loads data from last for that I used following code
GridLayoutManager recyclerViewLayoutManager = new GridLayoutManager(getActivity(), 3);
// LinearLayoutManager recyclerViewLayoutManager = new LinearLayoutManager(getActivity());
recyclerViewLayoutManager.setStackFromEnd(true);
lv_explore.setLayoutManager(recyclerViewLayoutManager);
it gives me error like this
java.lang.UnsupportedOperationException: GridLayoutManager does not support stack from end. Consider using reverse layout
at android.support.v7.widget.GridLayoutManager.setStackFromEnd(GridLayoutManager.java:107)
at in.co.ans.jalsounique.FragmentExplore.onCreateView(FragmentExplore.java:86)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2080)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1108)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1290)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1677)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:536)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
when I am using LinearLayoutManager it is working but I need grid view, please advise what should be better way?

It's just what it says: setStackFromEnd is not supported. It's only for lists, not grids.
Consider using reverse layout
So the way you work around this is to call setReverseLayout(true) on your GridLayoutManager.
This means you will need to reverse the entire order of your list. If you are appending items meant to show up at the bottom, you will have to insert them at the beginning instead.

Related

FirestorePagingAdapter crashes when scrolling in version 8.0.1

After updating FirebaseUi from implementation 'com.firebaseui:firebase-ui-firestore:8.0.0' to implementation 'com.firebaseui:firebase-ui-firestore:8.0.1' FirestorePagingAdapter crashes when I scroll the RecyclerView. I think it always crashes at the same position, maybe at this position it loads new items for the first time.
I get the following crashlog:
java.lang.IllegalStateException: The same value, PageKey{StartAfter=1MbZLsOSoWUPAdDnNOGlthxGjDC2 - 02:52:33 - 11.04.2022, EndBefore=null}, was passed as the nextKey in two
sequential Pages loaded from a PagingSource. Re-using load keys in
PagingSource is often an error, and must be explicitly enabled by
overriding PagingSource.keyReuseSupported.
at androidx.paging.PageFetcherSnapshot.doLoad(PageFetcherSnapshot.kt:419)
at androidx.paging.PageFetcherSnapshot.access$doLoad(PageFetcherSnapshot.kt:54)
at androidx.paging.PageFetcherSnapshot$doLoad$1.invokeSuspend(Unknown Source:15)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:233)
at android.app.ActivityThread.main(ActivityThread.java:8063)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978)

How to fix the IndexOutOfBoundsException in RecyclerView

I have a bunch of RecyclerViews throughout my application and have been seeing this exception in Fabric for a while now.
Stacktrace:
Fatal Exception: java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 8(offset:8).state:11 android.support.v7.widget.RecyclerView{3914473e VFED.... ........ 0,0-1080,1509 #7f11017a app:id/chatlist_recycler_view}, adapter:com.myapp.application.a.c#134b699f, layout:android.support.v7.widget.LinearLayoutManager#1449aec, context:com.myapp.application.activities.HomeActivity#1fcf5f5e
at android.support.v7.widget.RecyclerView$Recycler.clear(Unknown Source)
at android.support.v7.widget.GapWorker.add(Unknown Source)
at android.support.v7.widget.GapWorker.add(Unknown Source)
at android.support.v7.widget.GapWorker.remove(Unknown Source)
at android.support.v7.widget.GapWorker.add(Unknown Source)
at android.support.v7.widget.GapWorker.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5951)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
Looking at this updated stacktrace, it seems like it's an issue with my chatlist_recycler_view.
How should I go about debugging this and fixing it? I don't know what is causing the IndexOutOfBoundsException.
Code from the RecyclerView declaration:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/chatlist_recycler_view"
android:background="#android:color/white"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:isScrollContainer="false"/>
</RelativeLayout>
If you guys need any other code please let me know!
Adapter code can be found here:
https://pastebin.com/HzMkCDh5
Well, IndexOutOfBoundsException exception is a common one but in regards to recyclerview here is what you can change to avoid the exception.
1: when you assign the layout adapter just disable predictive animations
mRecyclerView.setLayoutManager(new LinearLayoutManager(this){
#Override
public boolean supportsPredictiveItemAnimations() {
return false;
}
});
2: you can try to clear the existing recycler pool and then notify the data change in case of large data set.
mRecyclerView.getRecycledViewPool().clear();
mAdapter.notifyDataSetChanged();
3: dont't use notifyItem.....() use notifyDataSetChanged() only
4: if getting data from API later you can try swapping the adapter again
swapAdapter(adapter, true)
5: make sure you are not scrolling recyclerview to some position on startup this may also cause the index related issues if data is inconsistent.
Link: source

Vector animation in RecyclerView

Preface
I want to implement a download animation in RecyclerView. In onBindViewHolder and onViewRecycled I subscribe to and unsubscribe from presenter which retrieves the percentage of already downloaded file.
I start animation:
AnimatedVectorDrawableCompat drawable = AnimatedVectorDrawableCompat.create(context, R.drawable.download_animated);
if (drawable != null) {
holder.downloadingIcon.setImageDrawable(drawable);
drawable.start();
}
Problem
I have got onViewRecycled invoked right after the animation is finished with follow stacktrace:
java.lang.RuntimeException
at EventRecyclerViewAdapter.onViewRecycled(EventRecyclerViewAdapter.java:271)
at android.support.v7.widget.RecyclerView$Recycler.dispatchViewRecycled(RecyclerView.java:6064)
at android.support.v7.widget.RecyclerView$Recycler.addViewHolderToRecycledViewPool(RecyclerView.java:5835)
at android.support.v7.widget.RecyclerView$Recycler.recycleViewHolderInternal(RecyclerView.java:5800)
at android.support.v7.widget.RecyclerView.removeAnimatingView(RecyclerView.java:1305)
at android.support.v7.widget.RecyclerView$ItemAnimatorRestoreListener.onAnimationFinished(RecyclerView.java:11775)
at android.support.v7.widget.RecyclerView$ItemAnimator.dispatchAnimationFinished(RecyclerView.java:12275)
at android.support.v7.widget.SimpleItemAnimator.dispatchChangeFinished(SimpleItemAnimator.java:304)
at android.support.v7.widget.DefaultItemAnimator$7.onAnimationEnd(DefaultItemAnimator.java:363)
at android.support.v4.view.ViewPropertyAnimatorCompatJB$1.onAnimationEnd(ViewPropertyAnimatorCompatJB.java:51)
at android.view.ViewPropertyAnimator$AnimatorEventListener.onAnimationEnd(ViewPropertyAnimator.java:1121)
at android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1149)
at android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1309)
at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:146)
at android.animation.AnimationHandler.-wrap2(AnimationHandler.java)
at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:54)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:957)
at android.view.Choreographer.doCallbacks(Choreographer.java:734)
at android.view.Choreographer.doFrame(Choreographer.java:667)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:945)
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:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
Question
Why it behaves like so and how can I fix it?
It turns out, notifyItemChanged caused to recycler previous ViewHolder so onBindViewHolder and onViewRecycled are invoked... but on different instances. Firstly onBindViewHolder is invoked with new ViewHolder instance. Next onViewRecycled is invoked with the old ViewHolder. In my case problem was relying only on one id of the model. It doesn't unambiguously describe Presenter's View I used to notify about updates.

Unsupported operation exception with ArrayAdapter.clear()

So I have an app where I have several drop down spinners several of which I would like to change their options based on the option selected by another spinner. My plan to do this was to put:
product_adapter.clear();
CharSequence[] array=makeArray(urlMaker.getProductid());
for(int i=0;i<array.length;i++){
product_adapter.add(array[i]);
}
product_adapter.notifyDataSetChanged();
within a case of the onItemSelected() method for the spinner that is to dictate the changing of contents of the other spinner. In theory the idea is that I clear the second spinner(product_adapter) then add a new array that is made by makeArray()(which returns an array of CharSequences as specified in the doc) to the spinner's adapter using product_adapter.add(array[i]) then call .notifyDataSetChanged() to formalize it. However, when it hits the first line the app crashes and yields the following stack trace:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.benhouse.weatherview, PID: 25791
java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:638)
at java.util.AbstractList$SimpleListIterator.remove(AbstractList.java:75)
at java.util.AbstractList.removeRange(AbstractList.java:658)
at java.util.AbstractList.clear(AbstractList.java:466)
at android.widget.ArrayAdapter.clear(ArrayAdapter.java:273)
at com.example.benhouse.weatherview.MainActivity$3.onItemSelected(MainActivity.java:102)
at android.widget.AdapterView.fireOnSelected(AdapterView.java:924)
at android.widget.AdapterView.dispatchOnItemSelected(AdapterView.java:913)
at android.widget.AdapterView.-wrap1(AdapterView.java)
at android.widget.AdapterView$SelectionNotifier.run(AdapterView.java:883)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Why am I getting this error and how can I fix it?
Edit: this is how I am intially populating the spinner that I am trying to change:
ArrayAdapter<CharSequence> T_spinnerAdapter = new ArrayAdapter(this, R.layout.support_simple_spinner_dropdown_item, makeArray("GFS"));
Time_spin.setAdapter(T_spinnerAdapter);
Edit 2: So I am a bit of an idiot. I was trying to modify product spinner rather than time spinner(the intended spinner) and the product spinner is initialized from an array in the values.xml. Also probably doesn't like modifying itself within itself. Thanks for the indirect help as it lead me to think and undummy-ify my code.
You are using list collection which doesn't support remove operation.
If you are constructing ArrayAdapter by providing the array of items:
ArrayAdapter (Context context,
int resource,
T[] objects)
Actual implementation creates fixed length list using Arrays.asList()
Fix:
ArrayList list = new ArrayList(Arrays.asList(makeArray("GFS")));
new ArrayAdapter(this, R.layout.support_simple_spinner_dropdown_item, list);
It is a common mistake. Another common mistake is providing an immutable list.

Android RecyclerView Endless Scroll adding item throwing Exception For Android Support Library 24.2.1

I have implemented the Endless scroll with RecyclerView. When user hit the bottom I'm adding null object to display progress in AsyncTask onPreExecute and notify adapter item Inserted. This code I have been using for quiet some time already. Recently I have updated android Support Library From 23.0.3 to 24.2.1. Since then I am getting exception when hit bottom of the list.
Cannot call this method in a scroll callback. Scroll callbacks might be run during a measure & layout pass where you cannot change the RecyclerView data. Any method call that might change the structure of the RecyclerView or the adapter contents should be postponed to the next frame.
java.lang.IllegalStateException:
at android.support.v7.widget.RecyclerView.assertNotInLayoutOrScroll(RecyclerView.java:2403)
at android.support.v7.widget.RecyclerView$RecyclerViewDataObserver.onItemRangeInserted(RecyclerView.java:4634)
at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyItemRangeInserted(RecyclerView.java:10472)
at android.support.v7.widget.RecyclerView$Adapter.notifyItemInserted(RecyclerView.java:6214)
at com.test.film.buzz.BuzzFeedsFragment$5.onPreExecute(BuzzFeedsFragment.java:229)
at com.test.utils.ParallelAsyncTask.executeOnExecutor(ParallelAsyncTask.java:595)
at com.test.utils.ParallelAsyncTask.execute(ParallelAsyncTask.java:543)
at com.test.film.buzz.BuzzFeedsFragment.onLoadMore(BuzzFeedsFragment.java:258)
at com.test.film.buzz.BuzzFeedsFragment$3.onScrolled(BuzzFeedsFragment.java:177)
at android.support.v7.widget.RecyclerView.dispatchOnScrolled(RecyclerView.java:4305)
at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:4463)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
at android.view.Choreographer.doFrame(Choreographer.java:616)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
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:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

Categories

Resources