Android Development long distance xiii--fragment best practices

Source: Internet
Author: User
Tags getcolor

This article is a series of articles, I am in the long-distance development of Android a little thoughts and records, I will try to follow the first easy after the difficult sequence to write the series. The series cited the "Android Development art exploration" and "in-depth understanding of Android volume Ⅰ,ⅱ,ⅲ" in the relevant knowledge, in addition to learn from other high-quality blog, here to the great God to thank you, worship!!!

Objective

The previous article detailed analysis of fragment related knowledge, then as "small activity", what can fragment do, how to use fragment to get the best practice. Fragment's design may have been designed primarily for the needs of large-screen tablet devices, but now fragment is widely used in our regular mobile devices. is a feature that we can find in almost every major app.

Friends who are familiar with Android will know, very simple, use tabhost is OK! But as everyone knows, tabhost is not so simple, its extensibility is very poor, can not arbitrarily customize the contents of the tab display, but also depends on the operation of Activitygroup. Activitygroup was originally used primarily to manage a single activity for each of the Tabhost's children, but it is now obsolete. Why is it? Of course, it's because of fragment's appearance!

Well, the following I will come to realize the effect, but before you start, you must already understand the use of fragment, if you are more unfamiliar with fragment, suggest first read my previous article on Android development long-distance xii--fragment detailed

Create the host activity first

New bestfragmentactivity

public class Bestfragmentactivity extends appcompatactivity {@Override protected void onCreate (Bundle savedinstance        State) {super.oncreate (savedinstancestate);            Setcontentview (r.layout.activity_best_fragment); The following is the use of luseenbottomnavigation bottomnavigationview Bottomnavigationview = (bottomnavigationview) findViewById (    R.id.bottomnavigation); Bottomnavigationitem Bottomnavigationitem = new Bottomnavigationitem ("Home", Contextcompat.getcolor (this, R.colo    R.firstcolor), R.MIPMAP.IC_ACCOUNT_BALANCE_WHITE_48DP); Bottomnavigationitem bottomNavigationItem1 = new Bottomnavigationitem ("Classification", Contextcompat.getcolor (this, r.col    Or.secondcolor), R.MIPMAP.IC_LIST_WHITE_48DP); Bottomnavigationitem bottomNavigationItem2 = new Bottomnavigationitem ("task", Contextcompat.getcolor (this, r.col    Or.firstcolor), R.MIPMAP.IC_ADD_CIRCLE_OUTLINE_WHITE_48DP);           Bottomnavigationitem bottomNavigationItem3 = new Bottomnavigationitem ("Shopping Cart", Contextcompat.getcolor (this, r.color.thirdcolor), R.MIPMAP.IC_ADD_SHOPPING_CART_WHITE_48DP); Bottomnavigationitem bottomNavigationItem4 = new Bottomnavigationitem ("My", Contextcompat.getcolor (this, r.col    or.coloraccent), R.MIPMAP.IC_ACCOUNT_BOX_WHITE_48DP);    Bottomnavigationview.addtab (Bottomnavigationitem);    Bottomnavigationview.addtab (BOTTOMNAVIGATIONITEM1);    Bottomnavigationview.addtab (BOTTOMNAVIGATIONITEM2);    Bottomnavigationview.addtab (BOTTOMNAVIGATIONITEM3);    Bottomnavigationview.addtab (BOTTOMNAVIGATIONITEM4); }}

The corresponding layout file activity_best_fragment

<?xml version= "1.0" encoding= "Utf-8"? ><relativelayout xmlns:android= "http://schemas.android.com/apk/res/ Android "xmlns:app=" Http://schemas.android.com/apk/res-auto "android:layout_width=" Match_parent "Android:layout_h eight= "Match_parent" android:id= "@+id/main_content" android:fitssystemwindows= "true" > <!--fragment after the dynamic        In the layout file--<framelayout android:id= "@+id/frame_content" android:layout_width= "Match_parent" android:layout_height= "Match_parent" android:scrollbars= "None" android:layout_above= "@+id/bottomnavigation "/> <!--about the underlying layout I used the open source project on GitHub--<com.luseen.luseenbottomnavigation.bottomnavigation.bottomna Vigationview android:id= "@+id/bottomnavigation" android:layout_width= "Match_parent" android:layout_he ight= "Wrap_content" android:layout_alignparentbottom= "true" app:bnv_colored_background= "false" app:bn V_with_text= "true" app:Bnv_shadow= "false" app:bnv_tablet= "false" App:bnv_viewpager_slide= "true" app:bnv_active_color= "@color /colorprimary "app:bnv_active_text_size=" @dimen/bottom_navigation_text_size_active "App:bnv_inactive_text_si Ze= "@dimen/bottom_navigation_text_size_inactive"/></relativelayout>

