Actionbarsherlock + Tabs + Multi Fragments

Actionbarsherlock + tabs + multi fragments?

You need the right libraries to implement what you want.

Basically, a ViewPager library is what is missing from you. My suggestions:

1. ActionbarSherlock

It's so dead-easy to work with that I won't explain it.

2. ViewPagerExtensions

You can find it here. Download the ZIP files and create a new project from it.

I only can make this set to work as static, I would like to create this like android market app (swype movement).

Implement com.astuetz.viewpager.extensions.SwipeyTabsView from this project. There are easy-to-follow examples. it does exactly what you want. There are even other tab styles to choose from (including the new People tab that comes with ICS). Besides, it's very easy to style it to match your app identity.

3. FragmentPagerAdapter

Finally, that class from the support library (v4).

Good luck, and be free to ask me if you need more help.


You don't need to override instantiateItem in FragmentPagerAdapter if you're using what I suggested. You only need to

  1. Provide a constructor with a FragmentManager and call the super implementation;
  2. Override getCount to return the number of fragments in your pager, and
  3. getItem, which is what you'll use to return your fragments for creation.

This is an example from code I have here (a full working, production example). It's an inner class to the activity that implements the pager:

static class MyFragmentPagerAdapter extends FragmentPagerAdapter {

public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}

@Override
public int getCount() {
return 2;
}

@Override
public Fragment getItem(int position) {
Fragment f;
switch(position) {
case 0:
f= new ItemSalesDataFragment();
break;
case 1:
f= new DepartmentChooserFragment();
break;
default:
throw new IllegalArgumentException("not this many fragments: " + position);
}
return f;
}
}

As you can see, this pager handles two 'pages', the left displays sales data. The right one allows the user to select which department. Those are returned in the getItem method. The proper fragments (you can use whatever Fragments you already have, no modification needed).

As expected, you join all this together by 1) creating an object that instantiate MyFragmentPagerAdapter, and 2) setting the adapter to your ViewPager object to be that class that you just instantiated. As you can see, its getItem method will "give" the pager all the fragments you need. Example:

mFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mFragmentPagerAdapter);

Of course, there are other things to do, like creating the tab buttons themselves and joining all this to cross-communicate. I suggest looking at the examples provided in the ViewPagerExtensions ZIP file that you download from GitHub. This is just the answer to the question in your comment. As you can see, it's not that much code using this library.

Multiple fragments/layout in one Tab of actionbarsherlock

If you know what the two Fragments are in advance just declar them both within the XML layout file for that tab. You can see how to do this in the fragment tutorial from the android docs. This will display two fragments in one activity using an outer layout element as a container.

ActionBar Tabs with multiple fragments

I'll leave this open incase someone has a simplification or a better idea...

Eventually went with a workaround of having a base layout with 3 frame layouts...

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<FrameLayout
android:id="@+id/fragment_sb"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="@+id/fragment_local"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="@+id/fragment_rest"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"/>

</LinearLayout>

Then in my activity with the tabs I made a custom TabListener that handled the changes between. The code I used is below (I'm using actionbarsherlock so it'll look slightly different than the normal stuff)

public class TabActivity extends FragmentActivity {

Fragment1 fragment1;
Fragment2 fragment2;
Fragment3 fragment3;
Fragment4 fragment4;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);

final ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayShowTitleEnabled(true);
bar.setDisplayShowHomeEnabled(false);
bar.setTitle("Title");

bar.addTab(bar.newTab()
.setIcon(R.drawable.ic_list_tab_selected)
.setTabListener(new ListTabListener(this)));
bar.addTab(bar.newTab()
.setIcon(R.drawable.ic_map_tab_selected)
.setTabListener(new MapTabListener(this)));

if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
}

@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("tab", getSupportActionBar().getSelectedNavigationIndex());
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.test_menu, menu);

return super.onCreateOptionsMenu(menu);
}

