I have struggled in the past couple of days to find the solution to this problem:
I have one activity which contains a tab layout and a view pager. The view pager is filled with fragments using an adapter. Tabs are created with this viewpager and are fixed. My question is how can I change the layout of tabs dynamically (for example after a button click) ?
This is xml file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark" />
<android.support.design.widget.TabLayout
android:id="#+id/tablayout"
android:layout_width="match_parent"
android:layout_height="65dp"
android:background="#color/white"
app:tabMode="fixed"
app:tabGravity="fill"
android:theme="#style/ThemeOverlay.AppCompat.Dark" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
This is Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupToolbar();
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tablayout);
setupTabLayout(tabLayout);
}
private void setupToolbar(){
...
}
public void setupViewPager(ViewPager viewPager) {
pageAdapter = new FragmentPageAdapter(getApplicationContext(), getSupportFragmentManager());
pageAdapter.addFragment(ContentFragment.newInstance(), "Following", R.drawable.following);
pageAdapter.addFragment(ContentFragment.newInstance(), "Discover", R.drawable.flower);
pageAdapter.addFragment(ContentFragment.newInstance(), "", R.drawable.camera);
pageAdapter.addFragment(ProfileFragment.newInstance(), "Profile", R.drawable.profile);
pageAdapter.addFragment(ContentFragment.newInstance(), "Task List", R.drawable.list);
viewPager.setAdapter(pageAdapter);
}
public void setupTabLayout(TabLayout tabLayout) {
try {
tabLayout.setupWithViewPager(viewPager);
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab = tabLayout.getTabAt(i);
tab.setCustomView(pageAdapter.getTabView(i));
}
tabLayout.requestFocus();
}
catch(Exception ex){
Log.e("errr2", ex.getMessage());
}
}
This is adapter:
public class FragmentPageAdapter extends FragmentStatePagerAdapter {
private Context mContext;
private List<Fragment> mFragments = new ArrayList<>();
private List<String> mFragmentTitles = new ArrayList<>();
private List<Integer> mFragmentIcons = new ArrayList<>();
public FragmentPageAdapter(Context context, FragmentManager fm) {
super(fm);
this.mContext = context;
}
public void addFragment(Fragment fragment, String title, int drawable) {
mFragments.add(fragment);
mFragmentTitles.add(title);
mFragmentIcons.add(drawable);
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getItemPosition(Object object)
{
return POSITION_UNCHANGED;
}
#Override
public int getCount() {
return mFragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
public View getTabView(int position) {
View tab = LayoutInflater.from(mContext).inflate(R.layout.tabbar_view, null);
TextView tabText = (TextView) tab.findViewById(R.id.tabText);
ImageView tabImage = (ImageView) tab.findViewById(R.id.tabImage);
tabText.setText(mFragmentTitles.get(position));
tabImage.setBackgroundResource(mFragmentIcons.get(position));
if (position == 3) {
tab.setSelected(true);
}
return tab;
}
}
The normal way to replace a fragment is by calling
fragmentManager.beginTransaction().replace(placeholderId, editPrifileFragment).commit();
but what should I use for placeholderId in this case ? because in activity layout I don't have a placeholder for fragments, just a viewpager.
So how can I replace the fragment dynamically and also keep the back button functionality ?
I have searched a lot and found some hacky solutions , but I think this is a very common situation and should have a better solution.
thanks.
Your ViewPager Fragment should hold the placeholderId.
So in your Fragment (which is part of the ViewPager) you can call getChildFragmentManager() to add Fragment like you usually do.
childFragmentManager.beginTransaction().add(placeholderId, editPrifileFragment).addToBackStack(null).commit();
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 am trying to add View Pager in Fragment Class. I have tried all stuff.
public class MessageFragment extends android.support.v4.app.Fragment{
private ViewPager viewPager;
private TabLayout tabLayout;
public static MessageFragment newInstance() {
MessageFragment fragment = new MessageFragment();
Log.d("Click", "newInstance: ");
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_message, container, false);
ViewPager viewPager=(ViewPager)view.findViewById(R.id.viewpager);
if(viewPager!=null)
{
setUpViewPager(viewPager);
}
TabLayout tabLayout = (TabLayout)view. findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
tabLayout.setTabTextColors(getResources().getColorStateList(R.color.colorToolbar));
return view;
}
private void setUpViewPager(ViewPager viewPager)
{
Adapter adapter=new Adapter(getActivity().getSupportFragmentManager());
adapter.addFragment(new TabTaskFragment(),"Tasks");
adapter.addFragment(new TabChatFragment(),"Chat");
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);
}
}
}
Here is my xml file, I have added all viewpager code over here
please find
XML FILE:
<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:id="#+id/appbar"
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="wrap_content"
android:visibility="gone"
app:layout_scrollFlags="scroll|enterAlways|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"
android:background="#color/white"
app:tabIndicatorColor="#color/colorToolbar"
app:tabTextAppearance="#android:style/TextAppearance.Widget.TabWidget"
app:tabTextColor="#color/colorToolbar" />
</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" />
How can I add?
I am not able to fix it.
Tabs will show 1st time, but when the user clicks on any bottom tab than tabs description gone and its show blank screens.
I have tried all stuffs disappointed at last.
Your class file should like this
public class ViewPagerFragment extends Fragment {
ViewPager viewPager;
PagerAdapter mPagerAdapter;
TabLayout tabLayout;
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.myLayout, null);
viewPager = (ViewPager) view.findViewById(R.id.transactions_recharge);
mPagerAdapter = new ViewPagerAdapter(getChildFragmentManager(), 7);
viewPager.setAdapter(mPagerAdapter);
tabLayout = (TabLayout) view.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
return view;
}
class ViewPagerAdapter extends FragmentPagerAdapter {
int pageCount = 0;
String titles[] = {"One", "Two", "Three"};
ViewPagerAdapter(FragmentManager manager, int _pageCount) {
super(manager);
pageCount = _pageCount;
}
#Override
public Fragment getItem(int position) {
if (position == 0) {
//load fragment one
return new FragmentOne();
} else if (position == 1) {
//load fragment two
} else if (position == 2) {
//load fragment three
}
}
#Override
public int getCount() {
return pageCount;
}
#Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
}
}
And your XML should me like this.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:id="#+id/content_layout"
android:layout_height="match_parent"
android:background="#color/primary">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="#color/white"
app:tabIndicatorHeight="2dp"
app:tabMode="scrollable" />
<android.support.v4.view.ViewPager
android:id="#+id/transactions_recharge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tabs"
android:background="#android:color/transparent">
</android.support.v4.view.ViewPager>
</RelativeLayout>
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... :)
This should be simple but I can't wrap my head around it.
I am setting up TabLayout with setupViewViewPager such that I have 3 tabs (Home, Tab1, Tab2). How do I set it so that when I click on a link in Tab1, a new fragment replaces the existing fragment?
Your XML layout
<?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">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0">
<include layout="#layout/toolbar" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="50dip"
android:gravity="bottom"
app:tabGravity="center"
app:tabIndicatorColor="#android:color/white"
app:tabMode="scrollable"
app:tabPaddingStart="20dp" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
Your java code
public class ClassName extends AppCompatActivity {
private ViewPager viewPager;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.xml_file_name);
init();
}
private void init() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
viewPager = (ViewPager) findViewById(R.id.viewpager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
setSupportActionBar(toolbar);
setupViewPager();
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager() {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FragmentName1(),"Home");
adapter.addFragment(new FragmentName2(),"Tab1");
adapter.addFragment(new FragmentName3(),"Tab2");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
For reference, I solved my problem by creating a fragment for each tab, each containing a unique FrameLayout.
Next, I used my activity to add a fragment to the FrameLayout (depending on which tab is selected) with FragmentTransaction.
I'm not sure if this is the best solution, but it did work for me.
I have a main activity, which hosts a fragment, which in turn hosts a TabLayout (with a ViewPager). The tab bar is shown, baut the tabs themselves are not shown.
Here is my code in the main activity for displaying the host fragment:
Fragment fragment = new BMITabsFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).addToBackStack(Constants.BMI_TABS_FRAGMENT).commit();
Here is my the Fragment which hosts the TabLayout, which is BMITabsFragment (s.a.):
public class BMITabsFragment extends Fragment {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Get the ViewPager and set it's PagerAdapter so that it can display items
ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
viewPager.setAdapter(new BMIFragmentPagerAdapter(getActivity().getSupportFragmentManager(),
getActivity()));
// Give the TabLayout the ViewPager
TabLayout tabLayout = (TabLayout) view.findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_bmitabs, container, false);
return view;
}
...
}
This is my FragmentPagerAdapter:
public class BMIFragmentPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 2;
private FragmentManager fragmentManager;
private Context context;
public BMIFragmentPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
this.fragmentManager = fm;
}
public BMIFragmentPagerAdapter(FragmentManager fm) {
super(fm);
fragmentManager = fm;
}
#Override
public CharSequence getPageTitle(int position) {
String[] pageTitles = context.getResources().getStringArray(R.array.page_titles_array);
return pageTitles[position];
}
#Override
public Fragment getItem(int position) {
SharedPreferences prefs = context.getSharedPreferences(Constants.SHARED_PREFS_FILE, 0);
long patientId = prefs.getLong(Constants.SELECTED_PATIENT_ID, 1);
Fragment fragment = null;
switch (position){
case 0:
return BMITabelleFragment.newInstance(patientId);
case 1:
return BMIChartFragment.newInstance(patientId);
default:
return BMITabelleFragment.newInstance(patientId);
}
}
#Override
public int getCount() {
return PAGE_COUNT;
}
}
And this is the fragment_bmitabs.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.TabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="#android:color/white" />
</LinearLayout>
My code is based on the Google Android Guide at https://github.com/codepath/android_guides/wiki/Google-Play-Style-Tabs-using-TabLayout
What I am missing here?
Note: I am using AppCompatActivity and the support libraries v4 & v7 and the com:android:support:design library
This fixed it for me:
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
https://code.google.com/p/android/issues/detail?id=180462
Set tab icons after setupWithViewPager()
private void setTabs {
tabLayout.setupWithViewPager(viewPager);
setupTabIcons();
}
private void setupTabIcons() {
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
tabLayout.getTabAt(1).setIcon(tabIcons[1]);
tabLayout.getTabAt(2).setIcon(tabIcons[2]);
}
like #Nathaniel Ford said,this should a bug, I change to use design library 23.0.1。google fixed it,so change build.gradle to compile 'com.android.support:design:23.0.1'. ps:you also must change your compileSdkVersionto 23
None of the other answers worked for me, I tried all of them
However, this one did: TabLayout not showing tabs after adding navigation bar
According to that answer, you have to enclose your TabLayout in a AppBarLayout. Why? Who knows. But at least it works.
Example Code (taken from that post):
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:id="#+id/appBarLayout2">
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tabLayout2"
app:tabMode="fixed"
app:tabGravity="fill"
></android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:id="#+id/viewPager2"
android:layout_below="#+id/appBarLayout2">
</android.support.v4.view.ViewPager>
If you are using android:tabPadding attribute in Tablayout of xml file,remove it.
You can use FragmentStatePagerAdapter instead of FragmentPagerAdapter.
It may help you.
If someone, in future, works with TabLayout along with ViewPager2 and faces same issue. Just add .attach(); at end of new TabLayoutMediator().
new TabLayoutMediator(tabLayoutRef, viewPager2Ref, (tab, position) -> tab.setText("Tab No. "+position)).attach();