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.
Related
I am developing an application where i need to call two fragments on an activity replacing another fragment,one of the fragment will contain a Form and another fragment will contain another Form ,i don't have any idea how to do this,so any suggestion will be cordially appreciated,thanks in advance....
I want to replace Form on Click button. by R&D i come to know at this point i need to use to fragment with two layout each layout will contain Forms.
Main Activity.
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Fragment 1.
public class Fragment1 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment1, container, false);
}
Fragment 2.
public class Fragment2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment2, container, false);
}
}
You can try like this
FragmentTransaction ft=getSupportFragmentManager().beginTransaction();
ft.add(Home.newInstance(),"First");
ft.add(Second.newInstance(),"Second");
ft.commit();
So here you are added multiple fragment into the stack
If you are trying to replace Fragment1 with Fragment2, you replace the fragment.
https://developer.android.com/reference/android/support/v4/app/FragmentTransaction.html#replace(int,%20android.support.v4.app.Fragment)
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.
I have created a MainActivity which consists of 3 tabs which are scrollable (by using ViewPager). Now each of these 3 tabs is a Fragment. Also, I am using ActionBarSherlock (ABS).
For the 1st Fragment, I have created the following class:
public class Fragment_1 extends SherlockFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View v = inflater.inflate(R.layout.fragment1, container, false);
return v;
/* R.layout.fragment1 only contains a TextView. */
}
}
For the 2nd Fragment, I want to extend a FragmentActivity as shown below.
public class Fragment_2 extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment2);
}
}
The 3rd Fragment is same as the first one.
But when I launch the app, it crashes. So, am I wrong in extending FragmentActivity for the class Fragment_2? Is it illegal to extend a FragmentActivity or even an Activity to fragment classes? If not, what is the problem here?
Thanks.
EDIT: After #CommonsWare's answer I updated my class as follows:
public class Fragment_2 extends SherlockFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button send = (Button) findViewById(R.id.bSend); //Error at this line
//some error free code
FragmentTransaction t = getSupportFragmentManager().beginTransaction(); //Error at this line
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View v = inflater.inflate(R.layout.fragment2, container, false);
return v;
}
My final two questions are:
How should I access my R.id.bSend Button in the Fragment_2 class.
Eclipse is giving the suggestion to change getSupportFragmentManager() to getFragmentManager(). Is that change all right?
Thanks!
Is it illegal to extend a FragmentActivity or even an Activity to fragment classes?
Fragment is a Java class. Your fragment implementations (for use as pages in your ViewPager) must inherit from Fragment, directly or indirectly.
Activity does not inherit from Fragment. FragmentActivity does not inherit from Fragment. Hence, you cannot inherit from Activity or FragmentActivity and somehow also inherit from Fragment.
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");
I'm trying to figure out how fragments are working.
I have 3 classes, MainActivity, Fragment1 and Fragment2.
MainActivity extends SherlockFragmentActivity
and
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Fragment1 firstFragment = new Fragment1();
firstFragment.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container1, firstFragment).commit();
Now, I load Fragment1 into my fragment_container, and it displays nice.
(So main_activity.xml has only one )
Ok, Fragment1 extends SherlockFragment, does nothing more then
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment1layout, container, false);
So I just inflate it from my .xml that has one text view and one button.
Where in the world now can I instance Button, and give him code to replace Fragment1 with Fragment2?
What is the code for that, as I'm now "in Fragment1" so I need to somehow communicate with Fragment holder and tell it "replace me with Fragment2".
Fragment2 also extends SherlockFragment, and does nothing, inflates it's empty .xml
You have to call your fragment2 from fragment1 like below
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment1layout, container, false);
Button button = (Button)view.findViewById(R.id.yourButton);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//Replace your fragment
}
});
return view;
}
I'm now "in Fragment1" so I need to somehow communicate with Fragment holder and tell it "replace me with Fragment2".
If you want replace Fragment1 to Fragment2 when you click on button which is into Fragment1:
(best practices)
you should create callbacks from fragment1 to MainActivity like it is described here
into MainActivity place logics which will replace fragment1 to fragment2.
(bad practices)
Create method into MainActivity which will replace one fragment to another for example changeFirstFragmentToAnother()
then when you need to change fragment1 to fragment2 you may call this method manually (from fragment1) like this:
((MainActivity)getActivity()).changeFirstFragmentToAnother();