public static class ListTabListener implements ActionBar.TabListener {
private static final String fragment1Tag = "fragment1_tag";
private static final String fragment2Tag = "fragment2_tag";
private static final String fragment3Tag = "fragment3_tag";

private FragmentActivity activity;
private Fragment1 fragment1;
private Fragment2 fragment2;
private Fragment3 fragment3;

public ListTabListener(FragmentActivity activity) {
this.activity = activity;

FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();
fragment1 = (Fragment1) activity.getSupportFragmentManager().findFragmentByTag(fragment1Tag);
if (fragment1 != null && !fragment1.isDetached()) {
ft.detach(fragment1);
}

fragment2 = (Fragment2) activity.getSupportFragmentManager().findFragmentByTag(fragment1Tag);
if (fragment2 != null && !fragment2.isDetached()) {
ft.detach(fragment2);
}

fragment3 = (Fragment3) activity.getSupportFragmentManager().findFragmentByTag(fragment1Tag);
if (fragment3 != null && !fragment3.isDetached()) {
ft.detach(fragment3);
}

ft.commit();
}

@Override
public void onTabReselected(Tab tab, FragmentTransaction nullFt) {
//Reselected don't do anything
}

@Override
public void onTabSelected(Tab tab, FragmentTransaction nullFt) {
FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();

if(fragment1 == null) {
fragment1 = new Fragment1();
ft.add(R.id.fragment_sb, fragment1, fragment1Tag);
} else {
ft.attach(fragment1);
}

if(fragment2 == null) {
fragment2 = new Fragment2();
ft.add(R.id.fragment_local, fragment2, fragment2Tag);
} else {
ft.attach(fragment2);
}

if(fragment3 == null) {
fragment3 = new Fragment3();
ft.add(R.id.fragment_rest, fragment3, fragment3Tag);
} else {
ft.attach(fragment3);
}

ft.commit();
}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction nullFt) {
FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();

if(fragment1 != null)
ft.detach(fragment1);
if(fragment2 != null)
ft.detach(fragment2);
if(fragment3 != null)
ft.detach(fragment3);

ft.commit();
}
}

public static class MapTabListener implements ActionBar.TabListener {
private static final String fragment4Tag = "fragment4_tag";

private FragmentActivity activity;
private Fragment4 fragment4;

public MapTabListener(FragmentActivity activity) {
this.activity = activity;

FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();
fragment4 = (Fragment4) activity.getSupportFragmentManager().findFragmentByTag(fragment4Tag);
if (fragment4 != null && !fragment4.isDetached()) {
ft.detach(fragment4);
}
ft.commit();
}

@Override
public void onTabReselected(Tab tab, FragmentTransaction nullFt) {
//Reselected don't do anything
}

@Override
public void onTabSelected(Tab tab, FragmentTransaction nullFt) {
FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();

if(fragment4 == null) {
fragment4 = new Fragment4();
ft.add(R.id.fragment_rest, fragment4, fragment4Tag);
} else {
ft.attach(fragment4);
}

ft.commit();
}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction nullFt) {
FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();

if(fragment4 != null)
ft.detach(fragment4);

ft.commit();
}
}
}

How can I replace a fragment used by the tabs in ActionBarSherlock using the Tabs and Pager example?

The answer resides in the answers to this question
Actionbarsherlock + tabs + multi fragments?

Answers to my questions are:
1. No this is not necessary: I can add them programaticllay.
2. I can use fragmentstacks as the example shows in the link above.

ActionBarSherlock Tabs+Fragments+MapView

MapViews can not be ran as part of a fragment layout. There's no library that will give you that, as long as i know.

Though, there's a hack that will allow you to put a MapView in a fragment, but it's a little bit more elaborated.

You can take a look to it here

http://xrigau.wordpress.com/2012/03/22/howto-actionbarsherlock-mapfragment-listfragment/

Android actionbar tabs multiple fragments in one tab

And I would like to keep the tabs on the top constantly.

Then you should not be starting an activity when the user taps on tab. Your tab contents should either be fragments or something else manipulated by your TabListener. The concept of activities being the contents of tabs is now deprecated (and, IMHO, was a bad idea to begin with).

I have attempted to extend the TabActivity to each of the activities that are started under the tab, but then the listviews create over eachother.

You will notice that TabActivity is deprecated, specifically for the activities-as-the-contents-of-tabs concept.

Android: Fragment stack confusion with ActionBar and Tabs

Here is the solution that worked for me:

@Override
public void onBackPressed() {

// initialize variables
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();

// check to see if stack is empty
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
ft.commit();
}
else {

super.onBackPressed();
}
return;
}


Related Topics



Leave a reply



Submit