javaandroidandroid-studioandroid-fragmentactivityfragment-lifecycle

Explanation needed for - Blank Fragment Java code in Android Studio


This is the Fragment java file created for my menu item 'Album' - AlbumFragment.java

package postbox.twentyfour.mybag;

import android.os.Bundle;

import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link AlbumFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class AlbumFragment extends Fragment {

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public AlbumFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment AlbumFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static AlbumFragment newInstance(String param1, String param2) {
        AlbumFragment fragment = new AlbumFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_album, container, false);
    }
}

Please Give the complete explanation for this java code.


Solution

  • This is a long one, so please stick with me!

    public class AlbumFragment extends Fragment
    

    The main point here is that we are of course extending from the Fragment API. Your class (AlbumFragment) is inheriting a lot of code! The Fragment API is substantial and as always it is worth keeping the guides and docs around for reference.

    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
    

    Our argument parameter keys/labels are created as constants. We use these as a key to refer to data passed in a Bundle from where our new Fragment instances (objects) are being created. In this case, I assume your Main Activity. Note the variable definitions are in block capitals - this is a Java convention used for constants (a variable that will not change after it's creation - ie; final).

    private String mParam1;
    private String mParam2;
    

    Simple variable definitions for storing data within an instance of this Fragment (object/class).

    public AlbumFragment() {
        // Required empty public constructor
    }
    

    This is an unfortunately necessary feature of the Android Fragment API. You won't be changing this at all. I'm sure you will learn more about this as you progress in your Android journey! Don't worry about it right now.

    public static AlbumFragment newInstance(String param1, String param2) {
        AlbumFragment fragment = new AlbumFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }
    

    This is a common convention used for instantiating new instances of a fragment - in your case AlbumFragment. (It is not the only way to go about things, but certainly a good way.)

    You will call this method from your MainActivity (or controller), to create a new instance of this fragment. Use this method to pass data from your controller (your Activity in your case). You can change these arguments as necessary to pass (serialised) data via a Bundle.

    Don't get confused by this method being within AlbumFragment itself - note that it is static. It is simply a helper method, to make life easier when instantiating a new Fragment object. The logic in this method could just as easily written within MainActivity (or the controller).

    See reference docs and guides on bundles.

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }
    

    This method call is an important part of the Fragment lifecycle.

    In this case, we are accessing any saved state, and reassigning the saved data to our variables as we potentially recreate our fragment. This will happen when you rotate the phone screen, or when your phone has been sleeping for a while and you come back to your app after some time (these are just two examples among many). There is a lot to consider here, but experimentation will serve you well!

    The fragment lifecycle is an entire topic unto itself, but shares many similar method calls with the activity lifecycle. Understanding the activity and fragment lifecycles is tough, but absolutely crucial for being an android developer. I can't recommend enough to keep with it, no matter how tough that mountain can be to climb (I've been there myself), it'll will make a big difference to you in the long run.

    For fragment life cycle you can refer to these training docs.

        @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_album, container, false);
    }
    

    Lastly is another lifecycle method call - in this case "onCreateView". This is where your layout is inflated and any data (stored in those mParam1, mParam2 variables) bound to your view! This is where those XML files come into play.

    A word to the wise - be sure to assign ID's in your XML to any layout views that your wish state to be saved on screen rotation / phone sleeping, etc.

    android:id="@+id/some_id"
    

    This will allow android (in simpler cases) to manage saved state for you and will really save a lot of frustration!