Fragment Series Articles:
1, Fragment full analytical series (a): Those who have stepped on the pit
2, Fragment full analytical series (ii): Correct use of posture
3, fragment of my solution: fragmentation
This article mainly introduces some fragment use techniques.
Fragment is a silky design for your app, and if your app wants to improve performance on a current basis and consumes less memory , the same interface activity consumes more memory than fragment. Response speed fragment than activty in the low-end mobile phone a lot faster, even can reach several times! Your app can save you a lot of time and effort if you have a platform such as a tablet that you're porting today or later.
A humble catalogue
1. Some suggestions for use
2. Add (), show (), Hide (), replace ()
3, about Fragmentmanager you need to know
4, the use of viewpager+fragment precautions
5, fragment business, you may not know the pit
6, is the use of single activity+ multi-fragment architecture, or multi-module activity+ multi-fragment architecture?
As a stable app, from the backstage and back to the front desk, you will be able to recover from any situation before leaving the page, and ensure the integrity of the data.
If you have not read the first article of this series, in order to facilitate the introduction of the following article, first specify a "term", the Android app has a special case, that is, when the app is running in the background, the system resources are tense when the resources of the app are all recycled (kill the app process), When you return the app from the background to the foreground, the app restarts. This is referred to as the following: "Memory restart".
Some suggestions for use
1, the fragment transmission of data, the proposed use setArguments(Bundle args)
, and then onCreate
use getArguments()
out in, in the "Memory restart" before the system will help you save data, will not cause data loss. is consistent with the intent principle of activity.
2. Using the newInstance(参数)
create fragment object, the advantage is that the caller only needs the data that the relationship passes, without worrying about what key to pass the data.
3. If you need to use the host activity object in fragment, it is recommended that you define an activity global variable in your base class fragment, and initialize it in onAttach
. The code for Getactivity () in Oncreateview () is likely to be dangerous because of the "getactivity () Null pointer" section of the first article.
protected Activity mActivity;@Overridepublic void onAttach(Activity activity) { super.onAttach(activity); this.mActivity = activity;}
Add (), show (), Hide (), replace () The little Thing
1. Difference
show()
, the hide()
final is to let fragment's view setVisibility
(True or false), does not invoke the life cycle;
replace()
Will destroy the view, that is, call Ondestoryview, Oncreateview and so on a series of life cycle;
add()
and replace()
do not mix and match in the same class of Fragmentmanager.
2. Usage Scenarios
If you have a very high probability of using the current fragment again, it is recommended to use, show()
hide()
which can improve performance.
During my use of the fragment process, most of the cases are used, show()
hide()
rather than replace()
.
3, onhiddenchanged of the callback time
When using the add()
+ show(),hide()
jump new fragment, the old fragment callback onHiddenChanged()
does not callback the onStop()
life cycle method, and the new fragment is not destroyed at the time of creation, onHiddenChanged()
this should be remembered.
4, fragment overlap problem
The problem with using this show()
hide()
is that if you do not do any processing, the fragment will overlap after the "Memory reboot";
Some small partners may be to avoid fragment overlap problem, and choose replace()
to use, but use, show()
when the hide()
overlap problem is completely can be resolved, there are two ways to solve, the details of the previous article.
You need to know about Fragmentmanager.
1. Fragmentmanager Stack View
(1) Each fragment and host activity (inherited from Fragmentactivity) will initialize a Fragmentmanager object when it is created, and the key to handling the fragment nesting problem is to sort out the stack views of these different classes.
A brief diagram is given below :
Stack diagram. png
(2) for the host activity, getSupportFragmentManager()
obtain the Fragmentactivity Fragmentmanager object;
For fragment, it is the getFragmentManager()
Fragmentmanager object that gets the parent fragment (or fragmentactivity if not), and the getChildFragmentManager()
Fragmentmanager object that gets its own.
2, restore fragment (while preventing fragment overlap), choose getfragments () or Findfragmentbytag ()
(1) SelectgetFragments()
For multiple fragment within an activity, if the fragment relationship is "process", such as sign-in/login/forgot password-fill information, go to the home activity. In this case, using getfragments () is most appropriate in your activity (the better way is in all of your "process" base activity), write the following code:
@OverrideProtectedvoidOnCreate (@Nullable Bundle savedinstancestate) {super.oncreate (savedinstancestate);if (savedinstancestate! =NULL) {list<fragment> fragments = Getsupportfragmentmanager (). getfragments ();if (fragments! = null && fragments.size () > 0) {Boolean showflag = FALSE; Fragmenttransaction ft = Getsupportfragmentmanager (). BeginTransaction (); for (int i = fragments.size ()-1; i >= 0; i--) {Fragment Fragment = Fragments. Get (i); if (fragment! = null) {if (! Showflag) {ft.show (Fragments.true;} else {ft.hide (fragments.
The way to restore fragment, not only improve performance, but also avoid overlapping fragment, the most important thing, you do not have a relationship in the activity container is what fragment.
(2) Select findFragmentByTag()
Recovery
If your activity's fragments, not "process" relationship, but "sibling" relationship, such as the main interface of QQ, "message", "Contact", "dynamic", these 3 fragment belong to the sibling relationship, with the above code is not appropriate, recovery will always restore the last one, That is, "dynamic fragment".
The correct way is to onSaveInstanceState()
save the current fragment tag or subscript, in the onCreate()
recovery, hide the other 2 fragment.
@OverrideProtectedvoidOnCreate(Bundle savedinstancestate) {Super.oncreate (savedinstancestate); Setcontentview (r.layout.activity); Msgfragment msgfragment; Contactfragment contactfragment; Mefragment mefragment;if (savedinstancestate! =NULL) {"Memory Restart" is called Msgfragment = Getsupportfragmentmanager (). Findfragmentbytag (Msgfragment.getclass (). GetName); Contactfragment = Getsupportfragmentmanager (). Findfragmentbytag (Contactfragment.getclass (). GetName); Mefragment = Getsupportfragmentmanager (). Findfragmentbytag (Mefragment.getclass (). GetName); index = Saveinstancestate.getint (Key_index);Determine which fragment to show before leaving according to the subscript,This omits the judgment code, assuming it was conactfragment before leaving.Resolve overlapping issues Getfragmentmanager (). BeginTransaction (). Show (Contactfragment). Hide (Msgfragment). Hide (mefragment). Commit (); }else{ //Normal msgfragment = Msgfragment.newinstance (); contactfragment = Contactfragment.newinstance (); Mefragment = Mefragment.newinstance (); Getfragmentmanager (). BeginTransaction (). Add (R.id.container, Msgfragment, Msgfragment.getclass (). GetName ()). Add ( R.id.container, Contactfragment, Contactfragment.getclass (). GetName ()). Add (R.id,container,mefragment, Mefragment.getclass (). GetName ()). Hide (Contactfragment). Hide (Mefragment). commit (); }}@Overridepublic void onsaveinstancestate(Bundle outstate) { super.onsaveinstancestate ( Outstate); //Save the current fragment subscript outstate.putint (Key_index, INDEX);}
Of course, in "sibling" relationships, using getfragments () recovery is also possible.
Precautions for using viewpager+fragment
1, when using viewpager+fragment, switch different Viewpager page, will not callback any life cycle method as well onHiddenChanged()
, only setUserVisibleHint(boolean isVisibleToUser)
will be callback, so if you want to do some lazy loading, need to deal with here.
2, in the Viewpager binding fragmentpageradapter, new FragmentPagerAdapter(fragmentManager)
the Fragmentmanager, must ensure that the correct, if the Viewpager is the activity within the control, then pass getSupportFragmentManager()
, If it is in a fragment control, it should be passed getChildFragmentManager()
. Just remember that the fragments in Viewpager is the principle of sub-fragment of the current component.
3, if the use of viewpager+fragment, do not need to "memory restart" in the case, to restore the fragments, there is a fragmentpageradapter existence, do not need you to do recovery work.
Fragment business that you may not know the pit
1, if you use the popBackStackImmdiate()
method, and then directly invoke a method similar to the following transactions, because they run in the message queue problem, before the stack to run the transaction method, which may lead to anomalies.
getSupportFragmentManager().popBackStackImmdiate();getSupportFragmentManager().beginTransaction() .add(R.id.container, fragment , tag) .hide(currentFragment) .commit;
The correct approach is to use the handler of the main thread and put the transaction into runnable.
getSupportFragmentManager().popBackStackImmdiate();new Handler().post(new Runnable(){ @Override public void run() { // 在这里执行Fragment事务 }});
2, for fragment set fragment transition animation, if you do not have a complete solution, you should avoid use .setTransition(transit)
and .setCustomAnimations(enter, exit, popEnter, popExit)
, but only use .setCustomAnimations(enter, exit)
this method.
The other 2 methods will cause a bug in "memory restart" in some cases.
The last article in this series gives me a solution that solves the problem and is interested in viewing it yourself:)
another mention : the use popStackBack(String tag/int id,int flasg)
of a series of methods carefully, for reasons described in the previous article.
Is it a single activity+ multi-fragment architecture or multi-module activity+ multi-fragment architecture?
Single activity+ multi-fragment:
An app has only one activity, and the interface is used by Frament,activity as an app container.
Advantages: High performance and fastest speed. Reference: New version, Google Apps
Cons: Logic is more complex, especially when the fragment between more linkage or deep nesting, more complex.
Multi-module activity+ multi-fragment:
A module uses an activity, such as
1. Login Registration Process:
Loginactivity + Login Fragment + Register fragment + fill in information fragment + forgot password fragment
2, or the common data presentation process:
dataactivity + Data List fragment + data details fragment + ...
Advantages: fast speed, compared to single activity+ more fragment, easier to maintain.
My point of view:
The pros and cons, I think multi-module activity+ multi-fragment is the most suitable architecture, not very complex development, the performance of the app is very efficient.
Of course. fragment is only an official flexible component, please follow your project design! a really special complex interface, or a single activity can complete a process interface, using activity may be a better solution.
At last
If you have read the first and this article, then I am sure you will find a solution for most of the pits you encounter with multi-module activity+ multi-fragment architectures.
However, if the process is more complex, such as fragment a needs to start a new fragment B and close the current a, or a boot b,b after acquiring the data, want to return to a when the data to a (similar to activity startActivityForResult
), Or do you promise to use the fragment to pop(tag\id)
exit multiple fragment from the stack, or even if you want to fragment have a startup mode like activity, SingleTask
then you can refer to the next article, My solution Gallery, Fragmentation. It even provides a UI interface that allows you to view the stack view of all classes at any time while developing.
Wen/yokeyword (author of Jane's book)
Original link: http://www.jianshu.com/p/fd71d65f0ec6
Copyright belongs to the author, please contact the author to obtain authorization, and Mark "book author".
Fragment full Analytical Series (ii): Correct use Posture