Fragment to Fragment communication with FragmentStatePagerAdapter - android

I'm trying to update the text of my TextView in my FragmentB through the Button in my FragmentA. But whenever I click the Button, nothing happens in my TextView. What could be the problem? Here's my code:
Communicator.java:
public interface Communicator {
public void respond(String data);
}
MainActivity.java:
public class MainActivity extends FragmentActivity implements Communicator{
ViewPager viewPager = null;
FragmentManager fragmentManager = getSupportFragmentManager();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(new MyAdapter(fragmentManager));
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FragmentB fragB = new FragmentB();
fragmentTransaction.add(R.id.pager, fragB, "frag_tag");
fragmentTransaction.commit();
}
public class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter (FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment = null;
if (i == 0)
{
fragment = new FragmentA();
}
if (i == 1)
{
fragment = new FragmentB();
}
if (i == 2)
{
fragment = new FragmentC();
}
if (i == 3)
{
fragment = new FragmentD();
}
if (i == 4)
{
fragment = new FragmentE();
}
if (i == 5)
{
fragment = new FragmentF();
}
return fragment;
}
#Override
public int getCount() {
return 6;
}
}
#Override
public void respond(String data) {
// TODO Auto-generated method stub
FragmentB f2 = (FragmentB) fragmentManager.findFragmentByTag("frag_tag");
f2.changeText(data);
}
}
FragmentA:
public class FragmentA extends Fragment implements OnClickListener {
int counter = 0;
Button button1;
Communicator comm;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragmenta, container, false);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
comm = (Communicator) getActivity();
button1 = (Button) getActivity().findViewById(R.id.button1);
button1.setOnClickListener(this);
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
counter++;
comm.respond("The button was clicked" + counter + "times");
}
}
FragmentB:
public class FragmentB extends Fragment {
TextView text1;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragmentb, container, false);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
text1 = (TextView) getActivity().findViewById(R.id.textView1);
}
public void changeText(String data) {
// TODO Auto-generated method stub
text1.setText(data);
}
}

The host activity can deliver messages to a fragment by capturing the Fragment instance with findFragmentById(), then directly call the fragment's public methods.
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
ArticleFragment articleFrag = (ArticleFragment)
getSupportFragmentManager().findFragmentById(R.id.article_fragment);
if (articleFrag != null) {
// If article frag is available, we're in two-pane layout...
// Call a method in the ArticleFragment to update its content
articleFrag.updateArticleView(position);
} else {
// Otherwise, we're in the one-pane layout and must swap frags...
// Create fragment and give it an argument for the selected article
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
}
For more detail please follow this link http://developer.android.com/training/basics/fragments/communicating.html#Deliver

Related

How to add backstack to viewpager with fragmentManager and FragmentPagerAdapter

How to add backstack to viewpager
How do we manage to go to previous fragment from the current fragment
I have got the fragment part working , now I am trying to learn to manage the naviation of fragments by the back button
Here is the main activity which contains three fragments
public class MainActivity extends FragmentActivity {
ViewPager viewpager = null;
LinearLayout lay;
#Override
protected void onCreate(Bundle savedInstancestate) {
// TODO Auto-generated method stub
super.onCreate(savedInstancestate);
setContentView(R.layout.activity_main);
viewpager = (ViewPager) findViewById(R.id.pager);
viewpager.setPageTransformer(true, new DepthPageTransformer());
FragmentManager fragmentManager = getSupportFragmentManager();
viewpager.setAdapter(new myAdaper(fragmentManager));
PagerTitleStrip pagerTitleStrip = (PagerTitleStrip)findViewById(R.id.pager_title_strip);
pagerTitleStrip.setTextSize(TypedValue.COMPLEX_UNIT_SP, 24);
// pagerTitleStrip.setTextColor(Color.BLUE);
}
class myAdaper extends FragmentPagerAdapter {
public myAdaper(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
#Override
public Fragment getItem(int i) {
// TODO Auto-generated method stub
Fragment fragment = null;
if (i == 0) {
fragment = new fragmentA();
}
if (i == 1) {
fragment = new fragmentB();
}
if (i == 2) {
fragment = new fragmentC();
}
return fragment;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
String title = new String();
SpannableStringBuilder sb = new SpannableStringBuilder(""+ position);
if (position == 0) {
return "Tab1";
}
if (position == 1) {
return "Tab2";
}
if (position == 2) {
return "Tab3";
}
return null;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
// TODO Auto-generated method stub
}
And the fragments are
public class fragmentA extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.fragment_a,container, false);
}
}
these are repeated with same code just diff color for the other two fragments fragment B and fragment C
now if
I am on fragment C i want ot go back to fragment B and
if I am on Fragment B i want to go to Fragment A
Store in a variable wich is your current page (you can get it with the ViewPager.OnPageChangeListener). Then override the onBackPressed()method of your activity and change to the previous of your viewpager with setCurrentItem(int item)
If you are in the first fragment just call super.onBackPressed()