About the underlying layout I used the open source project Luseenbottomnavigation on GitHub, the project address is Https://github.com/armcha/LuseenBottomNavigation readers can see for themselves

Then create the Fragment

Currently fragment as a demonstration to use, you can see the layout of the contents are very simple, I here only give one of the fragment of the creation process and source code, the project complete source code visible at the end of the source address.

We'll take the first goodsfragment example

public class Goodsfragment extends Fragment {private static String tag= GoodsFragment.class.getSimpleName ();        @Override public void Onattach (context context) {Super.onattach (context);    LOG.D (TAG, "Onattach"); } @Nullable @Override public View oncreateview (layoutinflater inflater, ViewGroup container, Bundle savedinstance        State) {LOG.D (TAG, "Oncreateview");        View view = Inflater.inflate (r.layout.fragment_goods, NULL);    return view; } @Override public void onviewcreated (view view, @Nullable Bundle savedinstancestate) {super.onviewcreated (v        Iew, savedinstancestate);    LOG.D (TAG, "onviewcreated"); } @Override public void onactivitycreated (@Nullable Bundle savedinstancestate) {super.onactivitycreated (save        Dinstancestate);    LOG.D (TAG, "onactivitycreated");        } @Override public void OnCreate (@Nullable Bundle savedinstancestate) {super.oncreate (savedinstancestate); LOG.D (TAG, "oncrEate ");        } @Override public void OnStart () {Super.onstart ();    LOG.D (TAG, "OnStart");        } @Override public void Onresume () {super.onresume ();    LOG.D (TAG, "Onresume");        } @Override public void OnPause () {super.onpause ();    LOG.D (TAG, "onPause");        } @Override public void OnStop () {super.onstop ();    LOG.D (TAG, "onStop");        } @Override public void Ondestroyview () {Super.ondestroyview ();    LOG.D (TAG, "Ondestroyview");        } @Override public void OnDestroy () {Super.ondestroy ();    LOG.D (TAG, "OnDestroy");        } @Override public void Ondetach () {Super.ondetach ();    LOG.D (TAG, "Ondetach"); }}

The source code is very simple, loading the layout file in Oncreateview, the layout file is very simple, just define a frame layout, in the frame layout contains a TextView

<?xml version="1.0" encoding="utf-8"?><FrameLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Goods"        android:textStyle="bold"        android:textSize="30sp"        android:layout_gravity="center"/></FrameLayout>

According to the above process we established the required fragment, and then change the bestfragmentactivity code, the source of the change is as follows

public class Bestfragmentactivity extends appcompatactivity{@Override protected void onCreate (Bundle savedinstances        Tate) {super.oncreate (savedinstancestate);        Setcontentview (r.layout.activity_best_fragment);        Bottom navigation layout bottomnavigationview Bottomnavigationview = (bottomnavigationview) Findviewbyid (r.id.bottomnavigation); Bottomnavigationitem Bottomnavigationitem = new Bottomnavigationitem ("Home", Contextcompat.getcolor (th        is, R.color.firstcolor), R.MIPMAP.IC_ACCOUNT_BALANCE_WHITE_48DP); Bottomnavigationitem bottomNavigationItem1 = new Bottomnavigationitem ("Classification", Contextcompat.getcolor (this, R        . Color.secondcolor), R.MIPMAP.IC_LIST_WHITE_48DP); Bottomnavigationitem bottomNavigationItem2 = new Bottomnavigationitem ("task", Contextcompat.getcolor (this, R        . Color.firstcolor), R.MIPMAP.IC_ADD_CIRCLE_OUTLINE_WHITE_48DP);      Bottomnavigationitem bottomNavigationItem3 = new Bottomnavigationitem          ("Shopping Cart", Contextcompat.getcolor (this, r.color.thirdcolor), R.MIPMAP.IC_ADD_SHOPPING_CART_WHITE_48DP); Bottomnavigationitem bottomNavigationItem4 = new Bottomnavigationitem ("My", Contextcompat.getcolor (this, R        . color.coloraccent), R.MIPMAP.IC_ACCOUNT_BOX_WHITE_48DP);        Bottomnavigationview.addtab (Bottomnavigationitem);        Bottomnavigationview.addtab (BOTTOMNAVIGATIONITEM1);        Bottomnavigationview.addtab (BOTTOMNAVIGATIONITEM2);        Bottomnavigationview.addtab (BOTTOMNAVIGATIONITEM3);        Bottomnavigationview.addtab (BOTTOMNAVIGATIONITEM4); Set the Click event Bottomnavigationview.setonbottomnavigationitemclicklistener for the bottom navigation layout (new                Onbottomnavigationitemclicklistener () {@Override public void Onnavigationitemclick (int i) {                        switch (i) {case 0:switchtohome ();                    Break       Case 1:switchtocategory ();                 Break                        Case 2:switchtotask ();                    Break                        Case 3:switchtogoodcar ();                    Break                        Case 4:switchtoabout ();                Break                }            }        });    Initial load first page, namely Goodsfragment switchtohome (); } private void Switchtoabout () {Getsupportfragmentmanager (). BeginTransaction (). Replace (r.id.frame_content,n    EW aboutfragment (), AboutFragment.class.getName ()). commit (); } private void Switchtocategory () {Getsupportfragmentmanager (). BeginTransaction (). Replace (R.id.frame_content,ne    W categoryfragment (), CategoryFragment.class.getName ()). commit (); } private void SwitchToTask () {Getsupportfragmentmanager (). BeginTransaction (). replace (R.id.frame_content,new Ta    Skfragment (), TaskFragment.class.getName ()). commit (); } private void SwitchtOgoodcar () {Getsupportfragmentmanager (). BeginTransaction (). Replace (R.id.frame_content,new goodcarfragment (),    GoodCarFragment.class.getName ()). commit (); } private void Switchtohome () {Getsupportfragmentmanager (). BeginTransaction (). replace (R.id.frame_content,new Go    Odsfragment (), GoodsFragment.class.getName ()). commit (); }}

