save instance in FragmentTabHost - android

I have a project where I used FragmentTabHost with inner fragment with FragmentTabHost
Main FragmentActivity
-FragmentTabHost
-TAB 1 - FragmentTabHost
-tab 1 Fragment
-tab 2 Fragment
-TAB 2 - Fragment
-TAB 3 - FragmentTabHost
-TAB 4 - Fragment
when I switch tab2 to tab1 in first TAB1 of main FragmentTabHost their instances always rebuild and I call API method, but i just want to show 'old' results.
How can I save instance of this fragments and dont make any additional query to API?
some snips of code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab_layout, container, false);
mTabHost = (FragmentTabHost) rootView.findViewById(android.R.id.tabhost);
mTabHost.setup(context, getChildFragmentManager(), R.id.tabContent);
......
mTabHost.addTab(mTabHost.newTabSpec("fragment1").setIndicator(viewLeft),
FragmentTab1.class, new Bundle(0));
UPD1. I tried to add
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
java.lang.IllegalStateException: Can't retain fragements that are nested in other fragments
at android.support.v4.app.Fragment.setRetainInstance(Fragment.java:784)

If you do not want to rebuild the instance of any tab, just take the response object of API as a global variable & make a check in onCreateView
YourResponseObject yourResponseObject; //this should be global
if(YourResponseObject == null){
// Hit API here
}else
{
InflateYourData(YourResponseObject)
}
you will be able to retain the instance of the tab.

Related

ViewPager/FragmentPageAdapter, after recreation, does not call onCreate() of last selected view

I am currently working on an application with ActionBar tabs inside one of its fragments (main navigation is NavigationDrawer). The fragment's onCreate():
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
actionBar = activity.getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Resources r = getResources();
//(…) tabNames initialization
adapter = new CustomTabAdapter(getFragmentManager());
}
and onCreateView():
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment, container, false);
viewPager = (ViewPager) rootView.findViewById(R.id.pager);
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(this);
for (String tabName : tabNames) {
actionBar.addTab(actionBar.newTab()
.setText(tabName)
.setTabListener(this));
}
return rootView;
}
There are 4 tabs, each of them with its own Fragment and layout. CustomTabAdapter returns new instance of proper fragment in its getItem(int). There are 4 tabs.
And now my problem is:
I start the application.
I choose this tab fragment from NavigationDrawer list. Everything is working just fine.
I choose another fragment from NavigationDrawer list which means that tab fragment is replaced with it.
I choose tab fragment again. And fragment related to tab that was selected before choosing another fragment from NavigationDrawer list, and one's adjacent to it are not recreated (blank screen under ActionBar tabs). I checked and onCreateView(…) methods of those fragment are not called. So after changing device orientation, or choosing tab not adjacent and this one again proper layout is shown.
How can I make it work as it should (showing proper layout on reentering tab fragment from NavigationDrawer list instead of blank space)? I run out of ideas.
Finally, I found a solution. My CustomTabAdapter was extension of FragmentPagerAdapter. I changed it to be extension of FragmentStatePageAdapter, and now fragments are recreated.
More details in this answer by #Louth.
It takes fragments from cache without recreation

Android FindFragmentByTag returns null in FragmentTabHost

I am trying to retrieve a fragment from my fragmentTabHost:
private void initView() {
FragmentTabHost mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("summary").setIndicator("Summary"),
SummaryActivity.class, bundle);
SummaryActivity summaryActivity = (SummaryActivity) getSupportFragmentManager().findFragmentByTag("summary");
System.out.println(summaryActivity);
}
When I try to get my fragment immediately after it was created, it returns null. It could be a thread issue. How, or even when, should I call getFragmentByTag to retrieve my fragment in this case?
The Fragment you are looking for is not in the stack. It is not even added/present at the time you are finding it back.
findFragmentByTag method will look and match last fragment that added in the transaction, if that is not matching with the required one, then it will search with the available list from history. Finally if your tag is not there with any fragments it will return null.
Make sure that , you are adding the Fragment to the view first.
the view should receive the fragment/tabhost to make it available in the lifecycle.
you have to return your tabHost to the view to add the fragment before you do findFragmentByTag lookup.
For ex:
You are in your Fragment's onCreateView then you should do return the tabhost to the view after you inflated it.
onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mTabHost = new FragmentTabHost(getActivity());
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.fragment1);
mTabHost.addTab(mTabHost.newTabSpec("fragmenttag").setIndicator("Fragmenttag"),
FragmentStackSupport.CountingFragment.class, null);
return mTabHost;
}
Then probably your Fragment will be available in back stack , you can get it back by Tag.
Fragment Tags can only be set during fragment transactions. The tab host tag refers to something else. Try using findFragmentById() if you set an id on the fragments root view.

In Tab bar to go an other fragment in the same tab?