Facebook like dynamic viewpager

I am trying to create facebook like viewpager (swipable tabs and proper backstack) I can create swipable tabs but cant handle the proper back navigation. Bellow is my code
public class MainActivity extends FragmentActivity {
private ViewPager mPager;
// private SlidePagerAdapter mPagerAdapter;
private MyPagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Instantiate a ViewPager and a PagerAdapter. */
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
mPager.setOffscreenPageLimit(4);
}
#Override
public void onBackPressed() {
Fragment currentVisibleFragment = mPagerAdapter.getRegisteredFragment(mPager.getCurrentItem());
if (currentVisibleFragment != null && currentVisibleFragment.isVisible()) {
FragmentManager childFm = currentVisibleFragment.getChildFragmentManager();
System.out.println("============================================");
System.out.println("childFm.getBackStackEntryCount()=== " + childFm.getBackStackEntryCount());
System.out.println("============================================");
if (childFm.getBackStackEntryCount() > 0) {
childFm.popBackStack();
return;
}
}
super.onBackPressed();
}
}
Adapter of my class is as bellow
public class MyPagerAdapter extends SmartFragmentStatePagerAdapter {
private static int NUM_ITEMS = 3;
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages
#Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
#Override
public Fragment getItem(int position) {
switch (position) {
case 0: // Fragment # 0 - This will show FirstFragment
return new FragmentA();
case 1: // Fragment # 0 - This will show FirstFragment different title
return new FragmentB();
case 2: // Fragment # 1 - This will show SecondFragment
return new FragmentC();
default:
return null;
}
}
// Returns the page title for the top indicator
#Override
public CharSequence getPageTitle(int position) {
return "Page " + position;
}
}
here is the exteded adapter
public abstract class SmartFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
// Sparse array to keep track of registered fragments in memory
private SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public SmartFragmentStatePagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Register the fragment when the item is instantiated
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
// Unregister when the item is inactive
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
// Returns the fragment for the position (if instantiated)
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
and Fragments are as bellow
public class FragmentA extends Fragment {
public static final String TAG = "FragmentA";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.first_fragment, container, false);
Button btn = (Button) view.findViewById(R.id.btn);
btn.setText(TAG);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction trans = getChildFragmentManager().beginTransaction();
/*
* IMPORTANT: We use the "root frame" defined in
* "root_fragment.xml" as the reference to replace fragment
*/
trans.replace(R.id.framelayout_infragment_one, new FragmentA1());
/*
* IMPORTANT: The following lines allow us to add the fragment
* to the stack and return to it later, by pressing back
*/
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
trans.commit();
}
});
return view;
}
}
public class FragmentA1 extends Fragment {
public static final String TAG = "FragmentA1";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.first_fragment, container, false);
view.setBackgroundColor(Color.RED);
Button btn = (Button) view.findViewById(R.id.btn);
btn.setText(TAG);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction trans = getChildFragmentManager().beginTransaction();
/*
* IMPORTANT: We use the "root frame" defined in
* "root_fragment.xml" as the reference to replace fragment
*/
trans.replace(R.id.framelayout_infragment_one, new FragmentA2());
/*
* IMPORTANT: The following lines allow us to add the fragment
* to the stack and return to it later, by pressing back
*/
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
trans.commit();
}
});
return view;
}
}
//second inner fragment
public class FragmentA2 extends Fragment {
public static final String TAG = "FragmentA2";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.second_fragment, container, false);
view.setBackgroundColor(Color.GRAY);
Button btn = (Button) view.findViewById(R.id.btn);
btn.setText(TAG);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction trans = getFragmentManager().beginTransaction();
trans.replace(R.id.root_frame, new FragmentC());
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
trans.commit();
}
});
return view;
}
}
When I am going to frament A2 expected behaviour when user press back is I want to go to Frament A1 but I am going to Frament A. Fragment B,B1,B2 are same as A A1 A2 resp...
Please help
I managed it by maintaining stacks by myself
public static HashMap<String, Stack<Fragment>> mStacks;
mStacks = new HashMap<String, Stack<Fragment>>();
mStacks.put("TAB1", new Stack<Fragment>());
mStacks.put("TAB2", new Stack<Fragment>());
mStacks.put("TAB3", new Stack<Fragment>());
mStacks.put("TAB4", new Stack<Fragment>());
//when starting new fragment add that to stack like this
public void pushFragments(Fragment fragment) {
setSelectedPageN(pager.getCurrentItem());
mStacks.get(ApplicationConstants.CURRENT_TAB).push(fragment);
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
if (ApplicationConstants.CURRENT_TAB.equals("TAB1")) {
ft.replace(R.id.container_feed, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals("TAB2")) {
ft.replace(R.id.container_chart, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals("TAB3")) {
ft.replace(R.id.container_explore, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals("TAB4")) {
ft.replace(R.id.container_profile, fragment);
}
ft.commit();
}
//When you want to finish
public void popFragments() {
/*
* Select the second last fragment in current tab's stack.. which will
* be shown after the fragment transaction given below
*/
setSelectedPageN(pager.getCurrentItem());
Fragment fragment = mStacks.get(ApplicationConstants.CURRENT_TAB).elementAt(mStacks.get(ApplicationConstants.CURRENT_TAB).size() - 2);
if (fragment instanceof ProfileContainerFragment) {
fragment = new ProfileFragment();
} else if (fragment instanceof FeedNewUserGuideline && !isShowFeedTutorial) {
fragment = new FeedFragment();
}
/* pop current fragment from stack.. */
mStacks.get(ApplicationConstants.CURRENT_TAB).pop();
/*
* We have the target fragment in hand.. Just show it.. Show a standard
* navigation animation
*/
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.setCustomAnimations(R.anim.abc_fade_in, R.anim.abc_fade_out);
if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_FEED)) {
ft.replace(R.id.container_feed, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_CHART)) {
ft.replace(R.id.container_chart, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_EXPLORE)) {
ft.replace(R.id.container_explore, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_PROFILE)) {
ft.replace(R.id.container_profile, fragment);
}
ft.commit();
}
//When user back press
#Override
public void onBackPressed() {
try {
if (((BaseFragment) mStacks.get(ApplicationConstants.CURRENT_TAB).lastElement()).onBackPressed() == false) {
switch (pager.getCurrentItem()) {
case KeyConstants.POSITION_ONE_FEED:
if (mStacks.get(ApplicationConstants.TAB_FEED).size() == 1) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
this.finish();
// super.onBackPressed(); // or call finish..
} else {
popFragments();
}
break;
case KeyConstants.POSITION_TWO_CHART:
if (mStacks.get(ApplicationConstants.TAB_CHART).size() == 1) {
pager.setCurrentItem(KeyConstants.POSITION_ONE_FEED);
} else {
popFragments();
}
break;
case KeyConstants.POSITION_THREE_EXPLORE:
if (mStacks.get(ApplicationConstants.TAB_EXPLORE).size() == 1) {
pager.setCurrentItem(KeyConstants.POSITION_TWO_CHART);
} else {
popFragments();
}
break;
case KeyConstants.POSITION_FOUR_PROFILE:
if (mStacks.get(ApplicationConstants.TAB_PROFILE).size() == 1) {
pager.setCurrentItem(KeyConstants.POSITION_THREE_EXPLORE);
} else {
popFragments();
}
break;
default:
break;
}
} else {
// do nothing.. fragment already handled back button press.
}
} catch (Exception e) {
e.printStackTrace();
}
}

