Android Fragments in Recyclerview ViewHolder - android

I need to place a lot of different views where some of them need to be fragments in a Recyclerview. For example a MapFragment or a YoutubePlayerFragment.
Is there a good way to place them into viewholders for the recycler view so that the references are not leaking or should I simply not use a Recyclerview therefore? (the list can get very long, it's a message timeline in a messenger)
I'm using the MVP pattern so every the Fragments will have presenters that have to get recycled somehow aswell but that's a minor problem. The Bigger problem is to handle the lifecycle events of the fragments in the viewholders.

Related

LiveData, View Models with Heterogeneous Recycler View

I am working on an android application which has a recycler view with multiple view types. It was originally a MVP based app, which I am trying to convert to MVVM based architecture with LiveData and ViewModels. I have a home screen with a list of different types of views inside a recycler view. Every view has its own ViewModel and corresponding Model, resulting it with a home screen having recycler view as a collection of different view models.
This is my first implementation of LiveData, so facing some issues with design. I see some options here -
I create a parent HomeViewModel for my home activity which holds a LiveData object, consisting a list of different child ViewModels (representing different view types), making activity to its life cycle owner. Then I update each view(elements of recycler view) from one observer to that LiveData object.
I create individual LiveData objects for every child view/view models and make home activity as life cycle owner for each model/live data and update their views independently from activity with respective observers.
I create individual LiveData objects for every child view/view models and make respective view holder classes as their lifecycle owners and update individual views in respective holder classes.
Please help me suggesting the better way to deal with this or if there is any other approach other than the specified ones.
Thanks
I agreed to create a parent viewmodel such as "HomeViewModel", but I think the creation of viewmodel for each view type seems a little over-engineering, because every time you need to create a new view type, you need to create a new ViewModel, and I dont see any requirement for the view in recyclerview to have a dedicated viewmodel. In my perspective, the best approach is only have 1 viewmodel. Then I suggest you to implement adapter factory pattern for your recyclerview like in this article https://proandroiddev.com/writing-better-adapters-1b09758407d2 . If you have adapter factory pattern like that, you can generalize your recyclerview data, for example you can call it "Visitable" like the post above. Then, your viewmodel can hold just 1 livedata of visitable list, which observed by the fragment/activity.

ViewPager or RecyclerView with fragments?

I am a little bit confused on how should I approach this particular case of doing some swipes between fragments.
So yea, I asked ViewPager or RecyclerView, because these 2 are my only options, if anyone can come up with a better idea, it is really welcome.
The flow is the following, I have a Main Timeline(ListView), each item of it opens a fragment with details about it. What I would actually want to do is to swipe between these full screen fragments without going back to MTL and open another item of the list.
You would ask me what I tried, well:
RecyclerView - HORIZONTALLY oriented as a root of the fragment, and each item of this RV had the details of each event. The problem with this is that it gets really buggy because I have a huge logic inside each item(like, another RV - horizontally , a PagerView also horizontally to swipe between images (or a youtube frame that is being played if is the case. Plus a lot of other stuff in this, so the logic of parent RV inside the onBindViewHolder() is really tricky.
Would be better to use a PagerView with fragments(since I have the DetailsFragment kind of ready) ? The problem here is that I need a certain number of swipes, right ?
Go with viewpager.
Because creating fragments inside recyclerview causes recyclerview performs to slow down.Also to create fragments in onBindViewHolder() dynamically every time you need different unique id of frame layout to load which will be tough to generate.
For more information on why recycler view is bad idea to load fragments check this.
Fragment replacing in RecyclerView item
Also try to use the ViewPager with an implementation of FragmentStatePagerAdapter. The adapter will optimize the memory usage by destroying fragments that are not visible at a given moment.
Check the documentation for details and code sample.
https://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html

Adding Fragment as a List Item

I am having a situation in which as a List Item I want to inflate a Fragment, but It seems like a bad approach. As Fragments are processed/managed by Activity's FragmentManager or by child FragmentManager and list item views are by ListView & ListAdapter.
Any comments and research regarding this would be highly appreciated.
Thanks
Here are my views and questions in mind on your problem.
You want to use ListView with fragments, since you already have a fragment which does that job and you dont want code to become redundant.
Though you can definitely use fragment, but i suppose its not the best practice. Fragments have their own life cycle and you are not going to use fragment life cycle methods (I suppose). Thus semantically it would not fit into this usecase.
And also your adapter will always be dependent on activity to retrieve fragments. (could there be any problems with orientation change again?)
List items and adapters are finetuned to work really well with scrolling really long lists. While the list view items get recycled when using view holder pattern, while scrolling, does any of fragment lifecycle methods come in between? would that cause performance impact. (I suppose yes. Havent tested it out yet)
You can instead have your view code in different layout file and include this layout in both fragment and also list adapter.
<include layout="#layout/YOUR_COMMON_VIEW_CODE"/>
and have utility class which takes the context and this layout container. Have all the functionality exposed inside that utility class.
You can't use fragment as list item views because the API doesn't allow you - View and Fragment aren't even related so there's no way you can use it like that. Make custom views and use adapter getViewTypeCount and getView to use different list item behavior.
Fragment are managed by Activity's FragmentManager or by other Fragments child FragmentManager; while list item views are managed by ListView & ListAdapter. You can use ListViews in Fragments, but not the other way around.
I googled and got this.

What is the convention for using Fragments and views in a ViewPager?

I have a ViewPager and I want to use implement fragments for it, but I don't know what is the best way to do it, should I have multiple instances of a fragment with different views or should I have multiple fragments with their own views?
Edit:
What should I do when I have different layouts, exactly?
Check out the code on my git.
This includes infinite scrolling along with header that moves along scrolling and clickable pagerview pager with fragments with listview
You just have to replace the fragmented layout to however you want.
Im using this for my own sns and its very speedy. Make sure you have asynctask for any heavy loading

ViewPager for displaying 5 Views at the same time or other options in Android?

I'm currently using a ViewPager with a pageWidth of 0.2 to display 5 Views at the same time. This logically requires an offscreen-limit from 7, to have a smooth transition between the views.
In the beginning I used a FragmentStatePagerAdapter but I was worried about the memory-consumption and the performance. This was the reason why I now only use a PagerAdapter to display my views.
What I want (and what I have):
<<-- View | View View View View View | View -->>
Is there any other approach in android to handle this? I thought about using a LinearLayout with a ScrollView but I need to "stick" to the Views after swiping. And I really like the custom-page indicators of the view.
Furthermore: Shall I save the views (of the elements) in my objects or should I recreate them after every call (and yes, I'm removing them in destroyItem) ?
Another question: Was it the right decision to switch from FragmentStatePageAdapter to a PagerAdapter?
From the document, http://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html
Implementation of PagerAdapter that uses a Fragment to manage each page. This class also handles saving and restoring of fragment's state.
This version of the pager is more useful when there are a large number of pages, working more like a list view. When pages are not visible to the user, their entire fragment may be destroyed, only keeping the saved state of that fragment. This allows the pager to hold on to much less memory associated with each visited page as compared to FragmentPagerAdapter at the cost of potentially more overhead when switching between pages.
Therefore, if you have a lot of pages, using FragementStatePageAdapter is better. FragementStatePageAdapter is more efficient on memory management.
But if you want cache 2 pages outside screen, no matter FragmentStatePageAdapter and PageAdapter, you have to cache them by yourself. Use SimpleOnPageChangeListener to catch page change event, then do some initialization for next page.
After removing the views from the container in destroyItem() keep them in an ArrayList. During instantiateItem(), first check if you have unused views in your arraylist, if so, use that one. If not, inflate one.
The garbage collector may or may not have collected the view, so you need to do a pre-check before you can use it.

Categories

Resources