How to communicate between Android Activity and Fragment

In this fragment communication tutorial, We learn how to do communication between Android Activity and Fragment.
In this tutorial we create one fragment MyFragment which extends Fragment , in this fragment we create on Interface named FragmentInteractionListener this interface contain one method onRadioButtonSelected() , this method delegate choice made by user in Fragment to Activity.
Our MainActivity implements FragmentInteractionListener show when user make choice, we can get user choice in MainActivity.
In MainActivity we save user's choice and when you reopen fragment again then we can set user
previous choice.


Let's show the Code.


MainActivity.java
package com.example.tredyprogrammer.fragmentCommunication;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import static android.widget.Toast.LENGTH_SHORT;
public class MainActivity extends AppCompatActivity
implements MyFragment.FragmentInteractionListener {
private Button button;
private boolean isFragmentShow = false;
//key for saved instance state
static final String FRAGMENT_STATE = "fragment_state";
static final String CHOICE_STATE = "user_choice";
//The radio button default choice is 2 (means no choice).
// Let's initialize the radio button choice to the default.
private int radioButtonChoice = 2;
@Override
protected void onCreate(Bundle savedInstaceState) {
super.onCreate(savedInstaceState);
setContentView(R.layout.actvity_main);
//Let's get the button for opening and closing the fragment.
button = findViewById(R.id.button_open);
//if activity returning from a configuration change,then get the
//fragment state and set the button text "open" or "close".
if (savedInstaceState != null) {
isFragmentShow = savedInstaceState.getBoolean(FRAGMENT_STATE);
radioButtonChoice = savedInstaceState.getInt(CHOICE_STATE);
if (isFragmentShow) {
//now if the fragment is displayed , change button text to "close";
button.setText("close");
}
}
//Let's set the click listener for button.
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!isFragmentShow) {
showFragment();
} else {
closeFragment();
}
}
});
}
/**
* showFragment() method call when
* user click the button to open fragment.
*/
public void showFragment() {
//create the object of MyFragment class;
MyFragment myFragment = MyFragment.newInstance(radioButtonChoice);
//get the fragmentManager and start a fragment transaction.
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
//Add the MyFragment.
fragmentTransaction.add(R.id.container, myFragment)
.addToBackStack(null).commit();
//change the button text
button.setText("close");
//set boolean flag to true,for indicate fragment is open.
showFragment = true;
}
/**
* closeMethod() called when the user clicks the button to
* close the fragment.
*/
public void closeFragment() {
//Get the fragmentManager
FragmentManager fragmentManager = getSupportFragmentManager();
//Let's check wether fragment is already showing.
MyFragment myFragment = (MyFragment) fragmentManager
.findViewById(R.id.container);
if (myFragment != null) {
//Let's create and commit the transaction to remove the fragment.
FragmentTransaction fragmentTransaction
= fragmentManager.beginTransaction();
fragmentTransaction.remove(myFragment).commit();
}
//Update the button text to "open"
button.setText("open");
//set the boolean flat to false , to indicate fragment is closed.
showFragment = false;
}
/**
* This is the FragmentInteractionListener interface
* method this method pass the user choice from fragment
* to activity and show the toast to display user choice.
*
* @param userChoice The user's radio button choice.
*/
@Override
public void onRadioButtonSelected(int userChoice) {
//save the radio button choice,to pass it back to fragment.
radioButtonChoice = userChoice
//show the toast message with radio button choice.
Toast.makeText(this, "You Choice is" + Integer.toString(userChoice), LENGTH_SHORT).show();
}
@Override
public void onSaveInstanceState(Bundle savedInstaceState) {
//Let's save the current state of fragment (true = open,false = close).
savedInstaceState.putBoolean(FRAGMENT_STATE, showFragment);
savedInstaceState.putInt(CHOICE_STATE, radioButtonChoice);
super.onSaveInstanceState(savedInstaceState);
}
}
activity_main.xml
<?xml version = "1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.tredyprogrammer.fragmentCommunication.MainActivity">
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginStart="5dp"
android:text="Trendy Programmer"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf = "parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<FrameLayout
android:id="@+id/container"
android:name="MyFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/title"
app:layout_constraintBottom_toTopOf="@id/button_open"
tools:layout="@layout/fragment_layout" />
<Button
android:id="@+id/button_open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:text="open"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_ToBottomOf="parent"
/>
</android.support.constraint.ConstraintLayout>
MyFragment.java.
package com.example.tredyprogrammer.fragmentCommunication;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioGroup;
import android.widget.TextView;
/**
* Simple subclass of Fragment,which show the Question with
* radio button choises for provide feedback,if user select "Yes"
* radio button then header text will be change to "Liked".
* And if the user selected the "No" radio button then header
* text change to "Thank you".
* the user choise will save in memory so that,when
* User open fragment again we can show previous selected choice.
*/
public class MyFragment extends Fragment {
//The radios button have three different choices.
// 0 = Yes , 1 = No And 2 = default (No choice)
public static final int YES = 1;
public static final int NO = 0;
public static final int NONE_SELECTION = 2;
// Lets initialize the choise to default (NONE)
private int radioButtonChoice = NONE;
// Let's have choise key for bundle
private static final String USER_CHOICE = "choice";
//The Listener interface for activity communication.
pravate FragmentInteractionListener
fragmentInterationListener;
public MyFragment() {
// empty public constractor
}
public interface FragmentInteractionListener {
public onRadioButtonSelected(int selectedChoice);
}
/**
* onAttach() in this callback method
* we check hosting activity has implemented
* FragmentInteractionListener interface. if hosting
* activity not implemented FragmentInteractionListener
* then we throw the exception
*/
@Override
public void onAttach(Context context) {
super.onAttech(context);
if (context instanceOf FragmentInteractionListener){
this.fragmentInterationListener = (FragmentInteractionListener) context;
}else{
throw new ClassCastException(context.toString() + "Hosting actvity does not implemented
FragmentInteractionListener interface ");
}
}
/**
* Let's create the fragment view by inflating the layout, and if the
* User's previously selected choice is found then get the choice argument
* from bundle and check the radio button accourdingly "Yes or No"
* We will use RadioGroup Listener,to get the radio button selection from user.
*
* @param inflater LayoutInflater,we will use this layout inflater to inflate view.
* @param container ViewGrop of parent view in which fragment is attach.
* @param savedInstanceState Bundle for previour state
* @return rootView
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container
, Bundle savedInstanceState) {
// Let's inflate the layout for fragment
final View mainView = inflater.inflate(R.layout.fragment_layout, container, false);
final RadioGroup radioGroupOfChoice = mainView.findViewById(R.id.radio_button_group);
// if user already made a choice then the bundle
// contains "choice".
if (getArguments().countainsKey(USER_CHOICE)) {
//user had a choice,so get the choice.
radioButtonChoice = getArgument().getInt(USER_CHOICE);
//Let's check the selected radio button.
if (radioButtonChoice != NONE_SELECTION) {
radioGroupOfChoice.check(radioGroupOfChoice.getChildAt(radioButtonChoice).getId());
}
}
//Let's set the onCheckedChanged listener on radioGroup
radioGroupOfChoice.setOnCheckedChangeListener(
new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
View checkedRadioButton = radioGroup.findViewById(checkedId);
int indexOfRadioButton = radioGroup.indexOfChild(checkeRadioButton)
TextView headerTextView =
mainView.findViewById(R.id.fragment_header_text);
switch (indexOfRadioButton) {
case YES: // User choice "Yes"
headerTextView.setText("Liked");
radioButtonChoice = YES;
fragmentInterationListener.onRadioButtonSelected(YES);
break
case NO: // User choice "No"
headerTextView.setText("Thank you");
radioButtonChoice = NO;
fragmentInterationListener.onRadioButtonSelected(NO);
break
case default: // User choice "Yes"
radioButtonChoice = NONE;
fragmentInterationListener.onRadioButtonSelected(NONE);
break
}
}
});
returm mainView;
}
public static MyFragment newInstance(int previousChoice) {
MyFragment myFragment = new MyFragment();
Bundle argument = new Bundle();
argument.putInt(USER_CHOICE, previousChoice);
myFragment.setArguments(arguments);
return fragment;
}
}
view raw MyFragment.java hosted with ❤ by GitHub
fragment_layout.xml
<?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="wrap_content"
android:background="#fff"
android:orientation="horizontal"
tools:context="com.example.tredyprogrammer.fragmentCommunication.MyFragment">
<TextView
android:id="@+id/fragment_header_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="Do you like Trendy Programmer Blog?"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium"/>
<RadioGroup
android:id="@+id/radio_button_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/radioButtonYes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="dp"
android:text="Yes"/>
<RadioButton
android:id="@+id/radioButtonNes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:text="No"/>
</RadioGroup>
</LinearLayout>

Leave you comments And Let us know you thoughts about this tutorial.
-Trendy Programmer

No comments:

Post a Comment