Nested Fragments with Fragment Pager Adapter [duplicate]

I have an application that uses ActionBarSherlock and inside the main fragment I have a ViewPager which uses several fragments to display different objects of a list.
Main Fragment:
public class CollectionDemoFragment extends SherlockFragment {
DemoCollectionPagerAdapter mDemoCollectionPagerAdapter;
ViewPager mViewPager;
public CollectionDemoFragment() {
setTitle(R.string.title);
setHasOptionsMenu(true);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.demo_fragment, container, false);
mDemoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mDemoCollectionPagerAdapter);
return view;
}
#Override
public void onPause() {
//This runs when the fragment goes to backstack
super.onPause();
}
#Override
public void onResume() {
//This runs when the fragment returns from backstack
super.onResume();
}
}
ViewPagerAdapter:
public class DemoCollectionPagerAdapter extends
FragmentStatePagerAdapter {
public DemoCollectionPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment = new DemoObjectFragment();
Bundle args = new Bundle();
args.putInt(DemoObjectFragment.ARG_OBJECT, i + 1);
fragment.setArguments(args);
return fragment;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public int getCount() {
return 100;
}
#Override
public CharSequence getPageTitle(int position) {
return "OBJECT " + (position + 1);
}
}
Inside each of this fragments I can create a new Main fragment with a new list to display in the ViewPager and replace the content with this new fragment.
ViewPager Fragments:
public static class DemoObjectFragment extends Fragment {
public static final String ARG_OBJECT = "object";
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.fragment_collection_object, container, false);
Bundle args = getArguments();
((TextView) rootView.findViewById(android.R.id.text1)).setText(
Integer.toString(args.getInt(ARG_OBJECT)));
//Setup components
return rootView;
}
#Override
public void setMenuVisibility(final boolean visible) {
if (visible) {
//Do something
}
super.setMenuVisibility(visible);
}
#Override
public void onPause() {
//This should run when the fragment goes to backstack
super.onPause();
}
#Override
public void onResume() {
//This should run when the fragment returns from backstack
super.onResume();
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.someComponent:
Fragment newContent = new CollectionDemoFragment();
switchContent(newContent, true);
break;
}
}
public void switchContent(Fragment newContent, boolean addToBackStack) {
if (newContent != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
ft.replace(R.id.content_frame, newContent);
if (addToBackStack) {
ft.addToBackStack("" + newContent.getId());
}
ft.commit();
}
}
}
This works ok, until I press back and the previous main fragment returns from the backstack.
The screen is empty (since onCreateView is not called the layout is not inflated), the lifecycle methods from the fragments in the ViewPager are never called either when the main fragment enters the backstack, nor when it returns .
The only method called in the fragments of the ViewPager is the setMenuVisibility() so, only the code in there runs.
Anyone knows a way to fix this and why this happens?
Not sure if it matters but I have to support since android 2.3.
When you are creating the view adapter You have to pass the fragment child manager as argument - getChildFragmentManager() instead of getFragmentManager().
Instead of,
mDemoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getFragmentManager());
you should use,
mDemoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getChildFragmentManager());

