Reputation: 922
I am following the example FragmentTabsPager under the Samples from ActionBarSherlock.
In my case, I have created a simple SherlockActivity with the TabsPager and the same code from the sample for the FragmentPagerAdapter.
I created two fragments (different classes). The first one contains just four buttons. Depending of which one is clicked, the main Activity gets a code (e.g. 1,2,3,4). I get correctly the code for the pressed button.
Now, in the second Fragment I want to draw something depending on that code, or what is the same, update dynamically its view.
I have been searched for a solution but I haven´t got anything. In this case I have this:
[MainActivity.java]
public static class TabsAdapter extends FragmentPagerAdapter
implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final TabHost mTabHost;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
[...]
@Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
I managed to update the Bundle info.args with the new value, but I don´t know how to pass it to the fragment correctly and order it to update its dynamic View.
Is this possible?
Thanks in advance.
UPDATE
Finally, I used what Sunny kindly explained. I kept an SparseArray with my Fragments so I could definitely access them as I know its position inside MainActivity:
[MainActivity.java]
//Once the user presses the button on the first fragment, the callback calls
// this function
public void onImageSelected(int iNumber){
MySecondFragment msf = (MySecondFragment)mTabsAdapter.getFragment(POS_1);
if(msf != null){
msf.setNumImage(iNumber);
msf.updateView();
}
}
And finally in MySecondFragment.java I can access my Layout components (e.g. a GridView), as they were initialized during onCreateView, so I put all the code I needed inside my updateView() method.
For instance, I update the content of a GridView:
[MySecondFragment.java]
myGridView.setBackground(getResources().getDrawable(iCode));
HTH
UPDATE 2
I have included the following code in order to save the fragments into the state bundle of the main activity. When the application changes from portrait to landscape or viceversa (it is recreated) the function getItem is not being called, so the SparseArray map is not refilled again with the necessary Fragments:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(CURRENT_TAB, mTabHost.getCurrentTabTag());
getSupportFragmentManager().putFragment(outState, MyFirstFragment.class.getName(), mTabsAdapter.getFragment(POS_1));
getSupportFragmentManager().putFragment(outState, MySecondFragment.class.getName(),
mTabsAdapter.getFragment(POS_2));
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
MyFirstFragment mff = (MyFirstFragment) getSupportFragmentManager().getFragment(savedInstanceState, MyFirstFragment.class.getName());
if(mff != null)
mTabsAdapter.setFragment(POS_1, mff);
MySecondFragment msf = (MySecondFragment) getSupportFragmentManager().getFragment(
savedInstanceState, MySecondFragment.class.getName());
if(msf != null)
mTabsAdapter.setFragment(POS_2, msf);
mTabHost.setCurrentTabByTag(savedInstanceState
.getString(CURRENT_TAB));
}
}
Also, inside the TabsAdapter class:
public Fragment getFragment(int pos) {
return map.get(pos);
}
public void setFragment (int position, Fragment fragment) {
map.put(position, fragment);
}
HTH
Upvotes: 1
Views: 9256
Reputation: 14818
anhanniballake answer might work. But This might break in future.
To actually get the fragment you can define a sparesArray in your TabAdapter class
private SparseArray<Fragment> map;
and add your fragments in this array
@Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
Fragment fragment = Fragment.instantiate(mContext, info.clss.getName(), info.args);
map.put(position, fragment);
return fragment;
}
You also need to remove the fragment from map when fragment get destroy
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
map.remove(position);
super.destroyItem(container, position, object);
}
Now define a public method in TabAdapter class which can get Fragments
public Fragment getFragment(int pos) {
return map.get(pos);
}
Now in Your Main SherlockFragementActivity you can get the instance of any fragment
MyFragment f = (MyFragment) mTabsAdapter.getFragment(1); // 1 means second fragment from left
Now call any method in your fragments using the fragment instance you got above
f.doAnyThingInMySecondFragment();
doAnyThingInMySecondFragment
must be declared public :)
Upvotes: 1
Reputation: 199880
The source for FragmentPagerAdapter shows that Fragments are given the following tag:
"android:switcher:" + viewId + ":" + id;
Where viewId
is the R.id of your ViewPager
and id
is the page number.
Therefore you can retrieve the second page's Fragment by using:
activity.getSupportFragmentManager().findFragmentByTag(
"android:switcher:" + pager.getId() + ":2")
Where pager
is your ViewPager
. You'd then want to cast that returned Fragment to whatever specific class you have, then call a method to pass in the information you need.
Upvotes: 2