Fragment-Loading and Data Communication of Android Notes

Posted by micknc on Tue, 16 Jul 2019 21:36:41 +0200

I. Loading Method

1. Static loading

1.1 Loading Step

(1) Create fragment: Create a custom fragment class that inherits from the Fragment class and binds the custom fragment class to the Fragment view (converting layout into View)

View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)

_inflater is used to bind the layout file of Fragment and convert the layout into a View object and return it; container is the parent container of the UI of Fragment. The UI whose return value is Fragmented is returned to null if it is not displayed.

inflate(int resource, ViewGroup root, boolean attachToRoot)

_resource is the layout file that Fragment needs to load; root is the parent ViewGroup that loads Fragment, which is the container passed in by onCreateView; attachToRoot is whether to return to the parent ViewGroup.

(2) Using fragment: Introducing fragment in parent view, static loading must specify name attribute and a unique identifier, which can be id or tag.

<!--Specify in layout Instantiated in Fragment Class, need to be "package name".The Complete Form of Class Name-->
android:name
<!--Unique identification, id and tag Either way, you can't have neither.-->
android:id
android:tag

(3) Listening events: If you set listening events in the class corresponding to the parent view, you can directly access the child components in the fragment; if you set them in the class of the fragment, you must access the child components in the fragment (view. findViewById (id) through the View object returned by inflate().

1.2 Simple Example

MyFragment view:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/fragment_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

MyFragment class:

public class MyFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    
        //Converting layout to View object
        View view = inflater.inflate(R.layout.myfragment, container, false);
        
        //Its subcomponents must be accessed through the view object
        TextView textView = (TextView) view.findViewById(R.id.fragment_text);
        textView.setText("Here is fragment");
        
        //Return Fragment to display UI
        return view;
    }
}

Refer to the parent view of fragment:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.studying.StaticFragmentActivity">

    <fragment
        android:tag="fragment"
        android:name="com.joahyau.studying.MyFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

The class corresponding to the parent view sets event listeners:

public class StaticFragmentActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_static_fragment);

        //Accessible directly through findViewById
        findViewById(R.id.fragment_text).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(StaticFragmentActivity.this, "Click on the text", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

2. Dynamic Loading

2.1 Loading Step

(1) Acquisition transaction manager: add, remove and replace fragments are transactions. The transaction manager needs to be acquired through the following code to dynamically manipulate fragments.

FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();

(2) Create Fragment Objects: Create fragments that need to be loaded, and then dynamically load them through add or replace.

2.2 Simple Example

Layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="io.github.joahyau.studying.DynamicFragmentActivity">

    <Button
        android:id="@+id/load"
        android:text="Load"
        android:layout_width="match_parent"
        android:layout_height="80dp" />

    <LinearLayout
        android:id="@+id/container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal" />
</LinearLayout>

Java:

public class DynamicFragmentActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dynamic_fragment);

        findViewById(R.id.load).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Get the transaction manager
                FragmentManager fragmentManager = getFragmentManager();
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

                //Create fragment s and dynamically load them into the layout of id-bit container s
                MyFragment myFragment = new MyFragment();
                fragmentTransaction.add(R.id.container, myFragment);
                //Submission transaction
                fragmentTransaction.commit();
            }
        });
    }
}

II. Data Communication

3. Activity delivers data to Fragment

3.1 Activity delivers data to dynamically loaded Fragment s

(1) Get Fragment objects in Activity;

(2) Create Bundle objects and pass in data;

(3) Pass the Bundle object to the Fragment object;

(4) Obtain the Bundle object in Fragment and unpack the data.

Example: There is only one Button with send id in Activity and only one TextView in MyFragment, so the layout code is no longer placed here.

Activity:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.send).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Creating Fragment Objects
                MyFragment myFragment = new MyFragment();

                //Create Bundle objects and pass in data
                Bundle bundle = new Bundle();
                bundle.putString("info", "Here is the direction. Fragment Transferred data");
                myFragment.setArguments(bundle);

                //Loading Fragment
                FragmentManager fragmentManager = getFragmentManager();
                FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
                beginTransaction.add(R.id.layout, myFragment, "myfragment");
                beginTransaction.commit();
            }
        });
    }
}

Fragment:

public class MyFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.my_fragment, container, false);
        TextView tv = (TextView) view.findViewById(R.id.text);

        //get data
        String text = getArguments().get("info") + "";
        tv.setText(text);

        return view;
    }
}

3.2 Activity delivers data to statically loaded Fragment s

(1) Create data objects as containers in Fragment, and create getter s and setter s;

(2) Get Fragment Manager in Activity;

(3) fragment objects are obtained by findFragmentById or findFragmentByTag methods of transaction manager.

(4) The value is passed by calling the setter method of the container through the obtained fragment object.

Example: The only difference between the layout here and that of dynamic loading is that the send button is placed in the Fragment, and the rest is the same.

Fragment:

public class MyFragment extends Fragment {

    private Button btn;
    private String received;//Objects as containers

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.my_fragment, container, false);
        TextView tv = (TextView) view.findViewById(R.id.text);
        tv.setText("Here is Fragment");

        btn = (Button) view.findViewById(R.id.send);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getActivity(), "Successful reception\"" + getReceived() + "\"", Toast.LENGTH_SHORT).show();
            }
        });

        return view;
    }

    public String getReceived() {
        return received;
    }

    public void setReceived(String received) {
        this.received = received;
    }
}

Activity:

public class MainActivity extends Activity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentManager fragmentManager = getFragmentManager();
        MyFragment myFragment = (MyFragment) fragmentManager.findFragmentById(R.id.my_fragment);
        myFragment.setReceived("this is a test.");
    }
}

4. Fragment delivers data to Activity

(1) Write a callback interface in Fragment;

(2) This callback interface is implemented in activity, and the functions implemented are used to transfer values.

(3) Rewrite onAttach in Fragment, create an interface object and get the passed activity (I understand that this interface is actually a parent class of the passed activity, which is used for polymorphism).

(4) Pass values with the obtained interface objects.

Fragment:

public class MyFragment extends Fragment {

    private SendData sendData;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        //Get the implemented interface object
        sendData = (SendData) activity;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.my_fragment, container, false);
        TextView tv = (TextView) view.findViewById(R.id.text);
        tv.setText("Here is Fragment");

        //Transfer data through interface objects
        sendData.sendMsg("this is a test.");

        return view;
    }

    //Define a callback interface
    public interface SendData{
        void sendMsg(String str);
    }
}

Activity:

public class MainActivity extends Activity implements MyFragment.SendData{

    private Button btn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = (Button) findViewById(R.id.send);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MyFragment myFragment = new MyFragment();

                FragmentManager fragmentManager = getFragmentManager();
                FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
                beginTransaction.add(R.id.layout, myFragment);
                beginTransaction.commit();
            }
        });
    }

    //Implement SendData interface to receive data
    @Override
    public void sendMsg(String str) {
        Toast.makeText(this, "Successful reception\"" + str + "\"", Toast.LENGTH_SHORT).show();
    }
}

Topics: Android Fragment xml encoding