Fragment Arguments

Every fragment instance can have a Bundle object attached to it. This bundle contains key-value pairs that work just like the intent extras of an Activity. Each pair is known as an argument.

To create fragment arguments, you first create a Bundle object. Next, you use type-specific put methods of Bundle (similar to those of Intent) to add arguments to the bundle:

    Bundle args = new Bundle();
    args.putSerializable(ARG_MY_OBJECT, myObject);
    args.putInt(ARG_MY_INT, myInt);
    args.putCharSequence(ARG_MY_STRING, myString);

Attaching arguments to a fragment

To attach the arguments bundle to a fragment, you call Fragment.setArguments(Bundle). Attaching arguments to a fragment must be done after the fragment is created but before it is added to an activity.

To hit this window, Android programmers follow a convention of adding a static method named newInstance() to the Fragment class. This method creates the fragment instance and bundles up and sets its arguments.

When the hosting activity needs an instance of that fragment, you have it call the newInstance(…) method rather than calling the constructor directly. The activity can pass in any required parameters to newInstance(…) that the fragment needs to create its arguments.

In CrimeFragment, write a newInstance(UUID) method that accepts a UUID, creates an arguments bundle, creates a fragment instance, and then attaches the arguments to the fragment.

Listing 10.6  Writing a newInstance(UUID) method (CrimeFragment.java)

public class CrimeFragment extends Fragment {

    private static final String ARG_CRIME_ID = "crime_id";

    private Crime mCrime;
    private EditText mTitleField;
    private Button mDateButton;
    private CheckBox mSolvedCheckbox;

    public static CrimeFragment newInstance(UUID crimeId) {
        Bundle args = new Bundle();
        args.putSerializable(ARG_CRIME_ID, crimeId);

        CrimeFragment fragment = new CrimeFragment();
        fragment.setArguments(args);
        return fragment;
    }
    ...
}

Now, CrimeActivity should call CrimeFragment.newInstance(UUID) when it needs to create a CrimeFragment. It will pass in the UUID it retrieved from its extra. Return to CrimeActivity and, in createFragment(), retrieve the extra from CrimeActivity’s intent and pass it into CrimeFragment.newInstance(UUID).

You can now also make EXTRA_CRIME_ID private, because no other class will access that extra.

Listing 10.7  Using newInstance(UUID) (CrimeActivity.java)

public class CrimeActivity extends SingleFragmentActivity {

    public private static final String EXTRA_CRIME_ID =
            "com.bignerdranch.android.criminalintent.crime_id";
    ...
    @Override
    protected Fragment createFragment() {
        return new CrimeFragment();
        UUID crimeId = (UUID) getIntent()
                .getSerializableExtra(EXTRA_CRIME_ID);
        return CrimeFragment.newInstance(crimeId);
    }
}

Notice that the need for independence does not go both ways. CrimeActivity has to know plenty about CrimeFragment, including that it has a newInstance(UUID) method. This is fine. Hosting activities should know the specifics of how to host their fragments, but fragments should not have to know specifics about their activities. At least, not if you want to maintain the flexibility of independent fragments.

Retrieving arguments

When a fragment needs to access its arguments, it calls the Fragment method getArguments() and then one of the type-specific get methods of Bundle.

Back in CrimeFragment.onCreate(…), replace your shortcut code with retrieving the UUID from the fragment arguments.

Listing 10.8  Getting crime ID from the arguments (CrimeFragment.java)

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    UUID crimeId = (UUID) getActivity().getIntent()
            .getSerializableExtra(CrimeActivity.EXTRA_CRIME_ID);
    UUID crimeId = (UUID) getArguments().getSerializable(ARG_CRIME_ID);
    mCrime = CrimeLab.get(getActivity()).getCrime(crimeId);

}

Run CriminalIntent. The app will behave the same, but you should feel all warm and fuzzy inside for maintaining CrimeFragment’s independence. You are also well prepared for the next chapter, where you will implement more sophisticated navigation in CriminalIntent.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.190.167