The above code can be based on the previous article is easier to write out, and normal operation, but in the actual development process we have to consider the performance of the code. In fact, the above code has a performance problem, especially in the bottom navigation in this scenario, fragment between the back and forth, the Replace method used here. The problem with this method and how to optimize it are explained in detail in the next section.

Fragment Performance Optimization Problem fragmenttransaction

When talking about the performance optimization problem of fragment, we have to study and explore Fragmenttransaction, which uses Getsupportfragmentmanager (). BeginTransaction () The Fragmenttransaction object is obtained, and the Replace method and the commit method are called in turn.

    • replace (int containerviewid, Fragment Fragment), replace (int containerviewid, Fragment Fragment, String tag)

The function of this method is similar to remove all fragment of the view container first, add the fragment in the method parameter, and set tag tag for the fragment.

    getSupportFragmentManager().beginTransaction().add(R.id.frame_content,new AboutFragment(),AboutFragment.class.getName()).commit();    getSupportFragmentManager().beginTransaction().add(R.id.frame_content,new CategoryFragment(),CategoryFragment.class.getName()).commit();    getSupportFragmentManager().beginTransaction().add(R.id.frame_content,new TaskFragment(),TaskFragment.class.getName()).commit();    getSupportFragmentManager().beginTransaction().replace(R.id.frame_content,new GoodsFragment(),GoodsFragment.class.getName()).commit();

As shown in the code block above, we first made 3 additions, then the replace operation moves out of the previously added fragment and adds the frament specified in the method parameter.

    • Add (int containerviewid, Fragment Fragment, String tag), remove (Fragment Fragment)
      The Add () operation of the fragmenttransaction is maintained in a queue, in which the order in which the add goes in is formed into a linked list, and the actions above us in the form of this listing change as shown:

    • Remove (Fragment Fragment): Removes an already existing Fragment.

    • Show (Fragment Fragment): shows a Fragment that was previously hidden

    • Hide (Fragment Fragment): Hides an existing Fragment

      Note:①fragment is hide/show, just hide/show fragment view, there will be no life cycle method calls.

      ② override the Onhiddenchanged method in fragment to listen for the Hide and show states of fragment.

There are some other ways not listed here, with the method listed above, we can have a very good optimization of the fragment.

Analysis of fragment performance problem and analysis of solving fragment performance problem

We use replace to switch pages, then each time you switch, fragment will be re-instantiated, reloading the data, which consumes performance and user data traffic. This is because the replace operation, each time the existing fragment instance in the container is emptied, and then add the specified fragment, it will cause the switch to the previous fragment, the instance will be re-fragment.

Fragment Performance Problem Solving

The

knows the root of the problem, and the solution is in the way. We can not use replace to make the page switch, then the method can be used as if only add, we may at the time of loading to determine whether fragment has been added to the queue, if added, we will show (show) The fragment, hide the other, If it has not been added, add it. This allows multiple fragment to be toggled without re-instantiation. This is exactly what it is in the code

