I have total of 5 fragments inside a Viewpager and I want to display 2 tabs on either side of the current visible tab.
Example : My current tab is 2 . And I want tab 0, tab 1 to left and tab 3,tab 4 to the right to be displayed at once.
I tried setting viewPager.setOffscreenPageLimit(2) but it didnt' work. I still see only 1 tab displayed on either sides. What am I missing?
public class TabsFragment extends Fragment {
mViewPager = (ViewPager) view.findViewById(R.id.pager);
titleStrip = (PagerTitleStrip) view.findViewById(R.id.titlestrip);
adapter = new TabsPagerAdapter(getChildFragmentManager(), getActivity());
mViewPager.setAdapter(adapter);
mViewPager.setOffscreenPageLimit(2);
mViewPager.setCurrentItem(2);
}
public class TabsPagerAdapter extends FragmentStatePagerAdapter {
private Context context;
public TabsPagerAdapter(FragmentManager fm, Context c) {
super(fm);
context = c;
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new FirstFrag();
case 1:
return new SecondFrag();
case 2:
return new ThirdFrag();
case 3:
return new FourthFrag();
case 4:
return new FifthFrag();
default:
return new SecondFrag();
}
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 5;
}
}
Solved this issue by using TabLayout. Posting the code for future readers.
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Light">
<android.support.v7.widget.Toolbar
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/awesome_toolbar"
android:layout_width="match_parent"
android:layout_height="74dp"
android:background="#ff31353f"
android:paddingTop="20dp"
app:popupTheme="#style/AppTheme"
app:theme="#style/ToolbarTheme"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
public class TabsFragment extends Fragment {
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
mViewPager = (ViewPager) view.findViewById(R.id.pager);
tabLayout = (TabLayout)view.findViewById(R.id.tabs);
adapter = new TabsPagerAdapter(getChildFragmentManager(), getActivity());
adapter.addFragment(new FirstFrag(), getResources().getString(R.string.frag1));
adapter.addFragment(new SecondFrag(), getResources().getString(R.string.frag2));
adapter.addFragment(new ThirdFrag(), getResources().getString(R.string.frag3));
adapter.addFragment(new FourthFrag(), getResources().getString(R.string.frag4));
adapter.addFragment(new FifthFrag(), getResources().getString(R.string.frag5));
mViewPager.setAdapter(adapter);
mViewPager.setOffscreenPageLimit(2);
mViewPager.setCurrentItem(2);
tabLayout.setupWithViewPager(mViewPager);
}
You need to modify your ViewPager adapter. Override the public Fragment getItem(int position) method, and create a custom Fragment that will contain the current fragment and the fragment in position-1 in the left, position+1 in the right. You may have to override the public int getCount() method too. I didn't try an implementation like this before but I think this is the way to approach this.
Related
I try to populate a TabLayout with a ViewPager but unfortunately it doesn't get populated.
I followed this tutorial to get in touch: TabLayout and ViewPager in your Android App. The tutorial uses the old Support Library v4. My project is based on AndroidX and i want to stay with it. The official documentation of TabLayout said that I need to create the TabLayout inside the ViewPager but that's not working at all. So i created the following XML layout file:
<LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/primaryColor"
app:tabGravity="fill"
app:tabMode="fixed"
app:tabTextColor="#color/primaryTextColor" />
</androidx.viewpager.widget.ViewPager>
</LinearLayout>
I setup the ViewPager with the following lines to connect TabLayout with ViewPager:
public class MyActivity extends AppCompatActivity {
...
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_layout);
...
// tab layout
ViewPager viewPager = findViewById(R.id.viewpager);
MyFragmentPagerAdapter adapter = new MyFragmentPagerAdapter(this, getSupportFragmentManager());
viewPager.setAdapter(adapter);
TabLayout tabLayout = findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);
...
}
...
}
My Adapter is a FragmentPagerAdapter
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
private Context context;
public MyFragmentPagerAdapter(Context context, FragmentManager fm) {
super(fm);
this.context = context;
}
#Override
public Fragment getItem(int position) {
if (position == 0) {
return new MyFragment1();
} else {
return new MyFragment2();
}
}
#Override
public int getCount() {
return 2;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return context.getString(R.string.building);
case 1:
return context.getString(R.string.buff);
default:
return null;
}
}
}
One of my Fragments looks like this:
public class MyFragment1 extends Fragment {
public MyFragment () {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_building, container, false);
}
}
Here is a picture how it looks like:
Empty ViewPager
Question
So why is the TabLayout not populated at all? I'm working with Android Studio and the Design Manager just shows me an empty TabLayout and ViewPager. I guess, it would precompile the TabLayout but it is just empty...
Please help me because i stuck at this topic. I really want to code it like this to get benefit of swiping tabs and stuff.
Thanks a lot!
Here is an example from one of my projects .Create and populate ViewPager, something like this:
<androidx.viewpager.widget.ViewPager
android:id="#+id/loginViewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#id/loginTitle">
<com.google.android.material.tabs.TabLayout
android:id="#+id/loginTabContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
app:tabIndicatorColor="#color/colorPrimary"
app:tabRippleColor="#color/colorPrimary"
app:tabSelectedTextColor="#color/colorPrimaryDark"
app:tabTextAppearance="#style/TabLayoutTheme">
<com.google.android.material.tabs.TabItem android:text="first tab" />
<com.google.android.material.tabs.TabItem android:text="second tab" />
</com.google.android.material.tabs.TabLayout>
</androidx.viewpager.widget.ViewPager>
Then in your activity create a FragmentStatePagerAdapter to decide what to return in each page. my codes are in kotlin, but java version is the same:
private inner class ScreenSlidePagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
override fun getCount(): Int = NUM_PAGES
override fun getItem(position: Int): Fragment = when (position) {
1 -> FirstFragment()
0 -> SecondFragment()
else -> FirstFragment()
}
override fun getPageTitle(position: Int): CharSequence? {
return when (position) {
0 -> "First Title"
1 -> "Second Title"
else -> "First Title"
}
}
}
And finally in your Activity:
val pagerAdapter = ScreenSlidePagerAdapter(supportFragmentManager)
loginViewPager.adapter = pagerAdapter
Put your TabLayout inside your ViewPager like below.
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabBackground="#color/colorPrimaryDark"
app:tabGravity="fill"
app:tabIndicatorColor="#color/colorPrimaryLight"
app:tabMaxWidth="0dp"
app:tabMode="scrollable"
app:tabRippleColor="#color/colorPrimaryLight"
app:tabSelectedTextColor="#color/colorPrimaryLight"
app:tabTextColor="#android:color/white" />
</androidx.viewpager.widget.ViewPager>
make sure that android:layout_height of your TabLayout is set to wrap_content.
When you put your TabLayout inside your ViewPager, you don't need to keep below lines:
TabLayout tabLayout = findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);
Everything else in your code is correct.
Also, now that I see your code, layout_height of your TabLayout is set to match_parent, so TabLayout is taking whole space in your screen, giving no height to ViewPager, also, in your XML, there is no container to hold your ViewPager and TabLayout (like LinearLayout, FrameLayout etc).
<android.support.design.widget.CoordinatorLayout 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.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"
app:tabGravity="fill"
style="#style/Base.Widget.Design.TabLayout"/>
</android.support.design.widget.AppBarLayout>
<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" />
viewPager = (ViewPager)rootView. findViewById(R.id.viewpager);
ViewPagerAdapter adapter = new ViewPagerAdapter(getFragmentManager());
adapter.addFragment(new FragAllONE(), "ONE");
adapter.addFragment(new FragAllTWO(), "TWO");
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(1);
viewPager.setCurrentItem(0);
viewPager.addOnPageChangeListener(this);
tabLayout = (TabLayout)rootView. findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
private class ViewPagerAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position)
}
#Override
public int getCount() {
return mFragmentList.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Object object = super.instantiateItem(container, position);
if (object instanceof Fragment) {
Fragment fragment = (Fragment) object;
String tag = fragment.getTag();
}
return object;
}
public void restoreState(Parcelable state, ClassLoader loader) {
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
I found a solution on another thread Use Tab layout in MVVM architecture with the data binding library. I'm using Android Data Binding so the TabLayout wasn't assigned to the ViewPager. So my code was correct but not accordingly to the Data Binding.
Nevertheless, thanks for your posts here!
I have a activity that contain 2 fragments and both the fragments containing a recyclerview.
I need to implement a swipe gesture (when i swipe from one side to another the fragments need to be changed).
Previously i have added swipe gesture, but when i swipe the recycler view will scroll instead of change of fragments.
Can you help in implementing this..
Thanks
Use TabLayout with ViewPager. Create two tabs for two fragments in the activity .
http://www.androidhive.info/2015/09/android-material-design-working-with-tabs/
just use Android TabLayout with ViewPager and your problem will be solved :)
This is how you can do it:
public class YourActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_activity);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
setupViewPager(viewPager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FragmentOne(), "Fragment One");
adapter.addFragment(new FragmentTwo(), "Fragment Two");
viewPager.setAdapter(adapter);
}
private class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentTitleList = new ArrayList<>();
ViewPagerAdapter(FragmentManager fragmentManager) {super(fragmentManager);}
#Override
public Fragment getItem(int position) {return fragmentList.get(position);}
#Override
public int getCount() {
return fragmentList.size();
}
void addFragment(Fragment fragment, String title) {
fragmentList.add(fragment);
fragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
}
}
And this is the .XML file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".YourActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay">
</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:animateLayoutChanges="true"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
Hope it helps!
Simply use Tablayout and ViewPager
Here the code :-
public class DispatchOrderTab extends Fragment {
public static TabLayout tabLayout;
public static ViewPager viewPager;
public static int int_items = 2 ;
android.support.v4.app.FragmentManager mFragmentManager;
View view;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
getActivity().setTitle("Order");
View x = inflater.inflate(R.layout.activity_dispatch_order_tab,null);
tabLayout = (TabLayout) x.findViewById(R.id.sliding_tabs_dispatchtoken);
viewPager = (ViewPager) x.findViewById(R.id.viewpagerdispatchtoken);
viewPager. setOffscreenPageLimit(2);
viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
tabLayout.setupWithViewPager(viewPager);
return x;
}
class MyAdapter extends FragmentPagerAdapter {
Order order;
Home home;
public MyAdapter(FragmentManager fm) {
super(fm);
}
/**
* Return fragment with respect to Position .
*/
#Override
public Fragment getItem(int position)
{
switch (position){
//Here u can put your fragment files for swipe
case 0 : return new Dispatchorder();
case 1 : return new DispatchOrderTokenComplete();
}
return null;
}
#Override
public int getCount() {
return int_items;
}
/**
* This method returns the title of the tab according to the position.
*/
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0 :
//Here you can put the name of tabs.
return "Pending Order";
case 1 :
return "Complete Order";
}
return null;
}
}
}
Here the xml :-
<LinearLayout 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"
tools:context="com.Weal.sachin.omcom.TabFragment"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/sliding_tabs_dispatchtoken"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#11977c"
app:tabTextColor="#d2cece"
app:tabSelectedTextColor="#fff"
/>
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v4.view.ViewPager
android:id="#+id/viewpagerdispatchtoken"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white">
android:background="#color/white">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/framelayout1"></FrameLayout>
</android.support.v4.view.ViewPager>
</android.support.design.widget.CoordinatorLayout>
</LinearLayout>
Hope this will help you... :)
I am using TabLayout inside a Fragment to display three fixed tabs and the tabs are working but it doesn't show the tab text even after I set the app:tabTextColor attribute in the layout it's still not visible.
NewFragment.java
public class NewFragment extends Fragment {
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private RecyclerView.Adapter mAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View inflatedView = inflater.inflate(R.layout.new_fragment, container, false);
TabLayout tabLayout = (TabLayout) inflatedView.findViewById(R.id.tabLayout);
tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
final ViewPager viewPager = (ViewPager) inflatedView.findViewById(R.id.viewpager);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
viewPager.setAdapter(new PagerAdapter(getFragmentManager(), tabLayout.getTabCount()));
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setupWithViewPager(viewPager);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
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) {
}
});
return inflatedView;
}
public class PagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;
public PagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FragmentTab();
case 1:
return new FragmentTab();
case 2:
return new FragmentTab();
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
}
newfragment.xml
<android.support.design.widget.AppBarLayout 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"
tools:context=".NewFragment">
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabTextColor="#ffffff"
app:tabGravity="fill"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"/>
</android.support.design.widget.AppBarLayout>
The problem is you're calling setupWithViewPager() after setting up your tabs with the addTab() calls, effectively overwriting them.
From the documentation of TabLayout regarding setupWithViewPager():
The tabs displayed in this
layout will be populated from the ViewPager adapter's page titles.
If you would like to use your TabLayout with a ViewPager, you should override getPageTitle() in your PagerAdapter (and remove the addTab() calls, they are redundant).
For example:
public class ExamplePagerAdapter extends FragmentStatePagerAdapter {
// tab titles
private String[] tabTitles = new String[]{"Tab1", "Tab2", "Tab3"};
public ExamplePagerAdapter(FragmentManager fm) {
super(fm);
}
// overriding getPageTitle()
#Override
public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new Tab1Fragment();
case 1:
return new Tab2Fragment();
case 2:
return new Tab3Fragment();
default:
throw new RuntimeException("Invalid tab position");
}
}
#Override
public int getCount() {
return tabTitles.length;
}
// ...
}
i added tab text and icon for each tab after calling tabs.setupWithViewPager(viewPager)
viewPager.setAdapter(new MyViewAdapter(getSupportFragmentManager()));
TabLayout tabs=(TabLayout) findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
tabs.getTabAt(0).setIcon(R.drawable.icon1);
tabs.getTabAt(1).setIcon(R.drawable.icon2);
tabs.getTabAt(0).setText(getResources().getText(R.string.tab1));
tabs.getTabAt(1).setText(getResources().getText(R.string.tab2));
I'm using Kotlin and have spent an hour to find the bugs with this code.
var viewPager: ViewPager = view.findViewById(R.id.viewPager)
...
adapter = TabAdapter(fragmentManager!!)
adapter.addFragment(Fragment1(), "Fragment 1")
adapter.addFragment(Fragment2(), "Fragment 2")
viewPager.adapter = adapter
tabLayout.setupWithViewPager(viewpager)
I can compile this with no error, but the tab title is not showing until I realize the viewpager I assigned to the tabLayout is not viewPager (notice the capitalize 'P'). It's not producing error because kotlin will find any matching layout id, in this case "viewpager" which is a ViewPager but on another view.
I wanted to define TabItem in XML instead of doing it programmatically. As you mentioned, this setupWithViewPager() call resets the text and icon of the tab items to null( It uses the same tab object, just resets its content). I used your approach but made it more reusable. Here is my code:
public class TabLayoutUtil {
public static void setupTabLayoutWithViewPager(TabLayout tabLayout, ViewPager viewPager) {
ArrayList<Pair<CharSequence, Drawable>> tabsContentCopy= new ArrayList<>();
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab = tabLayout.getTabAt(i);
tabsContentCopy.add(new Pair<>(tab != null ? tab.getText() : null, tab != null ? tab.getIcon() : null));
}
tabLayout.setupWithViewPager(viewPager);
for (int i = 0; i < tabLayout.getTabCount(); i++) {
if (i<tabsContentCopy.size()) {
tabLayout.getTabAt(i).setText(tabsContentCopy.get(i).first);
tabLayout.getTabAt(i).setIcon(tabsContentCopy.get(i).second);
}
}
}
}
android.support.design.widget.TabLayout not working properly with ViewPager
If I set tabLayout.setupWithViewPager(viewPager); then tablayout view not showing please find attached screen shots.
<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:fitsSystemWindows="false"
android:orientation="vertical"
tools:context=".home.HomeActivity"
tools:showIn="#layout/activity_home">
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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_layout"/>
Fragment Code :
TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tab_layout); tabLayout.addTab(tabLayout.newTab().setText(getActivity().getResources().getText(R.string.feeds))); tabLayout.addTab(tabLayout.newTab().setText(getActivity().getResources().getText(R.string.following))); tabLayout.addTab(tabLayout.newTab().setText(getActivity().getResources().getText(R.string.you)));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager) view.findViewById(R.id.pager);
final PageAdapter adapter = new PageAdapter(getChildFragmentManager(), 3);
viewPager.setOffscreenPageLimit(3);
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
When remove "tabLayout.setupWithViewPager(viewPager);" the view is working fine. But I need navigate respective fragment when click on respective tab.
In my case I solved this by replacing,
tabLayout.setupWithViewPager(viewPager);
By,
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) {
}
});
I hope this will help you out.
Incase if you are using tabLayout inside fragment try this answer
Possible mistake
you need to pass getChildFragmentManager() to FragmentPagerAdapter
not getSupportFragmentManager() or getFragmentManager()
//wrong one
ViewPagerAdapter adapter = new ViewPagerAdapter(getActivity().getSupportFragmentManager());
//correct one
ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
ViewPagerAdapter is FragmentPagerAdapter
public class ViewPagerAdapter extends FragmentPagerAdapter {
}
Short version of solution (Naveen Kumar M):
viewPager.addOnPageChangeListener(
new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(
new TabLayout.ViewPagerOnTabSelectedListener(viewPager));
try this
add this to viewpager.
app:layout_behavior="#string/appbar_scrolling_view_behavior"
Also keep to parent as Coordinator layout then only scrolling will work fine
Refer here:http://coderzpassion.com/working-appbarlayout-like-whatsapp/
Check the getCount().
DON'T RETURN IT TO NULL! RETURN TO blankFragment.
package my.package;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
public class tabPagers extends FragmentStatePagerAdapter {
String[] titles = new String[]{"Home", "Campus", "Course"};
public tabPagers(FragmentManager fm) {
super(fm);
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
#Override
public Fragment getItem(int position) {
BlankFragment blankFragment = new BlankFragment();
Blank2Fragment blank2Fragment = new Blank2Fragment();
Blank3Fragment blank3Fragment = new Blank3Fragment();
switch (position) {
case 0:
return blankFragment;
case 1:
return blank2Fragment;
case 3:
return blank3Fragment;
}
return blankFragment; //This one is important
}
#Override
public int getCount() {
return titles.length; //This one is important too
}
}
https://developer.android.com/reference/com/google/android/material/tabs/TabLayout#viewpager-integration
<androidx.viewpager.widget.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top" />
</androidx.viewpager.widget.ViewPager>
im using new away to use tabs with viewPager, but i dont know how to know what is the current fragment showing.
At the moment im getting an issue, that is loggint two items on method getItems, from pagerAdapater. I mean, when fragment loads, i see two getItems logs.
So, i dont know what is the fragament shwoing at the moment, and pass that information for my class fragment.
I have two classes
SlidingTabLayout and SlidingTabStrip, in my project.
And my classes...
Note: I didnt post my Fragment class, because is a simple class and doesnt matter for debug, because issue is happening before.
MyActivity
public class MyFragmentActivity extends ActionBarActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(myactivity.xml);
Toolbar toolbar = (Toolbar) this.findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
}
ViewPager mViewPager = (ViewPager) this.findViewById(R.id.viewpager);
mViewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
SlidingTabLayout mSlidingTabLayout = (SlidingTabLayout) this
.findViewById(R.id.sliding_tabs);
mSlidingTabLayout.setViewPager(mViewPager);
}
}
MyPagerAdapter
public class MyPagerAdapter extends FragmentPagerAdapter{
private static int TABS = 6;
public MyPagerPagerAdapter(FragmentManager fm) {
super(fm);
}
/**
* Return the Fragment associated with a specified position.
*/
#Override
public Fragment getItem(int position) {
Log.d("Just for log:" + position);
return new MyFragment();
}
/**
* Return the number of views available.
*/
#Override
public int getCount() {
return TABS;
}
#Override
public CharSequence getPageTitle(int position) {
switch(position){
case 0: return "TAB 1";
case 1: return "TAB 2";
case 2: return "TAB 3";
case 3: return "TAB 4";
case 4: return "TAB 5";
case 5: return "TAB 6";
}
return "";
}
}
myactivity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
<my.package.common.view.SlidingTabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</my.package.common.view.SlidingTabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#android:color/white" >
</android.support.v4.view.ViewPager>
</LinearLayout>
Every class that extends Fragment can override the following method:
#Override
public void setUserVisibleHint(boolean isVisibleToUser)
so, this gives you (or the fragment) the information that it is now
becoming visible (or unvisible). You can then pass this information
to holder Activity class.