I am using FragmentAcitvity in my Tab Bar .
I am able to load a new fragment on tab changed.
But i have a problem Because i have many activties in one tab.
for example i have 2 tabs :
Tab1 , Tab2. and i have in
Tab1 : activityA-->activityB---ActivityC
and
Tab2: activityF
how i can achieve this.
my code is here.
Main Class
public class MainActivity extends FragmentActivity {
private FragmentTabHost mTabHost;
Context context=this;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(context, getSupportFragmentManager(), android.R.id.tabcontent);
mTabHost.addTab(
mTabHost.newTabSpec("Records").setIndicator("")), ActiovityA.class, null);
mTabHost.addTab(
mTabHost.newTabSpec("tab2").setIndicator("tab2"),acitvityf.class, null);
mTabHost.setCurrentTab(0);
}
}
my acitvityA is here
public class acitvityA extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.acitvitya_xml, container, false);
return v;
}
}
myactivityB is
public class acitvityb extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.acitvityb_xml, container, false);
return v;
}
}
how i can solve this ?what is missing here.
You might have to do a little bit of homework yourself, but i could give you a hint that could help you.
You have the tabs set well. What you could do is, When the transition from Activity1 to 2 takes place, hide the last fragment from the stack, and then show the Activity 2 fragment in tab one (here you will push the fragment into the stack and show it). Maintain a stack of the fragments you are using, and compare an instance of which fragment has been pushed or popped from the stack to bring back the correct fragment.
Its a combination of fragment transactions add, hide, and stack push and pop.
Stack is needed for back press events.
Hope that helps.

findFragmentByTag - looking for fragment in FragmentTabHost - always null

I'm having trouble getting a pointer to a Fragment which is the currently visible fragment in a FragmentTabhost.
I have a SherlockFragmentActivity called SecondActivity that loads the Tabhost from it's onCreate method like this:
if (getSupportFragmentManager().findFragmentById(android.R.id.content) == null) {
Fragment f = new TabsFragment();
getSupportFragmentManager().beginTransaction().add(android.R.id.content, f, "tabsfragment").commit();
}
TabsFragment is a SherlockFragment subclass with this onCreate method to create the tabs
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mTabHost = new FragmentTabHost(getActivity());
mTabHost.setup(getActivity(), getChildFragmentManager(), R.layout.tabs);
mTabHost.addTab(mTabHost.newTabSpec("Tab1").setIndicator("Offers",
getResources().getDrawable(R.drawable.offersale)),
OfferListFragment.class,
null);
mTabHost.addTab(mTabHost.newTabSpec("Tab2").setIndicator("News",
getResources().getDrawable(R.drawable.newspaper)),
NewsFragment.class,
null);
return mTabHost;
}
Now when i'm in the 2nd tab, I have a background task done in a class that is initiated by the original activity SecondActivity, then I call this which is supposed to give me a reference to the tab, but it always returns null!
NewsFragment newsView = (NewsFragment) delegate.getSupportFragmentManager().findFragmentByTag("Tab2");
The delegate variable is a pointer back to SecondActivity when it starts the background class.
How do I get a pointer to the tab's fragment?
Am I wrong that "Tab2" set when adding the tabs is the Tag for the fragment?
I don't really like answering my own questions, but it's amazing what sleeping on it can do.
This monster gives me a pointer to the fragment in the tabhost
NewsFragment newsView = (NewsFragment) delegate
.getSupportFragmentManager()
.findFragmentByTag("tabsfragment")
.getChildFragmentManager()
.findFragmentByTag("Tab2");

Assign Content to Tabs in a Fragment - Android

Just created a new project in the newest ADT release in Eclipse and found that it will setup up certain environments for you to get things started. I choose Tabs + Swipe.
It has this code I have question on:
public static class DummyFragment extends Fragment {
public DummyFragment () {
}
public static final String ARG_SECTION_NUMBER = "section_number";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView textView = new TextView(getActivity());
textView.setGravity(Gravity.CENTER);
Bundle args = getArguments();
textView.setText(Integer.toString(args.getInt(ARG_SECTION_NUMBER)));
return textView;
}
}
Both tabs refer to this same fragment. All it does is switch the content on the TextView that has the tab position number on it (1,2, or 3).
The more advanced question first: I want two different Fragments that the tab switches to. In the example code, it points to the same fragment. Where does this change take place? and can I see brief code example?
Easier question: I have two pre-defined XML layouts I'd like to set each tab (or Fragment) with. Do I do this in the actual Fragment? And if so, where? setContentView does't seem to be working in the onCreateView method?
Not really sure what this question is asking exactly, but if I understand correctly the TabHost (or whatever you are using to manage the Fragment tabs) is instantiating multiple instances of the DummyFragment and then attaching each to the screen when a tab is clicked. This is all done behind the scenes... all you need to worry about is implementing the Fragment and telling the TabHost when it should be instantiated/displayed.
Fragments don't have a setContentView method. You should inflate your Fragment's layout from xml in onCreateView. For instance with,
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_layout, container, false);
}

Categories

Resources