I'm trying to show fragments in viewPager with tabsLayout but the viewPager shows nothing. However, the tabs have been added to the view.
I have also put some logs in the fragments just to make sure that they're created and it's showing the logs - nothing wrong with the fragments.
the layout that contains the tabs and viewPager:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:tabIndicatorColor="#color/colorAccent"
app:tabMode="fixed"
app:tabSelectedTextColor="#color/colorAccent"
app:tabTextAppearance="#style/customTabsStyle"
app:tabTextColor="#000" />
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Then in MainActivity I have this code:
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.promotions)));
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.all_stores)));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final HomeTabsAdapter tabsAdapter = new
HomeTabsAdapter(MainActivity.this,getSupportFragmentManager(),
tabLayout.getTabCount());
viewPager.setAdapter(tabsAdapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
And this is part of HomeTabsAdapter:
public HomeTabsAdapter(Context c, FragmentManager fm, int totalTabs) {
super(fm);
context = c;
this.totalTabs = totalTabs;
}
#NonNull
#Override
public Fragment getItem(int position) {
switch (position) {
case 1:
return getAllStoresFragment();
default:
return getPromotionsFragment();
}
Note: Both fragments are of the same type but i'm showing different stuff based on the Arguments. (I'm using the getInstance(..) way to handle this using Bundle and Arguments).
What changes to this code could solve the issue?
The position starts at 0.
#NonNull
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return getAllStoresFragment();
default:
return getPromotionsFragment();
}
Related
I am trying to develop one activity, which contains TabLayout, which is build using one Fragment, but used a few times (same layout, different data). But when I have such a configuration, my app doesn't even go inside of getItem() method and doesn't show up my layout. Any ideas where is the problem?
My code:
Activity:
public class IndoorArenaActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_arena);
TabLayout tabLayout = findViewById(R.id.tabs);
final ViewPager viewPager = findViewById(R.id.viewPager);
final PageAdapterArena adapter = new PageAdapterArena
(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addTab(tabLayout.newTab().setText("today"));
tabLayout.addTab(tabLayout.newTab().setText("tomorrow"));
tabLayout.addTab(tabLayout.newTab().setText("13/11"));
tabLayout.addTab(tabLayout.newTab().setText("14/11"));
tabLayout.addTab(tabLayout.newTab().setText("15/11"));
tabLayout.addTab(tabLayout.newTab().setText("16/11"));
tabLayout.addTab(tabLayout.newTab().setText("17/11"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
// if (id == R.id.action_settings) {
// return true;
// }
return super.onOptionsItemSelected(item);
}
}
Adapter:
public class PageAdapterArena extends FragmentStatePagerAdapter {
int mNumOfTabs;
public PageAdapterArena(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch(position){
case 0:
fragment = IndoorArenaFragment.newInstance();
break;
}
return fragment;
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
Fragment:
public class IndoorArenaFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.indoor_arena_fragment, container, false);
}
public static Fragment newInstance() {
IndoorArenaFragment fragment = new IndoorArenaFragment();
return fragment;
}
}
Layout for activity:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".IndoorArena.IndoorArenaActivity">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
app:tabMode="scrollable"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/tab_layout" />
Layout for fragment:
<?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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="7:00"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:text="Olga (Gatsby)"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="8:00"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="9:00"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
App doesn't show up any errors, only the fragment looks like this:
And I would like to show up like this (each fragment):
You're actually passing in NumOfTabs of 0 when you create the adapter, that's why you're getting an empty view in the ViewPager, and getItem not being called. To fix this, you just need to move your adapter creation line after adding the tabs:
TabLayout tabLayout = findViewById(R.id.tabs);
ViewPager viewPager = findViewById(R.id.viewPager);
tabLayout.addTab(tabLayout.newTab().setText("today"));
tabLayout.addTab(tabLayout.newTab().setText("tomorrow"));
tabLayout.addTab(tabLayout.newTab().setText("13/11"));
tabLayout.addTab(tabLayout.newTab().setText("14/11"));
tabLayout.addTab(tabLayout.newTab().setText("15/11"));
tabLayout.addTab(tabLayout.newTab().setText("16/11"));
tabLayout.addTab(tabLayout.newTab().setText("17/11"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
// Create adapter after adding the tabs
PageAdapterArena adapter = new PageAdapterArena(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
android BottomNavigationView with ViewPager implement Fragment and fragment inside tablayout attached with ViewPager Fragment RecyclerView Scroll Toolbar scroll
if RecyclerView Scroll toolbar scroll Please help me
As like this image
You can add TabLayout with PagerView by following step:
Step 1:
Add layout into you main xml like
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:tabStripEnabled="true"
app:tabBackground="#drawable/tab_color_selector"// make a xml selector
app:tabPaddingEnd="0dp"
app:tabIndicatorColor="#ff727272"
app:tabPaddingStart="0dp"
app:tabSelectedTextColor="#ffffff"></android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</LinearLayout>
</RelativeLayout>
Step 2:
Find these into your Activity and set FragmentPagerAdapter into PagerView and set other properties like this
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.addTab(tabLayout.newTab().setText("Artcles"));
tabLayout.addTab(tabLayout.newTab().setText("Dicussion"));
tabLayout.addTab(tabLayout.newTab().setText("News"));
ViewPager mViewPager = (ViewPager) findViewById(R.id.container);
ArrayList<Fragment> fragments = new ArrayList<>();
fragments.add(new ArtclesFragment());// create an ArtclesFragment
fragments.add(new DicussionFragment());// Create a DicussionFragment
fragments.add(new NewsFragment()); //Create a NewsFragment
mViewPager.setAdapter(new FragPagerAdaptor(getSupportFragmentManager(), fragments););
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
tabLayout.getTabAt(position).select();
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
FragPagerAdaptor look like:
public class FragPagerAdaptor extends FragmentPagerAdapter {
private ArrayList<Fragment> fragments;
public FragPagerAdaptor(FragmentManager fm, ArrayList<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments == null ? 0 : fragments.size();
}
}
Note: You have to create separate fragemet for each tab.
Hope it help you understand basic implementation of Tab and PagerView TabLayout.
I've created a tab layout with viewpager.
Everything was alright, except that I need to run a method in a specific moment. So I need to get fragment instance and run their method.
I create in this way:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
activateToolbarWithNavigationView(HomeActivity.this);
// Tabs Setup
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
final ViewPager viewPager = (ViewPager) findViewById(R.id.home_pager);
if (tabLayout != null) {
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.favorites_label_fragment)).setTag(getString(R.string.fragment_favorite_tag)));
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.air_today_label_fragment)).setTag(getString(R.string.fragment_airing_today_tag)));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final HomePageAdapter adapter = new HomePageAdapter
(getSupportFragmentManager(), tabLayout.getTabCount());
if (viewPager != null) {
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
}
public void refreshFavorites(){
FavoritesFragment favoritesFragment = (FavoritesFragment) getSupportFragmentManager().findFragmentByTag(getString(R.string.fragment_favorite_tag));
if(favoritesFragment != null) favoritesFragment.executeFavoriteList();
}
I don't know if i'm doing it in wrong way, or there some mistake that they return null from findFragmentByTag... I can't figure out. In case, I've checked some others answers but I can't understand what I really need to do.
viewpager adapter:
public class HomePageAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;
public HomePageAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
FavoritesFragment favoritesFragment = new FavoritesFragment();
return favoritesFragment;
case 1:
AirTodayFragment airTodayFragment = new AirTodayFragment();
return airTodayFragment;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
my xml:
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/ad_view_home">
<android.support.design.widget.AppBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?actionBarSize"
android:theme="#style/ActionBarThemeOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
app:logo="#mipmap/ic_launcher_initials"
app:popupTheme="#style/AppTheme.PopupOverlay"
app:theme="#style/ActionBarThemeOverlay"
app:titleTextAppearance="#style/ActionBar.TitleText">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/app_bar_layout"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/home_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
EDIT 1: HOW I SOLVED:
public void refreshFavorites(){
List<Fragment> allFragments = getSupportFragmentManager().getFragments();
for (Fragment fragmento: allFragments) {
if (fragmento instanceof FavoritesFragment){
((FavoritesFragment) fragmento).executeFavoriteList();
}
}
}
EDIT 2: WHERE I USE:
I didn't use refreshFavoretes inside my Activity but actually in Fragments that are inside of it:
#Override
public void onClick(View v) {
...
// Refresh Favorites
if (getActivity() instanceof MainActivity) ((MainActivity) getActivity()).refreshFavorites();
}
You can see more at:
GitHub/MainActivity.Java
and
GitHub/PopularFragment.Java -- Fragment from MainActivity
You are not setting tag for fragment that is the reason you get null
Instead of using,
FavoritesFragment favoritesFragment = (FavoritesFragment) getSupportFragmentManager()
.findFragmentByTag(getString(R.string.fragment_favorite_tag));
use this,
FavoritesFragment favoritesFragment = (FavoritesFragment) getSupportFragmentManager()
.getFragments()
.get(0);
to get instance of FavoritesFragment.
I have put get(0) as your position of FavoritesFragment instance is at zero.
You can get AirTodayFragment instance at position 1 calling get(1)
I have created an android activity that contains three tabs using tablayout and pager adapter. every tab has its Java file and (its layout in res/Layout folder).
the first tap has no problem while the problem appears in the second and the 3rd tab.
there is a difference between the layout xml design in android studio and when it is inflated on the emulator or real device.
the objects aren't in its correct positions and shifted horizontally and vertically! what is the problem causing this?
Android Studio Pic: (Spinners are in the correct position)
Emulator PIC: (Spinners are in incorrect positions)
Tab 3 Layout Design Example:
<RelativeLayout>
<ScrollView>
<RelativeLayout>
<TextView>
<TextView>
<Spinner>
<Spinner>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
there are so many textviews and everyone has a spinner in front of it. and the problem appears in the spinners position, they are shifted up.
Tab 3 Java file:
public class DCO_New_Report extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.dco_new_report, container, false);
}
}
Main Activity Java:
public class DCODatabase extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dcodatabase);
Toolbar toolbar = (Toolbar) findViewById(R.id.DCODatabaseToolbar);
setSupportActionBar(toolbar);
assert toolbar != null;
toolbar.setLogo(R.drawable.dco1);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab);
assert tabLayout != null;
tabLayout.addTab(tabLayout.newTab().setText("General Reports"));
tabLayout.addTab(tabLayout.newTab().setText("Report Display"));
tabLayout.addTab(tabLayout.newTab().setText("New Report"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final PagerAdapter adapter = new PagerAdapter
(getSupportFragmentManager(), tabLayout.getTabCount());
assert viewPager != null;
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
}
Main Activity XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="esmviewer.myandroid.com.esmviewer.DCODatabase">
<android.support.v7.widget.Toolbar
android:id="#+id/DCODatabaseToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="#+id/tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/DCODatabaseToolbar"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/tab"/>
</RelativeLayout>
Pager Adapter Java File:
public class PagerAdapter extends FragmentStatePagerAdapter{
int mNumOfTabs;
public PagerAdapter(FragmentManager fm, int mNumOfTabs) {
super(fm);
this.mNumOfTabs = mNumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
DCOGeneralReports tab1 = new DCOGeneralReports();
return tab1;
case 1:
DCOReportDisplay tab2 = new DCOReportDisplay();
return tab2;
case 2:
DCO_New_Report tab3 = new DCO_New_Report();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
For each row, make a LinearLayout with orientation set to horizontal.
Then add a TextView and a Spinner to it with proper weights and it should work.
Hope this hepls :)
I have successfully used TabLayout with AppCompatActivity with a CoordinatorLayout that looks close to this snippet:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:fab="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="snap"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"
app:tabMode="fixed" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content" />
</android.support.design.widget.CoordinatorLayout>
Now I have implemented a NavigationDrawer and I am struggling to implement tabs within one of the Fragments being shown inside my AppCompatActivity. I want to be able to switch with TabLayout between few child Fragments inside of this Fragment.
How do I access TabLayout from one of my Fragments?
How do I set PagerAdapter for each of the Fragments correctly?
Where do I call addOnPageChangeListener?
How do I hide TabLayout when one of my Fragments does not need to
display tabs?
1. Switching between first-level Fragments
Suppose layout content.xml stands for:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".ui.MyActivity"
tools:showIn="#layout/my_activity" />
Then, to be able to switch between the Fragments, implement this function:
private void makeTransition(int fragmentId) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
switch (fragmentId) {
// Fragment with tabs
case FRAGMENT_TABS:
fragmentTransaction.replace(R.id.fragment_container, new TabsFragment());
// This shows TabLayout
findViewById(R.id.tabs).setVisibility(View.VISIBLE);
getSupportActionBar().setTitle(R.string.fragment_tabs_title);
break;
// Fragment with no tabs
case FRAGMENT_NO_TABS:
fragmentTransaction.replace(R.id.fragment_container, new NoTabsFragment());
// This hides TabLayout
findViewById(R.id.tabs).setVisibility(View.GONE);
getSupportActionBar().setTitle(R.string.fragment_no_tabs_title);
break;
default:
throw new RuntimeException("No fragment with ID " + fragmentId + " found");
}
fragmentTransaction.commit();
}
2. Accessing and setting up TabLayout from first-level Fragment
In TabsFragment class, add a private class TabAdapter:
private class TabAdapter extends FragmentPagerAdapter {
public TabAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "TAB1";
case 1:
return "TAB2";
// ...
}
return null;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return Tab1Fragment.getInstance();
case 1:
return Tab2Fragment.getInstance();
// ...
}
return null;
}
#Override
public int getCount() {
return 2;
}
}
Also, optionally, implement a ViewPager.OnPageChangeListener:
private class FragmentPageChangeListener implements ViewPager.OnPageChangeListener {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
Log.d(getClass().getName(), "onPageScrolled");
}
#Override
public void onPageSelected(int position) {
Log.d(getClass().getName(), "onPageSelected");
}
#Override
public void onPageScrollStateChanged(int state) {
Log.d(getClass().getName(), "onPageScrollStateChanged");
}
}
Suppose your layout for fragment with tabs is like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true" />
</RelativeLayout>
Override onCreateView to look like this:
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.viewpager_fragment, null);
fragmentPagerAdapter = new TabAdapter(getChildFragmentManager());
fragmentPageChangeListener = new FragmentPageChangeListener();
ViewPager pager = (ViewPager) view.findViewById(R.id.viewpager);
pager.setAdapter(fragmentPagerAdapter);
pager.addOnPageChangeListener(fragmentPageChangeListener);
TabLayout tabLayout = (TabLayout) MyAcvtivity.getInstance().findViewById(R.id.tabs);
tabLayout.setupWithViewPager(pager);
return view;
}
NB:
Use getChildFragmentManager() and not getFragmentManager() in first-level Fragments when instantiating a ViewPager.