public class Bestfragmentactivity extends appcompatactivity{//current Fragment private Fragment mcurfragment = new F    Ragment ();    Initialize the other fragment private goodsfragment mgoodsfragment = new Goodsfragment ();    Private Goodcarfragment mgoodcarfragment = new Goodcarfragment ();    Private Taskfragment mtaskfragment = new Taskfragment ();    Private Aboutfragment maboutfragment = new Aboutfragment ();    Private Categoryfragment mcategoryfragment = new Categoryfragment ();        @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);        Setcontentview (r.layout.activity_best_fragment);        Bottomnavigationview Bottomnavigationview = (bottomnavigationview) Findviewbyid (r.id.bottomnavigation); Bottomnavigationitem Bottomnavigationitem = new Bottomnavigationitem ("Home", Contextcompat.getcolor (this, R.        Color.firstcolor), R.MIPMAP.IC_ACCOUNT_BALANCE_WHITE_48DP); Bottomnavigationitem bottomNavigationItem1= new Bottomnavigationitem ("Classification", Contextcompat.getcolor (this, r.color.secondcolor), R.mipmap.ic_list_white        _48DP); Bottomnavigationitem bottomNavigationItem2 = new Bottomnavigationitem ("task", Contextcompat.getcolor (this, R        . Color.firstcolor), R.MIPMAP.IC_ADD_CIRCLE_OUTLINE_WHITE_48DP); Bottomnavigationitem bottomNavigationItem3 = new Bottomnavigationitem ("Shopping Cart", contextcompat.getcolor (this,        R.color.thirdcolor), R.MIPMAP.IC_ADD_SHOPPING_CART_WHITE_48DP); Bottomnavigationitem bottomNavigationItem4 = new Bottomnavigationitem ("My", Contextcompat.getcolor (this, R        . color.coloraccent), R.MIPMAP.IC_ACCOUNT_BOX_WHITE_48DP);        Bottomnavigationview.addtab (Bottomnavigationitem);        Bottomnavigationview.addtab (BOTTOMNAVIGATIONITEM1);        Bottomnavigationview.addtab (BOTTOMNAVIGATIONITEM2);        Bottomnavigationview.addtab (BOTTOMNAVIGATIONITEM3);    Bottomnavigationview.addtab (BOTTOMNAVIGATIONITEM4);    Bottomnavigationview.setonbottomnavigationitemclicklistener (New Onbottomnavigationitemclicklistener () {@Ov                        Erride public void Onnavigationitemclick (int. i) {switch (i) {case 0:                        Switchtohome ();                    Break                        Case 1:switchtocategory ();                    Break                        Case 2:switchtotask ();                    Break                        Case 3:switchtogoodcar ();                    Break                        Case 4:switchtoabout ();                Break        }            }        });    Switchtohome (); } private void Switchfragment (Fragment targetfragment) {fragmenttransaction transaction = Getsupportfragmentmanag        ER (). BeginTransaction ();      if (!targetfragment.isadded ()) {//If the targetfragment to be displayed has not been added      Transaction Hide (mcurfragment)//hides the current fragment. Add (R.id.frame_content, TARGETF        Ragment,targetfragment.getclass (). GetName ())//Add targetfragment. Commit ();                    } else {//if the targetfragment you want to display has been added transaction//hides the current fragment. Hide (Mcurfragment)        . Show (Targetfragment)//Display targetfragment. commit ();    }//update current fragment to targetfragment mcurfragment = targetfragment;    } private void Switchtoabout () {switchfragment (maboutfragment);    } private void Switchtocategory () {switchfragment (mcategoryfragment);    } private void SwitchToTask () {switchfragment (mtaskfragment);    } private void Switchtogoodcar () {switchfragment (mgoodcarfragment);    } private void Switchtohome () {switchfragment (mgoodsfragment); }}

That's what we're doing, and we're going back and forth, fragment only one instance at a time, less of the performance cost of destruction and re-creation, and when we want to update the data in fragment, We can override its Onhiddenchanged method in custom fragment

@Overridepublic void onHiddenChanged(boolean hidden) {    super.onHiddenChanged(hidden);    if (hidden){       //Fragment隐藏时调用    }else {        //Fragment显示时调用    }}
Source Address: Source Portal This chapter summary

We give a fragment best practice in this blog, we can see the effect of top and bottom navigation in many mainstream apps, and on this basis we discuss the performance problems and optimizations of using fragment improperly.

Next trailer

The next article is going to add something to the fragment, ListView.

Sincerely, salute.

Android Development long distance xiii--fragment best practices

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.