Here, i am using tab widget and having 3 tabs tab1, tab2 and tab3.I am setting fragments on each tab,like Fragment1 will set initially on first tab.I move on to different fragment from Fragment1 on a button click and then when i clicked on first tab not able to set Fragment1 as initailly was set.
Here is my code to set fragment initially on tabs:
public class MainActivity extends FragmentActivity{
private FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.base_layout);
mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("tab1", getResources().getDrawable(R.drawable.list)),
ListOfArticlesFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("tab2", getResources().getDrawable(R.drawable.picture)),
PicturesFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab3").setIndicator("tab2", getResources().getDrawable(R.drawable.calendar)),
ListOfArticlesFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab3").setIndicator("tab4", getResources().getDrawable(R.drawable.help)),
ListOfArticlesFragment.class, null);
}
When i move from ListOfArticlesFragment to another fragment on a button click, how to set
ListOfArticlesFragment again when clicked on tab1.
Thanks in advance.
Related
I need to pass data between tab fragments after calling switch method of tabhost mTabHost.setCurrentTab(index);
public class FragmentTabs extends FragmentActivity {
private FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_tabs);
mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.content);
mTabHost.addTab(mTabHost.newTabSpec("class1").setIndicator("Class 1"),
Class1.class, null);
mTabHost.addTab(mTabHost.newTabSpec("class2").setIndicator("Class 2"),
Class2.class, null);
mTabHost.addTab(mTabHost.newTabSpec("class3").setIndicator("Class C"),
Class3.class, null);
}
}
Is there any way to do that ?
Often you will want one Fragment to communicate with another, for example to change the content based on a user event. All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.
Check this: https://developer.android.com/training/basics/fragments/communicating.html
I have a Fragment which implements FragmentTabHost and creates a couple of tabs each of which has a Fragment. I am trying to get a reference to one of these Fragments, but am drawing a blank as to how.
public class TabFragment extends Fragment {
private FragmentTabHost mTabHost;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mTabHost = new FragmentTabHost(getActivity());
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.container);
addTab("study","Study",StudyFragment.class);
addTab("tab2","Tab 2",Tab2Fragment.class);
return mTabHost;
}
private <T extends Fragment> void addTab(String sTag, String sTitle, Class<T> c) {
View tabView = createTabView(getActivity(),sTitle);
mTabHost.addTab(mTabHost.newTabSpec(sTag).setIndicator(tabView),
c, null);
}
public StudyFragment getStudyFragment() {
// not working as fragment has not been tagged
return getChildFragmentManager().findFragmentByTag("study");
}
So the question is how do I either tag the study fragment or return a reference to it when it is created?
I've seen a couple of solutions which suggest overriding onAttachFragment, but that is for FragmentActivity not Fragment
To get a fragment, you can set an id to your fragment, then use this:
FragmentManager manager = getSupportFragmentManager();
MyFragment myFragment = (MyFragment)manager.findFragmentById(R.id.MyFragment);
Ok so you have to add tabs using TabHost.TabSpec like that:
tabHost = (FragmentTabHost)mainView.findViewById(android.R.id.tabhost);
tabHost.setup(this, getSupportFragmentManager(), android.R.id.tabcontent);
TabHost.TabSpec tabOne = tabHost.newTabSpec("One").setContent(R.id.fragOne);
TabHost.TabSpec tabTwo = tabHost.newTabSpec("Two").setContent(R.id.fragTwo);
tabHost.addTab(tabOne, TabOne.class, savedInstanceState);
tabHost.addTab(tabTwo, TabTwo.class, savedInstanceState);
In this code R.id.fragOne and R.id.fragTwo refers to two FrameLayout defined in the activity layout.
If you dont have xml layout you can define programmatically a new FrameLayout with an id for each tab.
I am using FragmentTabHost in my app. I have three tabs. Each tab shows a Fragment.
addTab("Tab1", R.drawable.ic_launcher, Fragment1.class);
addTab("Tab2", R.drawable.ic_launcher, Fragment2.class);
addTab("Tab3", R.drawable.ic_launcher, Fragment3.class);
addTab("Tab3", R.drawable.ic_launcher, Fragment4.class);
When I press back from any of these tabs, the app is closed and home screen is shown. Now what I want is, when I press back from Tab1, the app should close. However, if I press back from Tab2 or Tab3, the user should be sent to Tab1. Summary is:
Currently in Tab1 -> press back -> app close
Currently in Tab2 -> press back -> Go to Tab1
Currently in Tab3 -> press back -> Go to Tab1
How can I achieve this?
In your Activity (where you have your FragmentTabHost) override the onBackPressed(). In onBackPressed() you can check for the currentTab's position.
If current tab is not 0 (i.e. not the first tab) then set the previous tab as the current tab.
Else if current tab is 0, exit the app.
Since i do not have your actual class, I created a dummy class with FragmentTabHost just to demonstrate how it can be done.
public class MainActivity extends FragmentActivity {
private FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTabHost = (FragmentTabHost) findViewById(R.id.tab_host);
mTabHost.setup(this, getSupportFragmentManager(), R.id.tab_framelayout);
mTabHost.addTab(
mTabHost.newTabSpec("tab1").setIndicator("Tab1",
getResources().getDrawable(R.drawable.ic_launcher)),
Fragment1.class, null);
mTabHost.addTab(
mTabHost.newTabSpec("tab2").setIndicator("Tab2",
getResources().getDrawable(R.drawable.ic_launcher)),
Fragment2.class, null);
mTabHost.addTab(
mTabHost.newTabSpec("tab3").setIndicator("Tab3",
getResources().getDrawable(R.drawable.ic_launcher)),
Fragment3.class, null);
mTabHost.addTab(
mTabHost.newTabSpec("tab4").setIndicator("Tab4",
getResources().getDrawable(R.drawable.ic_launcher)),
Fragment4.class, null);
}
#Override
public void onBackPressed() {
//get current tab index.
int index = mTabHost.getCurrentTab();
//decide what to do
if(index!=0){
mTabHost.setCurrentTab(index-1);
} else {
super.onBackPressed();
}
}
}
I've implemented few Fragments in a FragmentTabHost, using:
Inside FragmentActivity Class:
FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e(TAG, "onCreateView()");
setContentView(R.layout.activity_main);
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("audio").setIndicator("Audio"),
AudioFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("video").setIndicator("Video"),
VideoFragment.class, null);
mTabHost.setOnTabChangedListener(this);
}
In one of the fragment say AudioFragment there is a button which is supposed to open a new fragment over the current fragment of AudioFragment.
Inside AudioFragment.class
#Override
public void onClick(View button) {
switch (button.getId()) {
case R.id.bOpenNewFragment:
// WHAT TO CODE, TO REPLACE THE CURRENT FRAGMENT OF AudioFragment
break;
}
}
I tried the usual code using:
Fragment fragment = new ShowAudioDetailsFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.realtabcontent, fragment);
transaction.addToBackStack(null);
transaction.commit();
But, it was creating problems when I switched to another tabs (like state was not maintained & view of new fragment was merging with the layout of other tabs).
So How can I replace the fragment with the fragment opened within FragmentTabHost
Thank You
Just add this line
((RelativeLayout) findViewById(R.id.realtabcontent)).removeAllViews(); // whatever layout you have
before :
transaction.replace(R.id.realtabcontent, fragment);
I created three tabs using FragmentTabHost. Now I need to make all the navigation are under the tabs. How can I get this. I need to get what we get using TabGroupActivity.
Tab1
--->frag1-->frag2
Tab2
--->frag3
Tab3
--->frag4--->frag5
I have used fragmentTransaction.add(), fragmentTransaction.remove(), fragmentTransaction.replace(). These three methods but nothing give solution.
Replace method shows new fragment view on top of existing fragment view.
Remove and Add, from these two remove only works, add does not works.
Thanks in advance.
TabHostMain.java
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.bottom_tabs);
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
View view;
view=getTabView(R.drawable.ic_launcher);
Bundle b = new Bundle();
b.putString("key", "Simple");
mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator(view),Fragment1.class, null);
b = new Bundle();
b.putString("key", "Contacts");
view=getTabView(R.drawable.ic_launcher);
mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator(view), Fragment2.class, null);
b = new Bundle();
b.putString("key", "Custom");
view=getTabView(R.drawable.ic_launcher);
mTabHost.addTab(mTabHost.newTabSpec("custom").setIndicator(view),Fragment3.class, null);
}
Fragment3.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View view=LayoutInflater.from(getActivity()).inflate(R.layout.activity_second, null);
((TextView)view.findViewById(R.id.second_act_text)).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fm=getChildFragmentManager();
FragmentTransaction fragmentTransaction=fm.beginTransaction();
fragmentTransaction.replace(R.id.second_activity, new Fragment1()).addToBackStack(null).commit();
}
});
return view;
}
The concept of different fragment navigation stacks in each tab has been discussed quite a few times on stackoverflow, one example for instance:
Separate Back Stack for each tab in Android using Fragments
One simple/crude way of achieving this without having to manage your own custom navigation back stack is to have a root fragment under each tab, and then whenever a root fragment wants to navigate to another fragment (fragment B) simply show a new Activity initially with fragment B and that Activity will have its own fragment navigation back stack.
Tab1 --->root frag1 --> Activity (own nav back stack) --> frag2
Tab2 --->root frag3
Tab3 --->root frag4 --> Activity (own nav back stack) --> frag5 --> frag6 --> frag7
An example of an app that does something like this is actually the StackAnywhere app. It makes heavy use of tabs, but when you navigate within those tabs it generally moves the navigation to a new Activity. YMMV with this approach, however.