I am wondering if this can be done. Basically I have a layout with 2 fragments in it that I use for most of my tabs but on 2 of the tabs I want to add a couple more fragments to display more things. Is it possible to change the content view to a different layout when changing tabs?
If that cant be done I thought about creating a layout with all the fragment parts that I would need and just changing the layouts of the fragments so the ones I dont use wont "show". I dont mean using FragmentTransaction.hide() because I want the fragments to fill the screen when others are not used. Would that be a bad idea or is there an easier way to do what I want?
here is my code for the activity and tabs
public class Tabs extends Activity{
long deleteID;
#Override
public void onCreate(Bundle create){
super.onCreate(create);
setContentView(R.layout.main_layout);
createTabs();
ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
bar.setDisplayHomeAsUpEnabled(true);
if(create != null){
bar.setSelectedNavigationItem(create.getInt("Home",0));
}
}
I also add tabs a whatnot but thats not important
this is the actionbar subclass
private class TabListener implements ActionBar.TabListener{
TabContent mFragment;
public TabListener(TabContent fragment) {
mFragment = fragment;
}
#Override
public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) {
ListFragment newListFragment = new BowlersListFragment();
Fragment newFragment = new BowlerEntryFrag();
ft = getFragmentManager().beginTransaction();
ft.replace(R.id.frameOne, newListFragment);
ft.replace(R.id.frameTwo, newFragment);
ft.addToBackStack(null);
ft.commit();
}
#Override
public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {
if(ft != null){
ft.remove(mFragment);
}
}
}
}
I tried doing Activity.setContentView(r.layout.newView) but that won't work
I had similar problem, so implemented it like this. I have a mainActivity that holds and creates the tabs. That activity uses a layout with one fragment container, main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
In my activity I have the following code for creating the tabs and fragments:
historyTab = actionbar.newTab().setText("History");
historyTab.setTabListener(new MyTabsListener(new HistoryFragment()));
actionbar.addTab(historyTab);
My tabListener looks something like this:
private class MyTabsListener implements ActionBar.TabListener {
public Fragment fragment;
private boolean isFragmentAdded = false;
public MyTabsListener(Fragment fragment) {
this.fragment = fragment;
}
#Override
public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) {
FragmentManager fragMgr = getSupportFragmentManager();
FragmentTransaction xaction = fragMgr.beginTransaction();
if (fragment instanceof HistoryFragment) {
fragment = new HistoryFragment();
xaction.add(R.id.fragment_container, fragment);
} else if (fragment instanceof .. some other fragment..) {
fragment = new .. some other fragment();
xaction.add(R.id.fragment_container, fragment);
}
}
xaction.commit();
}
#Override
public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {
FragmentManager fragMgr = getSupportFragmentManager();
FragmentTransaction xaction;
xaction = fragMgr.beginTransaction();
Fragment fragment = fragMgr.findFragmentById(R.id.fragment_container);
xaction.remove(fragment);
xaction.commit();
}
}
The layout for the History fragment in my example, can be anything, even a layout that contains two fragments, or as much you need. Just be careful, and in onCreateview method in the fragment, use this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
if (view == null) { // this line is very important!
view = inflater.inflate(R.layout.history_fragment_layout, container, false);
listView = (ListView) view.findViewById(R.id.historyList);
}
return view;
}
Hope that helps!:)
Related
I put some tabs in the action bar with the following code. Everything looks fine. There are 5 tabs here. I coded each tab to open a new layout. But the problem is only the first tab works fine. Second tab opens the fifth layout and third, fouth, fifth tabs are not working. When I remove the fifth tab, then second tab opens the fourth layout and, other buttons are not woking, I couldn't silve this problem. Please help me. Thank you!
Here is my codings,
main class file;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
android.app.ActionBar actionbar = getActionBar();
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
// show the given tab
}
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction ft) {
// hide the given tab
}
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction ft) {
// probably ignore this event
}
};
ActionBar.Tab baby = actionbar.newTab().setText("Baby")
.setTabListener(tabListener);
ActionBar.Tab books = actionbar.newTab().setText("Books")
.setTabListener(tabListener);
ActionBar.Tab electronics = actionbar.newTab().setText("Electronics")
.setTabListener(tabListener);
ActionBar.Tab health = actionbar.newTab().setText("Health and Beauty")
.setTabListener(tabListener);
ActionBar.Tab sports = actionbar.newTab().setText("Sports")
.setTabListener(tabListener);
Fragment babyFragment = new Baby();
Fragment booksFragment = new Books();
Fragment electronicsFragment = new Electronics();
Fragment healthFragment = new Health();
//Fragment sportsFragment = new Sports();
baby.setTabListener(new MyTabsListener(babyFragment));
books.setTabListener(new MyTabsListener(booksFragment));
books.setTabListener(new MyTabsListener(electronicsFragment));
books.setTabListener(new MyTabsListener(healthFragment));
//books.setTabListener(new MyTabsListener(sportsFragment));
actionbar.addTab(baby);
actionbar.addTab(books);
actionbar.addTab(electronics);
actionbar.addTab(health);
actionbar.addTab(sports);
}
class MyTabsListener implements ActionBar.TabListener {
public Fragment fragment;
public MyTabsListener(Fragment fragment) {
this.fragment = fragment;
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(R.id.fragment_container, fragment);
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
}
}
every other other java file looks like this;
public class Baby extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.baby, container, false);
}
}
main xml file;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_gravity="center">
<LinearLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</LinearLayout>
</LinearLayout>
Pleease help me to solve this problem.
The error seems to be here:
baby.setTabListener(new MyTabsListener(babyFragment)); // OK
books.setTabListener(new MyTabsListener(booksFragment)); // OK
books.setTabListener(new MyTabsListener(electronicsFragment)); // !!
books.setTabListener(new MyTabsListener(healthFragment)); // !!
You are setting the different listeners to the same tab (that's why the "books" shows the "health" fragment, and the others do nothing).
i have the following activity which produced 3 tabs, and put fragment in each one of them.
public class ClientActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tabA = bar.newTab().setCustomView(R.layout.tab_a_layout);
ActionBar.Tab tabB = bar.newTab().setCustomView(R.layout.tab_b_layout);
ActionBar.Tab tabC = bar.newTab().setCustomView(R.layout.tab_c_layout);
Fragment fragmentA = new firstTab();
Fragment fragmentB = new secondTab();
Fragment fragmentC = new thirdTab();
tabA.setTabListener(new MyTabsListener(fragmentA));
tabB.setTabListener(new MyTabsListener(fragmentB));
tabC.setTabListener(new MyTabsListener(fragmentC));
bar.addTab(tabA);
bar.addTab(tabB);
bar.addTab(tabC);
}
protected class MyTabsListener implements ActionBar.TabListener {
private Fragment fragment;
public MyTabsListener(Fragment fragment)
{
this.fragment = fragment;
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft)
{
ft.add(R.id.fragment_place, fragment, null);
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
}
}
}
in the first fragment (tabA) i have listview and listener which replacing the fragment on click.
when i am clicking on the second tab (after selecting line on the listview on tabA), the listener adding the tab instead of replacing it.
it happens because the TabUnsellected is removing the wrong fragment (it was first_tab, but replaced to test_tab on the listview selecting row).
how can i use the remove option on the ft on TabUnselected to remove the CURRENT fragment on the tab, assuming i have always 1 fragment on each tab?
Thanks
Fixed it by changing from ft.add to ft.replace on the TabSelected:
ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_place, fragment);
ft.commit();
How do I switch fragments inside a tab?
My application contains three fragments, AFragment, BFragment, and CFragment. These fragments, in turn, correspond to their own layout files: AFragment contains a Button, and BFragment and CFragment have TextView. There is a fourth layout file named activity_main.
Now, I have four classes, MainActivity, AFragment, BFragment and CFragment. The classes AFragment, BFragment, CFragment only the typical contain OnCreateView on each of them.
MainActivity contains this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
appContext = getApplicationContext();
//ActionBar
ActionBar actionbar = getActionBar();
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab PlayerTab = actionbar.newTab().setText("Fragment A");
ActionBar.Tab StationsTab = actionbar.newTab().setText("Fragment B");
Fragment PlayerFragment = new AFragment();
Fragment StationsFragment = new BFragment();
PlayerTab.setTabListener(new MyTabsListener(PlayerFragment));
StationsTab.setTabListener(new MyTabsListener(StationsFragment));
actionbar.addTab(PlayerTab);
actionbar.addTab(StationsTab);
And then the TabListener:
class MyTabsListener implements ActionBar.TabListener {
public Fragment fragment;
public MyTabsListener(Fragment fragment) {
this.fragment = fragment;
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
Toast.makeText(MainActivity.appContext, "Reselected!", Toast.LENGTH_LONG).show();
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(R.id.fragment_container, fragment);
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
}
}
As you can see, activity_main.xml only contains a LinearLayout with an id 'fragment_container' for tabs AFragment and BFragment. Now I want it in such a way that clicking a button in AFragment switches the entire AFragment to CFragment. How can I achieve this? Thank you.
(EDIT) I did the following but my app crashed on start. What did I do wrong?
I added the following on my MainActivity.java, just below the ActionBar sequence:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
appContext = getApplicationContext();
//ActionBar
....
....
....
Button mButton = (Button) findViewById(R.id.button1);
mButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
CFragment fragment = new CFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
});
get a fragment transaction using the (support) fragment manager of your activity.
replace AFragment by CFragment as you did in onTabSelected
commit your transaction.
Also, please note :
don't keep references on your fragment, you actually prevent garbage collection from occuring. You should create your fragments once, not every time. In TabSelected, check if the fragment is known by the fragment manager (using findFragmentByTag). If not, create it. If it is, just re-replace it.
share your listener, you don't need one by tab.
Yesterday I downloaded new HoloEverywhere library.
Currently, I have problem with tab navigation after screen rotation.
My Home Activity:
public class MainActivity extends Activity implements TabListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setUpTabs();
}
private void setUpTabs() {
String[] titles = {
"First", "Second",
};
ActionBar supportActionBar = getSupportActionBar();
for (int i = 0; i < titles.length; i++) {
ActionBar.Tab tab = supportActionBar.newTab();
tab.setText(titles[i]);
tab.setTag(MyFragment.TAG);
tab.setTabListener(this);
supportActionBar.addTab(tab, false);
}
supportActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
supportActionBar.setSelectedNavigationItem(0);
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) {
final String fragmentTag = tab.getTag().toString();
Fragment fragment = getSupportFragmentManager().findFragmentByTag(fragmentTag);
if (fragment == null) {
fragment = new MyFragment();
fragmentTransaction.add(android.R.id.content, fragment, fragmentTag);
} else {
fragmentTransaction.attach(fragment);
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction fragmentTransaction) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag((String) tab.getTag());
if (fragment != null) {
fragmentTransaction.detach(fragment);
}
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction fragmentTransaction) {
}
}
And my Fragment class.
public class MyFragment extends Fragment {
public static final String TAG = MyFragment.class.getCanonicalName();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = new View(getActivity());
view.setBackgroundColor(Color.BLACK);
return view;
}
}
When I rotate the screen fragment not displaying. It displays when i select tab (which is not currently selected) manually.
I just solve the problem.
I post my code here and see if those can help you :D
if (savedInstanceState == null){
TabHomeFragment homeFragment = new TabHomeFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container, homeFragment, "home_fragment").commit();
}else{
TabHomeFragment homeFragment = (TabHomeFragment) getSupportFragmentManager().findFragmentByTag("home_fragment");
}
Those code are located in OnCreate method.
When the Device rotate and Ortiention change, the fragment will recreate again. So add a if clase to check if there is already one here.
But I am using normal Fragment in Android. Hope it can help you a little.
I am trying to create a scrollable tabs using fragment.
Tabs are showing and scrolling also. But the problem is the tab content is not showing.
I am using fragments to show the contents. I am new in this topic : fragment. Am I missing anything in this code?
Please help me.
public class SrollableTab extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
bar.addTab(createTab("Tab 1"));
bar.addTab(createTab("Tab 2"));
bar.addTab(createTab("Tab 3"));
bar.addTab(createTab("Tab 4"));
bar.addTab(createTab("Tab 5"));
bar.addTab(createTab("Tab 6"));
if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
}
public Tab createTab(String tabTitle)
{
ActionBar bar = getActionBar();
Tab tab = bar.newTab().setText(tabTitle).setTabListener(new TabFragment());
return tab;
}
class TabFragment extends Fragment implements TabListener
{
#Override
public void onCreate(Bundle fragmentState)
{
super.onCreate(fragmentState);
}
#Override
public View onCreateView(LayoutInflater inflator, ViewGroup container, Bundle savedState)
{
View view = inflator.inflate(R.layout.tab_content, container, false);
TextView t = (TextView)view.findViewById(R.id.txtTab);
t.setText("tab content");
return view;
}
#Override
public void onActivityCreated(Bundle savedState)
{
super.onActivityCreated(savedState);
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
}
}
tab_content.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#ffffff" >
<TextView android:id="#+id/txtTab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hello"
android:textColor="#ff0000"/>
</LinearLayout>
This may be old but found my own solution on this.
I've use PagerSlidingTabStrip for a while now until I start using the new material TabLayout. Both works on Activity, but not on Fragments. This are some discussion about the bug on fragments.
The fix I've come up with is, on settings viewpager's adater (usually extended with FragmentPagerAdapter) on its constructor parameter it needs FragmentManager, instead of using the activity's FragmentManager use the fragment's one instead which is getChildFragmentManager().
That fix it. Android bugs still annoys me though.
Cheers