With FragmentManager, we can access another fragment from our current fragment by calling findFragmentByTag(<tag of target fragment>). But, what's the tag of Fragment B? I can't found any method something like setTag()!
Luckly; I found getTag() method to get the tag name of current fragment. So I create a mechanism to access the tag across fragments via the main activity, AndroidViewPagerActivity. - Call getTag() in onCreateView() of MyFragmentB. Then pass it to the main activity AndroidViewPagerActivity. When MyFragmentA need to pass something to MyFragmentB, it retrieve it from AndroidViewPagerActivity.
Modify the main activity, AndroidViewPagerActivity.java, to have a String TabFragmentB; and implement setTabFragmentB() and getTabFragmentB() to access it.
package com.exercise.AndroidViewPager;
import java.util.ArrayList;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
public class AndroidViewPagerActivity extends FragmentActivity {
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
String TabFragmentB;
public void setTabFragmentB(String t){
TabFragmentB = t;
}
public String getTabFragmentB(){
return TabFragmentB;
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewPager = new ViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);
final ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText("Fragment A"),
MyFragmentA.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Fragment B"),
MyFragmentB.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Fragment C"),
MyFragmentC.class, null);
if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
//super.onSaveInstanceState(outState);
outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
}
public static class TabsAdapter extends FragmentPagerAdapter
implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(FragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
@Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Auto-generated method stub
}
@Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
mActionBar.setSelectedNavigationItem(position);
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i=0; i<mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
@Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
@Override
public int getCount() {
return mTabs.size();
}
}
}
Modify MyFragmentA.java and /res/layout/fragment_a.xml to add a ExitText and a Butten to send something.
package com.exercise.AndroidViewPager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MyFragmentA extends Fragment {
EditText A_input;
Button A_enter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);
A_input = (EditText)myFragmentView.findViewById(R.id.a_input);
A_enter = (Button)myFragmentView.findViewById(R.id.a_enter);
A_enter.setOnClickListener(A_enterOnClickListener);
return myFragmentView;
}
OnClickListener A_enterOnClickListener
= new OnClickListener(){
@Override
public void onClick(View arg0) {
String textPassToB = A_input.getText().toString();
String TabOfFragmentB = ((AndroidViewPagerActivity)getActivity()).getTabFragmentB();
MyFragmentB fragmentB = (MyFragmentB)getActivity()
.getSupportFragmentManager()
.findFragmentByTag(TabOfFragmentB);
fragmentB.b_updateText(textPassToB);
Toast.makeText(getActivity(),
"text sent to Fragment B:\n " + TabOfFragmentB,
Toast.LENGTH_LONG).show();
}};
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment A" />
<EditText
android:id="@+id/a_input"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/a_enter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Enter to Fragment B"/>
</LinearLayout>
Modify MyFragmentB.java and /res/layout/fragment_b.xml to receive something.
package com.exercise.AndroidViewPager;
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.TextView;
import android.widget.Toast;
public class MyFragmentB extends Fragment {
TextView b_received;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_b, container, false);
b_received = (TextView)myFragmentView.findViewById(R.id.b_received);
String myTag = getTag();
((AndroidViewPagerActivity)getActivity()).setTabFragmentB(myTag);
Toast.makeText(getActivity(),
"MyFragmentB.onCreateView(): " + myTag,
Toast.LENGTH_LONG).show();
return myFragmentView;
}
public void b_updateText(String t){
b_received.setText(t);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment B" />
<TextView
android:id="@+id/b_received"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
android:src="@drawable/ic_launcher"/>
</LinearLayout>
Download the files.
Next:
- AsyncTask run in background thread of a invisible Fragment of ViewPager
Please notice:
This exercise aim to demonstrate how to communicate between Fragments in ViewPager. But, you have to take care about live-cycle of the Fragments. For example, may be the target Fragment have not yet created when data is passed. Or, the Fragment have been destroyed after data passed. Read more: Life cycle of Fragments in ViewPager.
19 comments:
great post!
i have a quick question, how do i send my activity values to say FragmentB string? getActivity() doesn't seems to work in activity class file.
Hello I have a problem with our method. When I try to send any information to fragment B and it's ok but when I try to send any information to fragment C with the same method the program bug and stoped. Can you help me for this problem?
Hello ligol,
It's problem of life-cycle of Fragments. Please read Life cycle of Fragments in ViewPager.
Thanks,
It's nice.Work for the me.
This solution is INGENIOUS. I have been trying to solve a problem with using FragmentASDF.method() not being able to be static (but that function call requires it). This solution helped fix that! Thank you so much!
200 lines of code just to send one String :) nice
getTag() is always null for me, any body know why ? thanks
In Build Paths, delete the reference to
android-support-v4.jar- /home/eric/android....(missing)
for the download to work.
Delete the reference to
android-support-v4.jar- /home/eric/android....(missing)
for the download to work.
I have an error on mViewPager.setId(R.id.pager);
cant find the "pager"
Thank you for Helpful tutorial to communicate between fragments without using interfaces
Hello!
When I click the button not only data but also screen move to next screen, can u give me code?
ViewPager example, with switching page programmatically
if want to add more questional bottons, how should I do?
Thank you very much!
hi, if I want to pass a data(.kml file) how can i do??
Thanks
Is it possible to send and receive data from one fragment to other in Navigationdrawer?
i have 2 fragments in Navigationdrawer.I am trying to send data from one fragment to other.. ...can u please tell me how to do it?
Implementing this code to my app does not show text in next fragment. any reason ?
WOW DUDE this worked like a charm
Post a Comment