How could I get view of one fragment while add this fragment to an Activity

I have one FragmentActivity and a Fragment, well, now I want to add this fragment to the Activity programmatically, and I also want to update value of one TextView. but I keep getting NullPointException.
Need some help here... :(
this is my code:
public class NewsDetailsFragment extends Fragment {
private View _currentview = null;
public View getCurrentView() {
return _currentview;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
_currentview = inflater.inflate(R.layout.newsdetails_layout, container,
false);
Button b = (Button) _currentview.findViewById(R.id.btnReplace);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction transaction = getFragmentManager()
.beginTransaction();
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
transaction.replace(R.id.landscapeLayout,
new ReplacementFragment(), "replace");
} else {
transaction.replace(R.id.newsdetailsPortrait,
new ReplacementFragment(), "replace");
}
transaction.addToBackStack(null);
transaction.commit();
}
});
return _currentview;
}
public void setNewsContent(String content) {
TextView lblNewsContent = (TextView) getView().findViewById(
R.id.lblNewsContent);
lblNewsContent.setText(content);
lblNewsContent.setTextColor(Color.CYAN);
}
}
This is the FragmentActivity:
public class NewsDetailsActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.newsdetailsactivity_layout);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
finish();
return;
}
// setContentView(R.layout.newsdetails_layout);
NewsDetailsFragment detailsFragment = new NewsDetailsFragment();
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
transaction.add(R.id.newsdetailsPortrait, detailsFragment,
"newsdatails");
String newString = getIntent().getStringExtra("news");
if (null != newString) {
TextView t = (TextView) detailsFragment.getView().findViewById(
R.id.lblNewsContent);
t.setText(newString);
t.setTextColor(Color.GREEN);
}
transaction.commit();
}
}
Thanks in advance! :)

