Introduction to lightweight development kits for fragment write parameters in Android Fragmentargs _android

Source: Internet
Author: User

Android development can sometimes cause headaches. You have to write a lot of code for something as simple as building fragment. Fortunately, Java supports a powerful tool: the annotation processor (Annotation processors).

The problem with fragment is that you have to set a lot of parameters so that it works. Many Android developers usually write this:

Copy Code code as follows:

public class Myfragment extends Fragment
{
private int id;
Private String title;

public static myfragment newinstance (int id, String title)
{
Myfragment f = new myfragment ();
F.id = ID;
F.title = title;
return F;
}

@Override
Public View Oncreateview (layoutinflater inflater, ViewGroup container,
Bundle savedinstancestate)
{
Toast.maketext (Getactivity (), "Hello" + title.substring (0, 3),
Toast.length_short). Show ();
}
}

What's wrong with doing this? I've tried it on my device.

It works, but have you ever tried to change your device from vertical to horizontal? Your app will crash because of NullPointerException when you try to access the ID or title.

My app is normal because I set the app to vertical. So I've never had this problem before.

Whatever you want! Android is a really multitasking operating system. Multiple apps run at the same time, and if the memory Android system is needed, the activity (and the fragment contained therein) will be destroyed. You may not notice these problems in your daily app development. However, when you publish in the Play store, you will notice that your app crashes, but you don't know why. Users of your app may be using multiple apps at the same time, and it's possible that your app was destroyed in the background. For example: A user opens your app,myfragment to display on the screen. Next, your user presses the home key (this is your app running in the background) and opens up other apps. Your app may be destroyed by releasing memory. After that, the user returns to your app, for example through a multitasking button. So what is Android going to do now? The problem is that Android will restore the previous app state and restore myfragment. Fragment attempts to access title, but the title is NULL because it is not persisted.

I know, so I need to keep them in onsaveinstancestate (Bundle)?

No. The official documents are not clear, but onsaveinstancestate (Bundle) should be used like you would with Activity.onsaveinstancestate (Bundle): You use this method to save the "temp" state of the instance, For example, to handle the direction of the screen (from vertical to horizontal, and vice versa). So when app is killed in the background, the instance state of the fragment cannot be saved as persistent data, and its role is to restore the data once again when it returns to the foreground. It works the same as Activity.onsaveinstancestate (Bundle) in activity, and they are used to "temporarily" save instance states. However, the persistent parameters are transmitted via intent external data.

So should I have intent in the activity to save the fragment parameters?

No need, fragment has its own mechanism. There are two methods: Fragment.setarguments (Bundle) and fragment.getarguments (), which you must use to ensure that the parameters are persisted. This is the pain I mentioned above. A lot of code needs to be written like this. First, you want to create a bundle, and then you need to put the key-value pair, and finally call Fragment.setarguments (). Unfortunately, your work is not over yet and you have to read the bundle through Fragment.getarguments (). Some of these jobs:

Copy Code code as follows:

public class Myfragment extends Fragment
{
private static String key_id = "Key.id";
private static String Key_title = "Key.title";
private int id;
Private String title;

public static myfragment newinstance (int id, String title)
{
Myfragment f = new myfragment ();
Bundle B = new Bundle ();
B.putint (key_id, ID);
B.putstring (Key_title, TITLE);
F.setarguments (b);
return F;
}

@Override
public void OnCreate (Bundle savedinstancestate)
{
OnCreate it ' s a good point to read the arguments
Bundle B = getarguments ();
This.id = B.getint (key_id);
This.title = b.getstring (Key_title);
}

@Override
Public View onCreate (layoutinflater inflater, ViewGroup container,
Bundle savedinstancestate)
{
No Nullpointer here, because OnCreate () are called before this
Toast.maketext (Getactivity (), "Hello" + title.substring (0, 3),
Toast.length_short). Show ();
}
}

I hope you can now understand what I mean by "pain." In your application you will write a lot of code for each fragment. If someone writes this code for you, it's not going to be satisfying. Annotation processing allows you to generate Java code at compile time. Note that we are not talking about evaluating comments that use reflection at run time.

Fragmentargs is a lightweight package that is used to generate accurate Java code for your fragment.

Copy Code code as follows:

Import Com.hannesdorfmann.fragmentargs.FragmentArgs;
Import Com.hannesdorfmann.fragmentargs.annotation.Arg;

public class Myfragment extends Fragment
{
@Arg
int id;
@Arg
String title;

@Override
public void OnCreate (Bundle savedinstancestate)
{
Super.oncreate (savedinstancestate);
Fragmentargs.inject (this); Read @Arg fields
}

@Override
Public View Oncreateview (layoutinflater inflater, ViewGroup container,
Bundle savedinstancestate)
{
Toast.maketext (Getactivity (), "Hello" + title, Toast.length_short)
. Show ();
}
}


Just add the annotation field to your fragment class and Fragmentargs will generate the reference code. In your activity you will use the generated Builder class (your fragment suffix is "Builder") instead of using the new myfragment () or static myfragment.newinstance (int ID, String title) method.

For example:

Copy Code code as follows:

public class MyActivity extends activity
{
public void OnCreate (Bundle savedinstancestate)
{
Super.oncreate (savedinstancestate);
int id = 123;
String title = "Test"; Using the generated Builder
Fragment Fragment = new Myfragmentbuilder (ID, title). Build (); Fragment Transaction
Getfragmentmanager (). BeginTransaction (). replace (r.id.container,fragment). commit ();
}
}

You may have noticed the fragmentargs.inject (this) declared in Fragment.oncreate (Bundle). This call allows your fragment to get a connection to the generated code. You may ask yourself: "I don't need to add inject () method to the OnCreate (Bundle) in every fragment." The answer is no. You just need to insert this sentence into your fragment base class and inherit it in all fragment.

Copy Code code as follows:

public class Basefragment extends Fragment
{
@Override
public void OnCreate (Bundle savedinstancestate)
{
Super.oncreate (savedinstancestate);
Fragmentargs.inject (this); Read @Arg fields
}
}

public class Myfragment extends Basefragment
{
@Arg
String title;

@Override
Public View Oncreateview (layoutinflater inflater, ViewGroup container,
Bundle savedinstancestate)
{
Toast.maketext (Getactivity (), "Hello" + title, Toast.length_short)
. Show ();
}
}

Credits: part of the annotation generation code is based on Hugo Visser's bundles project.

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.