Heu guys i am building an app and i have implemented scrollable tabs. i would like to make it google play style like when the viewpager is scrolling i want the tabpagerindicator to move with it. is this possible?? i have tried to use this example but i failed.
Make TabPagerIndicator Like Google Play
My code so far.
public class TabsActivity extends FragmentActivity implements
ActionBar.TabListener {
private ViewPager mViewPager;
private ActionBar actionBar;
#SuppressLint({ "NewApi" })
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabs);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager
.setAdapter(new TabsPagerAdapter(getSupportFragmentManager()));
mViewPager
.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
actionBar.setSelectedNavigationItem(arg0);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tab1 = actionBar.newTab();
ActionBar.Tab tab2 = actionBar.newTab();
tab1.setText(R.string.info);
tab1.setTabListener(this);
tab2.setText(R.string.graph);
tab2.setTabListener(this);
actionBar.addTab(tab1);
actionBar.addTab(tab2);
}
class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int arg0) {
Fragment fragment = null;
if (arg0 == 0) {
fragment = new InfoFragment();
}
if (arg0 == 1) {
fragment = new GraphFragment();
}
return fragment;
}
#Override
public int getCount() {
return 2;
}
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
}
I'm a little confuse by your words: "the tabs activity has 2 fragments inside which everyone of them extends FragmentActivity". They (the Fragments) should extends Fragment and not FragmentActivity..
The right way to have this library is to create (in your case) one FragmentActivity (extends FragmentActivity) and two Fragments (extends Fragment). Your FragmentActivity will have an FragmentPagerAdapter setting with your ViewPager and your PagerTabStrip to display the two Fragments.
All is explain on the GitHub page in Usage section:
Firstly, include the library as local library project:
Download the zip > Copy/paste the Library to your application (PagerSlidingTabStrip Library: you will need PagerSlidingTabStrip.java and also the res folder as everything in attrs file, the background_tab.xml drawable, etc. copy/paste it to yours).
Then, your layout with ViewPager will be:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myappname="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.mypackagename.PagerSlidingTabStrip
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="48dip"
android:background="#drawable/background_tabs" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tabs"
tools:context=".TabsActivity" />
</RelativeLayout>
Finally, your FragmentActivity will be:
import com.mypackagename.PagerSlidingTabStrip;
public class TabsActivity extends FragmentActivity {
private ActionBar actionBar;
private ViewPager pager;
private PagerSlidingTabStrip tabs;
private MyPagerAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabs);
// ActionBar settings
actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
// ViewPager, Tab, Adapter init
tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);
pager = (ViewPager) findViewById(R.id.pager);
adapter = new MyPagerAdapter(getSupportFragmentManager());
// Adapter settings
pager.setAdapter(adapter);
tabs.setViewPager(pager);
}
public class MyPagerAdapter extends FragmentPagerAdapter {
private final String[] tab_titles = { "InfoFragment", "GraphFragment" };
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return tab_titles[position];
}
#Override
public int getCount() {
return tab_titles.length;
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
fragment = new InfoFragment();
} else {
fragment = new GraphFragment();
}
return fragment;
}
}
}
You don't need to implements ActionBar.TabListener, to set NavigationMode to MODE_TABS and adding Tab dynamically with actionBar.addTab.
As you can read on the project page: compatible with the ViewPager from the Android Support Library, this is not related with the ActionBar but with the ViewPager. Your tabs are added in the Adapter..
Finally, you can customize your Tabs with xml attributes. These attributes are handled via your attrs file and all are visible in Customization section on home page:
<com.mypackagename.PagerSlidingTabStrip
myappname:pstsIndicatorColor="#FFFF0000"
myappname:pstsUnderlineColor="#FFFF0000"
myappname:pstsIndicatorHeight="2dp"
... />
Hope this helps.
Related
Okay, I decided that using TabHost would be nice in my little app.
However, under Android 6.0+, TabActivity and several others have been deprecated.
So I have written this:
public class TabMain extends Activity{
#Override
protected void onCreate(Bundle bundle){
super.onCreate(bundle);
setContentView(R.layout.tab_main);
TabHost tabHost = (TabHost)findViewById(R.id.tab_main_tabhost);
tabHost.setup();//several lines here....}}
And when I run this code, IDE throws me an RuntimtException:
"java.lang.IllegalStateException: Did you forget to call 'public void setup(LocalActivityManager activityGroup)'?"
And I found out that ActivityGroup is also deprecated.
How should I bypass this?
try this
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"/>
<android.support.v4.view.ViewPager
android:id="#+id/home_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
in your activity
viewPager = (ViewPager) findViewById(R.id.home_viewpager);
viewPager.setOffscreenPageLimit(4);
if (viewPager != null) {
setupViewPager(viewPager);
}
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
method is
private void setupViewPager(ViewPager viewPager) {
adapter = new Adapter(getSupportFragmentManager());
adapter.addFragment(new Store(), "Store");//fragment class name
adapter.addFragment(new Post(), "GG Connect");//fragment class name
viewPager.setAdapter(adapter);
}
static class Adapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
public Adapter(FragmentManager fm) {
super(fm);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
}
You should use TabLayout and ViewPager.
Here is an answer I found through hours search on internet Android Tabs with Fragements.
I think it's a viable solution here.
ViewPage and TabLayout are in the android.support package meaning they support the backward versions, that's the main reason why I chose not to use it. It's hard to even study the new version of android, and even harder to make backward-compatible code.
I'm trying to implement 3 swapping tabs. I'm following some tutorials from YouTube. But my code's not running properly. I found many solutions, tried those solutions, did exactly same code but while running my project, it crushes. my codes below:
main java class
package io.github.hackimti.curiousity;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.ActionBar.TabListener;
import android.app.FragmentTransaction;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
public class MainActivity extends FragmentActivity implements TabListener {
ActionBar actionBar;
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager)findViewById(R.id.main_pager1);
viewPager.setAdapter(new MyAdapter(getSupportFragmentManager()));
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.addTab(actionBar.newTab().setText("Tab A").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("Tab B").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("Tab C").setTabListener(this));
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
class MyAdapter extends FragmentPagerAdapter{
public MyAdapter(android.support.v4.app.FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if(position == 0){
fragment = new FA();
}
if(position == 1){
fragment = new FB();
}
if(position == 2){
fragment = new FC();
}
return fragment;
}
#Override
public int getCount() {
return 3;
}
}
main xml file
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/main_pager1">
</android.support.v4.view.ViewPager>
I think the way you trying to achieve this is an old way.
For sliding pages with tabs do following.
Download or copy following two files on github and paste your project. this is same as on developers.google.com except setDistributeEvenly method.
https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/widget/SlidingTabLayout.java
https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/widget/SlidingTabStrip.java
activity_main.xml
<your.package.name.SlidingTabLayout
android:clickable="true"
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</your.package.name.SlidingTabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
MyAdapter.java (Here i used two pages only)
class MyPagerAdapter extends FragmentPagerAdapter
{
String[] title = {"All","Favourites"};
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment=null;
if (position==0)
fragment= new All();
if (position==1)
fragment= new Favourites();
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
return title[position];
}
}
tab_view.xml (view of tab only , if you want u can also use ImageView here)
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="#+id/tab_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text=""
android:padding="15dp"
android:textStyle="bold"
android:textSize="25dp"
/>
</FrameLayout>
MainActivity.java
private SlidingTabLayout tabLayout;
private ViewPager pager;
tabLayout= (SlidingTabLayout) findViewById(R.id.tabs);
pager = (ViewPager) findViewById(R.id.pager);
tabLayout.setCustomTabView(R.layout.tab_view,R.id.tab_title);
MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager());
pager.setAdapter(adapter);
tabLayout.setDistributeEvenly(true);
tabLayout.setViewPager(pager);
Above code is fine. but latest way to achive swiping tabs with pages is throug android support design library.
I'm following this example..
I'm having one issue, when I swipe on ViewPager respective fragment appear but when I swipe from from left to right or right to left and select previous Tab the Tab indicator appear on new selected Tab but respective fragment not appear on ViewPager.
Please help me, where I'm getting wrong?
It was bug in support lib 23.0.0 but it is solved in 23.0.1. First of all update your suppory library using SDK manager from the extras section.
and write the following line in app gradle file.
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
for your reference
https://developer.android.com/topic/libraries/support-library/revisions.html
and read the Changes for Design Support library in Android Support Library, revision 23.0.1 section
This is what i use and works fine.
Adapter:
public class SCFragmentPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
private Context mContext;
private FragmentManager mFragmentManager;
public SCFragmentPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.mFragmentManager = fm;
this.mContext = context;
}
#Override
public int getCount() {
return mFragments.size();
}
// Return the correct Fragment based on index
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
// Return the tab title to SlidingTabLayout
return mFragmentTitles.get(position);
}
public Fragment getActiveFragment(ViewPager container, int position) {
String name = makeFragmentName(container.getId(), position);
return mFragmentManager.findFragmentByTag(name);
}
private static String makeFragmentName(int viewId, int index) {
return "android:switcher:" + viewId + ":" + index;
}
}
Activity:
public class SCWelcomeActivity extends AppCompatActivity implements
SCWelcomeFragment.OnFragmentInteractionListener,
SCSyncFragment.OnFragmentInteractionListener,
SCRegisterFragment.OnFragmentInteractionListener,
SCConfirmationFragment.OnFragmentInteractionListener {
private static final String TAG = SCWelcomeActivity.class.getSimpleName();
private ViewPager viewPager = null;
private TabLayout tabLayout = null;
private Toolbar toolbar = null;
private SCFragmentPagerAdapter adapter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scwelcome);
// Layout manager that allows the user to flip through the pages
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
// Initialize the Sliding Tab Layout
tabLayout = (TabLayout) findViewById(R.id.tablayout);
// Connect the viewPager with the sliding tab layout
tabLayout.setupWithViewPager(viewPager);
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
#Override
public void onFragmentInteraction(Uri uri) {
}
private void setupViewPager(ViewPager viewPager) {
adapter = new SCFragmentPagerAdapter(getSupportFragmentManager(), SCWelcomeActivity.this);
adapter.addFragment(SCWelcomeFragment.newInstance(), getString(R.string.title_tab1));
adapter.addFragment(SCSyncFragment.newInstance(), getString(R.string.title_tab2));
adapter.addFragment(SCRegisterFragment.newInstance(), getString(R.string.title_tab3));
adapter.addFragment(SCConfirmationFragment.newInstance(), getString(R.string.title_tab4));
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(4);
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
Fragment Example :
public class SCWelcomeFragment extends Fragment {
private OnFragmentInteractionListener mListener;
public static SCWelcomeFragment newInstance() {
SCWelcomeFragment fragment = new SCWelcomeFragment();
return fragment;
}
public SCWelcomeFragment() {
super();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_scwelcome, container, false);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
Layout:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="130dp"
android:fitsSystemWindows="true"
android:gravity="bottom"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
android:layout_gravity="center"
android:theme="#style/ThemeOverlay.AppCompat.Dark"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<android.support.design.widget.TabLayout
android:id="#+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
Please try to implement the adapter as i do. Pay close attention that in mine Adapter all instances are saved in the
private final List<Fragment> mFragments = new ArrayList<>();
In your case you are always returning a new instance. So that's why a set the setOffscreenPageLimit(4). to 4 so they are kept in memory as well.
In your activity, after find Views by Id, you should "config" your ViewPager and TabLayout. Some necessary features maybe: "addOnPageChangeListener" for ViewPager and "setOnTabSelectedListener" for your TabLayout like this:
public class MainActivity extends AppCompatActivity {
private final int numOfPages = 4; //viewpager has 4 pages
private final String[] pageTitle = {"Food", "Movie", "Shopping", "Travel"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
for (int i = 0; i < numOfPages; i++) {
tabLayout.addTab(tabLayout.newTab().setText(pageTitle[i]));
}
//set gravity for tab bar
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final PagerAdapter adapter = new PagerAdapter
(getSupportFragmentManager(), numOfPages);
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(onTabSelectedListener(viewPager));
}
private TabLayout.OnTabSelectedListener onTabSelectedListener(final ViewPager pager) {
return new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
pager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
};
}
I have a tutorial post about this and it works well! There is no error like yours.
Hope it help:
http://www.devexchanges.info/2015/08/android-material-design-viewpager-with.html
None of the above answers worked for me AS of end of 2016 the bug still exists in design support library 24+.
I was able to fix this issue by wrapping the tab layout inside a
co-ordinator layout
I have more shorter variant to fix this bug (android support design lib v.23.0.0):
...
//initialize views
mViewPager.setAdapter(pagerAdapter);
mTabLayout.setupWithViewPager(mViewPager);
mViewPager.clearOnPageChangeListeners();
mViewPager.addOnPageChangeListener(new WorkaroundTabLayoutOnPageChangeListener(mTabLayout));
...
And class WorkaroundTabLayoutOnPageChangeListener:
public class WorkaroundTabLayoutOnPageChangeListener extends TabLayout.TabLayoutOnPageChangeListener {
private final WeakReference<TabLayout> mTabLayoutRef;
public WorkaroundTabLayoutOnPageChangeListener(TabLayout tabLayout) {
super(tabLayout);
this.mTabLayoutRef = new WeakReference<>(tabLayout);
}
#Override
public void onPageSelected(int position) {
super.onPageSelected(position);
final TabLayout tabLayout = mTabLayoutRef.get();
if (tabLayout != null) {
final TabLayout.Tab tab = tabLayout.getTabAt(position);
if (tab != null) {
tab.select();
}
}
}
}
Are you using support library version 23.0.0. There was an issue https://code.google.com/p/android/issues/detail?id=183123 which looks similar to yours. If that is the case indeed, update your support library version to 23.0.1. This issue has been fixed.
I'm developing an application for Android and need some help implementing Tabs
I need it to be compatible with android 2.2
I started to implement Tabs but now i dont know if it was the best idea
What I want is basically:
I want to open a activity where it will have the tabs
In each of the Tab, I want to load content dinamicly, like the play store apk:
My main problem is:
I have created a AsyncTask with an ProgressDialog for each fragment to load the data and show it on the fragment, but when the fragment activity open, it initialize all the tabs and makes to load all the fragments at the same time.
I want to load the Tab content only when the Tab becomes visible, because the user may want to see only one tab, so no need to get the other Tabs
How should I do that?
Should I use TabFragments or others methods?
My current Tab activiy is:
public class Tabs2 extends FragmentActivity implements OnTabChangeListener, OnPageChangeListener{
ViewPagerAdapter pageAdapter;
private ViewPager mViewPager;
private TabHost mTabHost;
private String interID;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Infla o layout
setContentView(R.layout.tablayout);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
// Tab Initialization
initialiseTabHost();
// Fragments and ViewPager Initialization
List<Fragment> fragments = getFragments();
pageAdapter = new ViewPagerAdapter(getSupportFragmentManager(), fragments);
mViewPager.setAdapter(pageAdapter);
mViewPager.setOnPageChangeListener(Tabs2.this);
}
// Method to add a TabHost
private static void AddTab(Tabs2 activity, TabHost tabHost, TabHost.TabSpec tabSpec) {
tabSpec.setContent(activity.new MyTabFactory(activity));
tabHost.addTab(tabSpec);
}
// Manages the Tab changes, synchronizing it with Pages
public void onTabChanged(String tag) {
int pos = this.mTabHost.getCurrentTab();
this.mViewPager.setCurrentItem(pos);
}
// Manages the Page changes, synchronizing it with Tabs
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
int pos = this.mViewPager.getCurrentItem();
this.mTabHost.setCurrentTab(pos);
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
#Override
public void onPageSelected(int arg0) {
}
private List<Fragment> getFragments(){
List<Fragment> fList = new ArrayList<Fragment>();
// Put here your Fragments
fList.add(Fragment.instantiate(this, TabFragmentA.class.getName()));
fList.add(Fragment.instantiate(this, TabFragmentB.class.getName()));
fList.add(Fragment.instantiate(this, TabFragmentC.class.getName()));
return fList;
}
// Tabs Creation
private void initialiseTabHost() {
mTabHost = (TabHost) findViewById(android.R.id.tabhost);
mTabHost.setup();
// Put here your Tabs
Tabs2.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab1").setIndicator("Detalhes"));
Tabs2.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab2").setIndicator("Comentários"));
Tabs2.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab3").setIndicator("cenas"));
mTabHost.setOnTabChangedListener(this);
}
// Um simples factory que retorna View para o TabHost
class MyTabFactory implements TabContentFactory {
private final Context mContext;
public MyTabFactory(Context context) {
mContext = context;
}
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
}
The ViewPagerAdatper:
public class ViewPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> mFragments;
public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
mFragments = fragments;
}
#Override
public Fragment getItem(int i) {
return mFragments.get(i);
}
#Override
public int getCount() {
return mFragments.size();
}
}
The XML for the Tabs activiy
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TabHost
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="35dp"
android:orientation="horizontal"
android:gravity="bottom"
android:padding="0dip" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:isScrollContainer="true"
android:scrollbars="vertical" />
</LinearLayout>
</TabHost>
For each Tab I used Fragments
public class TabFragmentA extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (container == null) {
return null;
}
// HERE I Call the AsyncTask and return the data with the layout
return (RelativeLayout) inflater.inflate(R.layout.layout_a, container, false);
}
}
since you are using a viewpager this is how a viewpager works and for good reason. A view pager by default loads the previous, current and next tab so that the content is ready when the user gets to the tab. you cannot change the viewpager to only load one page at a time.
If you notice this is exactly how the play store works
I've looked at the samples and the only difference seems to be the name, but when I just switch all the names in my app to TabPageIndicator from TitlePageIndicator, the tabs are in a messed up alignment and the footer underline is gone.
Am I missing something? Is there something extra I need to do? I have
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MyFragmentPagerAdapter adapter = new MyFragmentPagerAdapter( getSupportFragmentManager() );
ViewPager pager =
(ViewPager)findViewById( R.id.viewpager );
TabPageIndicator indicator =
(TabPageIndicator)findViewById( R.id.indicator );
pager.setAdapter( adapter );
indicator.setViewPager( pager );
and
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp" >
<com.viewpagerindicator.TabPageIndicator
android:id="#+id/indicator"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</FrameLayout>
What are the differences between TabPageIndicator and TitlePageIndicator?
Try viewing that page and see if you find the answer.
I did, that's why I posted to begin with.
Title Indicator
Displays the title of the selected page in the center with the titles
of the adjacent pages (if available) in a more subtle style.
Tab Indicator
Similar to the title indicator but displays as many titles as possible
in scrolling and animated horizontal tabs.
TitlePagerIndicator example:
Adapter
class TestFragmentAdapter extends FragmentPagerAdapter {
protected static final String[] CONTENT = new String[] { "This", "Is", "A", "Test", };
private int mCount = CONTENT.length;
public TestFragmentAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return TestFragment.newInstance(CONTENT[position % CONTENT.length]);
}
#Override
public int getCount() {
return mCount;
}
public void setCount(int count) {
if (count > 0 && count <= 10) {
mCount = count;
notifyDataSetChanged();
}
}
}
When you use TitlePagerIndicator you need to implement TitleProvider in your Adapter.
class TestTitleFragmentAdapter extends TestFragmentAdapter implements TitleProvider {
public TestTitleFragmentAdapter(FragmentManager fm) {
super(fm);
}
#Override
public String getTitle(int position) {
return TestFragmentAdapter.CONTENT[position % CONTENT.length];
}
}
Putting it all together
TestFragmentAdapter mAdapter = new TestTitleFragmentAdapter(getSupportFragmentManager());
ViewPager mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
PageIndicator mIndicator = (TitlePageIndicator)findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
TabPagerIndicator example:
public class SampleTabsDefault extends FragmentActivity {
private static final String[] CONTENT = new String[] { "Recent", "Artists", "Albums", "Songs", "Playlists", "Genres" };
TestFragmentAdapter mAdapter;
ViewPager mPager;
PageIndicator mIndicator;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_tabs);
mAdapter = new GoogleMusicAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mIndicator = (TabPageIndicator)findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
}
class GoogleMusicAdapter extends TestFragmentAdapter implements TitleProvider {
public GoogleMusicAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return TestFragment.newInstance(SampleTabsDefault.CONTENT[position % SampleTabsDefault.CONTENT.length]);
}
#Override
public int getCount() {
return SampleTabsDefault.CONTENT.length;
}
#Override
public String getTitle(int position) {
return SampleTabsDefault.CONTENT[position % SampleTabsDefault.CONTENT.length].toUpperCase();
}
}
}
All of these examples and more can be found on Jake Wharton's Github repo for ViewPagerIndicator