In this tutorial, we’ll be developing an application that contains TabLayout, ViewPager, and Fragments. We’ll implement functionality that passes data from one Fragment to the other fragment.
Table of Contents
- 1 Android Passing Data between Fragments
- 1.1 Android Passing Data between Fragments Project Structure
Android Passing Data between Fragments
Intents are only usable for sending data on an Activity level. To pass data between fragments we need to create our own interfaces. The flow to send a String data from one Fragment to another is shown below.
Let’s get started with the implementation of the above flow.
Let’s get started with the implementation of the above flow.
Android Passing Data between Fragments Project Structure
The XML layout for the MainActivity.java class is given below.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.journaldev.passingdatabetweenfragments.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
style="@style/MyStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"
app:tabMode="fixed" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
The styles for the TabLayout and ToolBar are defined in the styles.xml file as shown below.
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
<style name="MyStyle" parent="Widget.Design.TabLayout">
<item name="tabIndicatorColor">#FFFF</item>
<item name="tabIndicatorHeight">5dp</item>
<item name="tabPaddingStart">8dp</item>
<item name="tabPaddingEnd">8dp</item>
</style>
</resources>
The ViewPagerAdapter.java is where the Fragments are initialized. The code is given below.
public class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
fragment = new FragmentOne();
} else if (position == 1) {
fragment = new FragmentTwo();
}
return fragment;
}
@Override
public int getCount() {
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
String title = null;
if (position == 0) {
title = "Tab-1";
} else if (position == 1) {
title = "Tab-2";
}
return title;
}
}
FragmentOne would be sending the data entered in EditText to FragmentTwo.
The XML layout for fragment_one.xml is given below.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/inMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/btnPassData"
android:layout_margin="16dp"
android:hint="Enter here" />
<Button
android:id="@+id/btnPassData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="PASS DATA TO FRAGMENT TWO" />
</RelativeLayout>
</ScrollView>
The XML layout for fragment_two.xml is given below.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/txtData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_centerInParent="true"
android:text="No data received" />
</RelativeLayout>
The code for the FragmentOne.java class is given below.
package com.journaldev.passingdatabetweenfragments;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
public class FragmentOne extends Fragment {
SendMessage SM;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.fragment_one, container, false);
return rootView;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Button btnPassData = (Button) view.findViewById(R.id.btnPassData);
final EditText inData = (EditText) view.findViewById(R.id.inMessage);
btnPassData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SM.sendData(inData.getText().toString().trim());
}
});
}
interface SendMessage {
void sendData(String message);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
SM = (SendMessage) getActivity();
} catch (ClassCastException e) {
throw new ClassCastException("Error in retrieving data. Please try again");
}
}
}
The Custom Interface namely
SendMessage
is initialised in the onAttach
method above. This interface would be implemented in the MainActivity.java that we’ll be seeing shortly.
The code for FragmentTwo.java class is given below.
package com.journaldev.passingdatabetweenfragments;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class FragmentTwo extends Fragment {
TextView txtData;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.fragment_two, container, false);
return rootView;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
txtData = (TextView)view.findViewById(R.id.txtData);
}
protected void displayReceivedData(String message)
{
txtData.setText("Data received: "+message);
}
}
The
displayReceivedData()
would be called on the instance of FragmentTwo.java from inside the Custom Interface’s method inside the MainActivity.java as shown below.
package com.journaldev.passingdatabetweenfragments;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
public class MainActivity extends AppCompatActivity implements FragmentOne.SendMessage{
TabLayout tabLayout;
ViewPager viewPager;
ViewPagerAdapter viewPagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(viewPagerAdapter);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
@Override
public void sendData(String message) {
String tag = "android:switcher:" + R.id.viewPager + ":" + 1;
FragmentTwo f = (FragmentTwo) getSupportFragmentManager().findFragmentByTag(tag);
f.displayReceivedData(message);
}
}
The
sendData()
a method in the above code gets triggered as soon as the Button in FragmentOne is pressed. We fetch the FragmentTwo that was already initialized in ViewPagerAdapter using the method findFragmentByTag.
The output of the above application in action is given below.
0 Comments