Adding Tab Inside Fragment in Android

Fragment Tabs inside Fragment

See below answer that I achieved with using fragment tabs inside fragment tabs that are in my MainActivity

Inside my fragment using getChildFragmentManager()

public class FixturesTabs extends Fragment {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.fixtures_new_tabs,container, false);
// Setting ViewPager for each Tabs
ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
setupViewPager(viewPager);
// Set Tabs inside Toolbar
TabLayout tabs = (TabLayout) view.findViewById(R.id.result_tabs);
tabs.setupWithViewPager(viewPager);

return view;

}

// Add Fragments to Tabs
private void setupViewPager(ViewPager viewPager) {

Adapter adapter = new Adapter(getChildFragmentManager());
adapter.addFragment(new TodaysFixturesFragment(), "Today");
adapter.addFragment(new WeekFixturesFragment(), "Week");
adapter.addFragment(new MonthFixturesFragment(), "Month");
adapter.addFragment(new AllFixturesFragment(), "Month");
adapter.addFragment(new MyTeamsFixturesFragment(), "My Teams");
viewPager.setAdapter(adapter);

}

static class Adapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();

public Adapter(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);
}
}

}

And my XML named "fixtures_new_tabs.xml" to match the inflated layout

<?xml version="1.0" encoding="utf-8"?>
<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.support.design.widget.CoordinatorLayout
android:id="@+id/main_content"
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.design.widget.TabLayout
android:id="@+id/result_tabs"
android:background="@color/grey"
app:tabTextColor="@color/medium_grey"
app:tabSelectedTextColor="@color/colorPrimary"
app:tabIndicatorColor="@color/colorPrimary"
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/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</android.support.design.widget.CoordinatorLayout>

</RelativeLayout>

Hope this helps or points others in the direction for their solution..

P.S. If you get a white screen after implementing this, you might have added the same parent fragment to it's child fragment.

How to add tab inside fragment in android?

I believe this could work for you, if you are targeting API17 +. If not you should take a look at ViewContainers, and swipeable views.

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTabHost;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class TabHostParentFragment extends Fragment {

private FragmentTabHost tabHost;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
tabHost = new FragmentTabHost(getActivity());
tabHost.setup(getActivity(), getChildFragmentManager(), R.layout.my_parent_fragment);

Bundle arg1 = new Bundle();
arg1.putInt("Arg for Frag1", 1);
tabHost.addTab(tabHost.newTabSpec("Tab1").setIndicator("Frag Tab1"),
NewsFragment.class, arg1);

Bundle arg2 = new Bundle();
arg2.putInt("Arg for Frag2", 2);
tabHost.addTab(tabHost.newTabSpec("Tab2").setIndicator("Frag Tab2"),
MyNestedFragment2.class, arg2);

return tabHost;
}

Android TabLayout inside Fragment

After looking into yours code, I found that you forget to return a fragment in getItem method of PagerAdapter that you overrided from the FragmentStatePagerAdapter and there is no break statement in each case due to which every time a null value was returned.

To doing so you need to create a another new fragment for each page in ViewPager or you can create one new fragment that could use in all page of ViewPager.

You can't use the same recyclerview into the tabs of view pager that you have defined in parent fragment.

activity_fragment_one.xml

 <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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".NewFragment">

<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">

<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:tabTextAppearance="?android:attr/textAppearanceMedium"
app:tabTextColor="#ffffff"
android:layout_height="?android:actionBarSize"
app:tabMode="fixed"
app:tabGravity="fill"/>

</android.support.design.widget.AppBarLayout>

<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:background="@android:color/white"/>
</android.support.design.widget.CoordinatorLayout>

I have fixed your fragment and created a new Fragment that you can use in ViewPager Pages.

public class NewFragment extends Fragment {

private RecyclerView mRecyclerView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_fragment_one, container, false);
TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tabs);
tabLayout.addTab(tabLayout.newTab().setText("A"));
tabLayout.addTab(tabLayout.newTab().setText("B"));
tabLayout.addTab(tabLayout.newTab().setText("C"));
final ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
// mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
//mRecyclerView.setLayoutManager(mLayoutManager);
viewPager.setAdapter(new PagerAdapter(getFragmentManager(), tabLayout.getTabCount()));
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setupWithViewPager(viewPager);
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
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 view;
}

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;
}
}
}

FragmentTab for each Page in View Pager (or you can create different fragment for each page according to yours need).

public class FragmentTab extends Fragment {
RecyclerView mRecyclerView;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tab, container, false);

mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(mLayoutManager);
RecyclerView.Adapter mAdapter = new AdapterOne();
mRecyclerView.setAdapter(mAdapter);
return view;
}
}

fragment_tab.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

</LinearLayout>

Put Tabs inside a Fragment of the BottomNavigationView

When you declare a variable as val, it is the same as declaring it as final in Java; once it's been assigned, it cannot be changed. In addition, vals declared on the class-level cannot be initialized from other methods than the constructor. Declaring a val in a method follows different rules; it needs to be assigned, but it doesn't need to be right away. The only requirement is initialization before accessing, but this is because vals and vars in methods are different than class-level ones

Which means, since you assign the val instantly, it's locked to be null. Since you try changing it in onCreate, you get an error because you cannot reassign a val that's already been assigned.

Which means, since you aren't assigning it in the constructor (/init block) or something similar, you have to use var. I recommend you use lateinit var, because this enables you to maintain null safety, as you don't need to initialize it. Lateinit is exactly what you'd think it means; late initialization. So change the declaration of your fields to:

private lateinit var tabLayout: TabLayout
private lateinit var firstViewPager: ViewPager

Android Adding Tab inside Fragment

I believe this could work for you, if you are targeting API17 +.
If not you should take a look at ViewContainers, and swipeable views.

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTabHost;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class TabHostParentFragment extends Fragment {

private FragmentTabHost tabHost;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
tabHost = new FragmentTabHost(getActivity());
tabHost.setup(getActivity(), getChildFragmentManager(), R.layout.my_parent_fragment);

Bundle arg1 = new Bundle();
arg1.putInt("Arg for Frag1", 1);
tabHost.addTab(tabHost.newTabSpec("Tab1").setIndicator("Frag Tab1"),
NewsFragment.class, arg1);

Bundle arg2 = new Bundle();
arg2.putInt("Arg for Frag2", 2);
tabHost.addTab(tabHost.newTabSpec("Tab2").setIndicator("Frag Tab2"),
MyNestedFragment2.class, arg2);

return tabHost;
}


Related Topics



Leave a reply



Submit