Example below is from Vivz slide nerd videos on youtube
MainActivity.java
package com.jamesfroggatt.fragments4.app; import android.app.Activity; import android.app.FragmentManager; import android.os.Bundle; public class MainActivity extends Activity implements Communicator{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public void respond(String data) { // get reference to fragment 2 FragmentManager manager=getFragmentManager(); // gives reference to fragment b FragmentB f2=(FragmentB)manager.findFragmentById(R.id.fragment2); f2.changeText(data); } }
FragmentA.java
package com.jamesfroggatt.fragments4.app; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; public class FragmentA extends Fragment implements View.OnClickListener { Button button; int counter=0; // create an interface reference variable // can refer to a subclass object // (dynamic runtime polymorphism) Communicator comm; //link the layout (fragment_a.xml) to the fragment class @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_a,container,false); } // initialise the button in fragment a // using onActivityCreated it is save to access // the view hierarchy as Activity has been create when // this method is called @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // in the left side we have an interface variable // on the right, a subclass object so we add the cast (Communicator) // This is possible because the activity implements the interface // which means the Activity is a subclass of the interface // comm is pointing to our mainActivity comm= (Communicator) getActivity(); button= (Button) getActivity().findViewById(R.id.buttonInFragmentA); // set button on click listener button.setOnClickListener(this); } @Override public void onClick(View v) { counter++; // comm.respond is in the mainActivity comm.respond("Button was clicked "+counter+" times"); } }
FragmentB.java
package com.jamesfroggatt.fragments4.app; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class FragmentB extends Fragment { TextView text; //link the layout (fragment_b.xml) to the fragment class @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_b,container,false); } // initialise the TextView in fragment b // using onActivityCreated it is save to access // the view hierarchy as Activity has been create when // this method is called @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); text= (TextView) getActivity().findViewById(R.id.textViewInFragmentB); } public void changeText(String data){ text.setText(data); } }
activity_main.xml
<RelativeLayout 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:background="#00BBFF" android:id="@+id/my_layout"> <fragment android:layout_width="match_parent" android:layout_height="wrap_content" android:name="com.jamesfroggatt.fragments4.app.FragmentA" android:id="@+id/fragment" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" /> <fragment android:layout_width="match_parent" android:layout_height="wrap_content" android:name="com.jamesfroggatt.fragments4.app.FragmentB" android:id="@+id/fragment2" android:layout_below="@+id/fragment" android:layout_alignLeft="@+id/fragment" android:layout_alignStart="@+id/fragment" android:layout_marginTop="147dp" /> </RelativeLayout>
fragment_a.xml
<?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" android:background="#772233"> <Button android:layout_margin="30dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click this" android:id="@+id/buttonInFragmentA" /> </LinearLayout>
fragment_b.xml
<?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" android:background="#FFCCAA"> <TextView android:layout_margin="30dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Large Text" android:id="@+id/textViewInFragmentB" android:layout_gravity="center_horizontal" /> </LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jamesfroggatt.fragments4.app" > <uses-sdk android:minSdkVersion="11"></uses-sdk> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.jamesfroggatt.fragments4.app.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
When orientation changes – how do we remember the state of Fragment A and Fragment B?
Look for
// MODIFIED CODE BEGIN //
// MODIFIED CODE END //
in the code of:
FragmentA.java
package com.jamesfroggatt.fragments4.app; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; public class FragmentA extends Fragment implements View.OnClickListener { Button button; int counter=0; // create an interface reference variable // can refer to a subclass object // (dynamic runtime polymorphism) Communicator comm; // MODIFIED CODE BEGIN // @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState==null){ counter=0; }else{ counter=savedInstanceState.getInt("counter",0); } } // MODIFIED CODE END // //link the layout (fragment_a.xml) to the fragment class @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_a,container,false); } // initialise the button in fragment a // using onActivityCreated it is save to access // the view hierarchy as Activity has been create when // this method is called @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // in the left side we have an interface variable // on the right, a subclass object so we add the cast (Communicator) // This is possible because the activity implements the interface // which means the Activity is a subclass of the interface // comm is pointing to our mainActivity comm= (Communicator) getActivity(); button= (Button) getActivity().findViewById(R.id.buttonInFragmentA); // set button on click listener button.setOnClickListener(this); } // MODIFIED CODE BEGIN // // this method is called just before fragment is destroyed when we // change orientation @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("counter",counter ); } // MODIFIED CODE END // @Override public void onClick(View v) { counter++; // comm.respond is in the mainActivity comm.respond("Button was clicked "+counter+" times"); } }
FragmentB.java
package com.jamesfroggatt.fragments4.app; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class FragmentB extends Fragment { TextView text; String data; //link the layout (fragment_b.xml) to the fragment class @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // MODIFIED CODE BEGIN // View view= inflater.inflate(R.layout.fragment_b,container,false); if (savedInstanceState==null){ }else{ data=savedInstanceState.getString("savedData"); TextView myText=(TextView) view.findViewById(R.id.textViewInFragmentB); myText.setText(data); } return view; // MODIFIED CODE END // } // initialise the TextView in fragment b // using onActivityCreated it is save to access // the view hierarchy as Activity has been create when // this method is called @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); text= (TextView) getActivity().findViewById(R.id.textViewInFragmentB); } // MODIFIED CODE BEGIN // @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString("savedData",data); } // MODIFIED CODE END // public void changeText(String data){ text.setText(data); } }