I have implemented ViewPager and number of Fragment as child, here every child override own onAttach, onCreateView, onViewCreated and setUserVisibleHint.
In my app navigation behaviour is random, it not be in sequence every time. Since page viewer perform caching to load extra child, and this is what my problem is. I am not sure exactly when I should initialise/release member of child class.
Required suggestion from you guys, will it be preferable to use PageViwer in this case or I should go with traditional activity flow for each of component.
ViewPager is typically used for move efficient horizontal item to item navigation. Typical use cases would be
Swiping through the related items (e.g. emails, images, songs of an album, etc.)
Swiping between the tabs
Swiping back-and-forth in a wizard-like activity
For more details you can read a section about Swipe Views Android Design pattern.
Regarding the lifecycle, it basically uses the same lifecycle as any other Fragment. The only difference is, that lifecycle methods can be called a bit later or earlier than you expect, because of fragment's caching ViewPager implements.
I am not sure exactly when I should initialise/release member of child class.
You should basically rely on two methods: onStart() and onStop(). In onStart() you create class members and initialize everything you want to. In onStop() method you should deinitialize everything and remove all listeners you set in onStart().
Method setUserVisibleHint() is used independently of onStart() or onStop(). You shoud better not initialize or destroy anything in there. You must not consider it to the a lifecycle method, because it's not. It's there just to give you a hint, that your fragment is visible to the user. Here you can start or stop animation, or request data update or perform similar tasks. This is the only purpose of this method.
Required suggestion from you guys, will it be preferable to use
PageViwer in this case or I should go with traditional activity flow
for each of component.
If your activity fits into one of the points mentioned about, I would suggest you to use ViewPager. Otherwise you might consider other options.
Update: Most likely you won't override onCreate() and onDestroy() lifecycle methods of a fragment very often. You will use onCreateView() and onDestroyView() methods instead. There you can implement so called static initialization, the initialization which doesn't change while a fragment is still alive. This is layout initialization and similar tasks.
ViewPager Usages
Screen slides are transitions between one entire screen to another and are common with UIs like setup wizards or slideshows.
If you have good knowledge in Fragment than ViewPager is right component for implements.
Because viewpager provide a place which you can add fragment runtime.
For eg.
If you want to use TabBar in your project than viewpager is right component for using. Because it's provide a place which you can add Fragment runtime. Tabbar is common in android application. It's provide lot of functionality inbuild we can use to add fragment runtime.
Facebook app using ViewPager to manage tab. Viewpager provide smoothness of your application.
You can Download example from this url and check your requirement fulfill or not
You can download the Example here
ViewPager
It is an widget
Allows the user to swipe left or right to see an entirely new screen.
Easy to show the user multiple tabs
Dynamically add and remove pages (or tabs) at anytime.
To Read More: http://architects.dzone.com/articles/android-tutorial-using
Related
The ViewPager object is implemented such that the next screen is already created in memory before the user swipes to it. ViewPager has a method setOffscreenPageLimit(n) in which you can set the number of ViewPager fragments that are created in advance, but n=0 is not allowed. The reason behind that is to garantee a 'smooth user experience'. In my case however then content of page n+1 is determined by what the user has done on page n. For instance if the user has clicked on a checkbox on page n, it can happen that some widget should not be shown on page n+1. My question is: how can I ensure that page n+1 is recreated? If that goes at the cost of a 'smooth user experience' so be it. I am able to intercept the swipe event in:
pager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener()
In that method I can call a refresh() method of the current fragment. The problem is: what do I do in that refresh() method or is this the wrong approach? The user interface I want to recreate is in the onCreate method, a callback method. Or can't this work and do I need to replace the Fragment (n+1) in memory with a new one and if so, how do I do that?
Any help would be appreciated.
Trying to replace the fragment associated with a page in a ViewPager is going to be the responsibility of your fragment-based PagerAdapter. I am not aware of an easy way to accomplish that with FragmentPagerAdapter or FragmentStatePagerAdapter. My ArrayPagerAdapter can handle it better, though I don't offer a direct replace() operation.
In your case, the better solution is to adjust the fragment that you have, rather than to replace the fragment outright. In theory, this should be possible for just about any degree of change. In practice, there is probably a level of complexity after which trying to replace the fragment would be simpler than trying to have a mashup of all possible fragments.
Note that nested fragments might be another option, where the N+1th page was a placeholder and ran a FragmentTransaction to populate itself when shown. Nested fragments are tricky and quirky.
With regards to the "holes", View.INVISIBLE indicates that you want the widget to continue taking up space (e.g., so stuff after it in a LinearLayout does not move), but do not draw the pixels. View.GONE means that the View is totally ignored for layout purposes, though it is still in the hierarchy and so can be easily toggled back to View.VISIBLE if needed. Another possibility would be to remove the View entirely from the parent container, though this should have no visible change when compared with View.GONE.
Let's say I have an Activity with a certain content. Now I need to create a new screen with tabs, so that the content of this activity will become the content of one of those tabs. I know I can do tabs with ViewPagerIndicator, for example. But, in order to do that, I need the screens to be implemented as Fragments. The problem is that the current implementation relies heavily on the Activity hierarchy (lots of calls to methods on the superclass, etc). So, I cannot simply make the current class extend Fragment. What other options do I have in this case?
Now I need to create a new screen with tabs, so that the content of this activity will become the content of one of those tabs
Having activities be the contents of tabs has been deprecated as a technique for nearly three years.
The problem is that the current implementation relies heavily on the Activity hierarchy (lots of calls to methods on the superclass, etc). So, I cannot simply make the current class extend Fragment.
Replace most of those "calls to methods on the superclass" to use getActivity(). as a prefix, where relevant.
What other options do I have in this case?
You could remove the activities entirely and rewrite your UI as custom views. This would be more work than converting them to fragments.
Or, you can just not do tabs.
So, I cannot simply make the current class extend Fragment.
That sounds like you have a huge Software architecture problem. In this case you may consider a complete rewrite (or more a copy & paste rewrite)
Normally it should be really straight forward to "convert" a Activity to a Fragment.
Fragment has nearly the same lifecycle callbacks:
Activity.onCreate() ---> Fragment.onCreateView() etc.
You can also access the parent Activity of the Fragment by calling Fragment.getActivity().
I don't know your code, but it should be definitely possible to "convert" Activities to Fragments.
You may split your activities code in own classes and inject them to the Fragment.
There is not really a alternative I could recommend you!
If you want tabs, use a ViewPager with Fragments. DO NOT USE OLD DEPRECATED STUFF like TabActivity
I have a question about whether to use View or Fragment with ViewPager.
Background:
I have an Activity A that contains a ListView. Each ListView item opens Activity B. Activity B shows different content depending on which ListView item is tapped in Activity A.
Activity B's content is shown inside a ListView.
Question:
Now, instead of going back and forth between Activity A and B to switch contents, I have a requirement to implement horizontal view swiping to switch contents all within Activity B.
One solution I found (tried it and it works) is to create many instances of Activity B's ListView and use it with ViewPager + PagerAdapter.
Another potential solution found on the doc (haven't tried it) is to bring that ListView into a Fragment, create many instances of the fragment and use it with ViewPager + FragmentPagerAdapter or FragmentStatePagerAdapter.
My question is, what's the benefit of using each approach? Should I go through all the trouble of bringing the ListView into Fragment or just simply use ListView with ViewPager?
Thanks
A Fragment is a useful approach, I think, when you want to tie some UI business logic to a particular View (or group of). As you know, that individual Fragment has its own lifecycle callbacks and so forth, just as an Activity would.
Rather than having a single Activity host many ListViews through a single PagerAdapter, it may be cleaner to use the Fragment approach because the Fragment only needs to deal with the logic behind driving a single ListView.
This is a very similar situation to one I've just been facing. I'm showing various vertically scrolling forms (consisting of lots of input fields) within a ViewPager. In my case I have gone for the Fragment approach because in my case, it's possible that the ViewPager will actually need to display a completely different kind of view on certain pages. For example, on the first few pages, user input forms might be displayed. But on the final page, a graph will be displayed. A whole separate set of logic is required to drive that graph. To drive those input forms and one graph from a single Activity would get a bit messy, and I would probably need to contain the business logic in several delegate classes or something. So for me, Fragments were the obvious choice in the end. I have my InputFormFragment and a GraphFragment, and they each contain only the applicable logic for the Views that they supply.
Another thing to consider is that in the near future you too may want to display a different kind of View in your ViewPager. Or, you might want to have another UI layout altogether, perhaps one that doesn't use the ViewPager but displays them all side-to-side (e.g. a layout used on a large tablet in landscape mode). With Fragments, things are just far more modular and you could factor the code to do this quicker. If on the other hand you achieved your objective by using a single Activity that contains a simple PagerAdapter and all the logic for the ListViews within, you might find it takes more work in the future to support new kinds of Views or special tablet layouts.
One thing I will say is having implemented Fragments in a ViewPager myself through FragmentPagerAdapter and FragmentStatePagerAdapter, things can get a bit awkward if you have any special requirements; managing Fragments can be tricky sometimes. For example, for my UI I needed to be able to programmatically add and remove the ViewPager containing the Fragments. I also needed to ensure that the adapter in use didn't destroy Fragments once they had been shown, because I needed to collect data from all Fragments simultaneously at a certain point. Furthermore, I had to extend and modify FragmentPagerAdatper to make sure that the Fragments go through their onDestroy() properly and are removed from the FragmentManager when the ViewPager was removed.
Fragments enable a very modular way of constructing UIs for various screen sizes and orientations, and are excellent in how they allow you to encapsulate business logic and lifecycles for individual UI elements. However if your scenario really is just as simple as several ListViews in a ViewPager and you know that you will never need the modularity, then the overhead of Fragments could be an overkill.
Having searched regarding this issue beforehand, I can find many discussions regarding dynamically adding and removing selected Fragments from a ViewPager. What I'm actually concerned about here however is how I can programmatically remove an entire ViewPager 'cleanly' from its containing ViewGroup, when that ViewPager has been used to display Fragments via a FragmentPagerAdapter, and ensure that the contained Fragments are destroyed properly.
To expand on the question a bit more, I have a landscape two-pane layout where a selection is made from a list within a Fragment on the left-hand-side, and chosen content is then placed on the right within a FrameLayout. The key thing is that the content may or may not be paginated. Therefore, the content must either be displayed in a ViewPager format, or if it is not paginated then it shall be represented by a single Fragment directly.
To show a single Fragment, I simply perform a FragmentTransaction as you normally would in order to place the Fragment into the FrameLayout container. If on the other hand it's paginated content to be shown, then instead I create a ViewPager and add it as a child of the FrameLayout.
When I need to change the content, then if the previous content was a stand-alone Fragment then I can simply remove it via FragmentTransaction .remove(). When I do this, the Fragment goes through the onPause() ... onDestroy() cycle as expected. If the previous content was a ViewPager then I remove it from the FrameLayout using .removeAllViews(). Here I come to the problem: I don't see any of the onPause() ... onDestroy() methods being called in any of the Fragments that were held within that ViewPager via the FragmentPagerAdapter.
From a user point of view, the application works fine. After several rounds of ViewPager being removed, I can see the GC reclaiming memory. However, I don't like the fact that those Fragments' end of life methods aren't called as I can't do any cleanup within them, and it just doesn't seem 'right'.
Is there a method I can hook into in order to remove the ViewPager's Fragments when the ViewPager is detached from its parent, perhaps? In other words, when I know that the ViewGroup is no longer in used, I would perform FragmentTransactions somewhere (perhaps in the FragmentPagerAdapter) to remove those Fragments.
Alternatively, I realise that I could just keep the ViewPager on the right permanently, and dynamically swap the Fragments within it. Of course it simply would not matter that at certain times it would only hold one page. If this would be a better way to go then I shall refactor my code to do this, but I would appreciate opinions.
However, I don't like the fact that those Fragments' end of life methods aren't called as I can't do any cleanup within them, and it just doesn't seem 'right'.
They should get cleaned up when the activity is destroyed, if that is not too late for you (e.g., heap issues).
In other words, when I know that the ViewGroup is no longer in used, I would perform FragmentTransactions somewhere (perhaps in the FragmentPagerAdapter) to remove those Fragments.
You did not execute the transactions to put the fragments there. Hence, you cannot readily execute the transactions to remove the fragments. If you switch to FragmentStatePagerAdapter, and call setAdapter(null), it should cause all existing fragments in the pager to be destroyed, by my reading of the source code. FragmentPagerAdapter never uses remove(), but FragmentStatePagerAdapter does, from its destroyItem() method, and all extant fragments are destroyed via destroyItem() when a new adapter (or null) is supplied to setAdapter().
I am trying to make a sudoku application. It's a fragment based design, in which a fragment hosts a custom view which is a board. I am trying to learn how to build an effective communication within FragmentActivity, Fragment and View
Although a view is created using the FragmentActivity context and I can catch a reference to that context within the current view and then call methods inside FragmentActivity I don't want to tie views so directly to a fragment activity. Instead I want to tie the view to use methods inside a fragment. How can i do that, I can I capture a reference to a fragment and call methods inside that fragment from a view?
First of all, I strongly recommend that you read through the documentation on Fragments, as you clearly don't understand the whole concept/purpose of using Fragments in the first place (which is OK, because they are confusing the first time you learn them :P).
A lot of your question doesn't make very much sense to me, because I'm not sure what the View you are speaking of refers to. What I can tell you is that Fragments have their own UI/layout, along with their own separate lifecycle. So it sounds like you don't want your FragmentActivity to interact with the Fragments layouts/methods at all... instead, you should implement the UI's behavior and layout inside of the Fragment itself. That is, the Fragment will be in charge of updating the UI, receiving click/touch events, displaying information on the screen etc. The FragmentActivity will simply hold a reference to the current Fragment(s), and will be in charge of displaying/swapping in and out new Fragments as necessary (via the activity's FragmentManager).
Hope that answers the question somewhat... read through the documentation a couple times, it sounds like you are just misunderstanding the theory/purpose behind Fragments.