ActionBarSherlock with ViewPager not calling ViewPager fragments lifecycle methods when going to and returning from backstack

I have an application that uses ActionBarSherlock and inside the main fragment I have a ViewPager which uses several fragments to display different objects of a list.
Main Fragment:
public class CollectionDemoFragment extends SherlockFragment {
DemoCollectionPagerAdapter mDemoCollectionPagerAdapter;
ViewPager mViewPager;
public CollectionDemoFragment() {
setTitle(R.string.title);
setHasOptionsMenu(true);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.demo_fragment, container, false);
mDemoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mDemoCollectionPagerAdapter);
return view;
}
#Override
public void onPause() {
//This runs when the fragment goes to backstack
super.onPause();
}
#Override
public void onResume() {
//This runs when the fragment returns from backstack
super.onResume();
}
}
ViewPagerAdapter:
public class DemoCollectionPagerAdapter extends
FragmentStatePagerAdapter {
public DemoCollectionPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment = new DemoObjectFragment();
Bundle args = new Bundle();
args.putInt(DemoObjectFragment.ARG_OBJECT, i + 1);
fragment.setArguments(args);
return fragment;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public int getCount() {
return 100;
}
#Override
public CharSequence getPageTitle(int position) {
return "OBJECT " + (position + 1);
}
}
Inside each of this fragments I can create a new Main fragment with a new list to display in the ViewPager and replace the content with this new fragment.
ViewPager Fragments:
public static class DemoObjectFragment extends Fragment {
public static final String ARG_OBJECT = "object";
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.fragment_collection_object, container, false);
Bundle args = getArguments();
((TextView) rootView.findViewById(android.R.id.text1)).setText(
Integer.toString(args.getInt(ARG_OBJECT)));
//Setup components
return rootView;
}
#Override
public void setMenuVisibility(final boolean visible) {
if (visible) {
//Do something
}
super.setMenuVisibility(visible);
}
#Override
public void onPause() {
//This should run when the fragment goes to backstack
super.onPause();
}
#Override
public void onResume() {
//This should run when the fragment returns from backstack
super.onResume();
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.someComponent:
Fragment newContent = new CollectionDemoFragment();
switchContent(newContent, true);
break;
}
}
public void switchContent(Fragment newContent, boolean addToBackStack) {
if (newContent != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
ft.replace(R.id.content_frame, newContent);
if (addToBackStack) {
ft.addToBackStack("" + newContent.getId());
}
ft.commit();
}
}
}
This works ok, until I press back and the previous main fragment returns from the backstack.
The screen is empty (since onCreateView is not called the layout is not inflated), the lifecycle methods from the fragments in the ViewPager are never called either when the main fragment enters the backstack, nor when it returns .
The only method called in the fragments of the ViewPager is the setMenuVisibility() so, only the code in there runs.
Anyone knows a way to fix this and why this happens?
Not sure if it matters but I have to support since android 2.3.
When you are creating the view adapter You have to pass the fragment child manager as argument - getChildFragmentManager() instead of getFragmentManager().
Instead of,
mDemoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getFragmentManager());
you should use,
mDemoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getChildFragmentManager());

Categories

Resources