I have an application with a TabLayout that has a ViewPager that handles the tabs. The two tabs instantiate different fragments.
What I am trying to achieve is to switch fragments within the same tab. Since each fragment within the same tab holds a different layout (as it relies on a specific user flow), using a FrameLayout and switching it's contents, only creates the new fragment's layout on top of the previous fragment.
Should I create a general fragment with a container and replace it with each fragment? If so, would I need to build the layout for each fragment at runtime?
I have searched online and in SO, but failed to find a solution that addresses my scenario specifically.
Is there a way to achieve this or should I approach this problem from a different angle?
Some code for reference:
MainActivtiy XML:
<?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.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"
tools:context=".Main2Activity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
First fragment's XML:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:gravity="center"
android:layout_gravity="center"
android:orientation="vertical"
android:id="@+id/container">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20dp"
android:gravity="center"
></TextView>
<ProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleLarge"
android:id="@+id/progress_bar"
android:layout_gravity="center">
</ProgressBar>
<GridView
android:rowCount="3"
android:numColumns="2"
android:gravity="center"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:layout_marginLeft="40dp"
>
</GridView>
</FrameLayout>
Second Fragment's 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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:layout_gravity="center"
android:layout_marginBottom="5dp">
</TextView>
<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/myRadioGroup"
android:orientation="horizontal">
</RadioGroup>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:inputType="numberDecimal">
</EditText>
<androidx.appcompat.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:text="Submit"
android:id="@+id/submit_btn">
</androidx.appcompat.widget.AppCompatButton>
</LinearLayout>
-- EDIT --
The code I am using to switch between fragments (found inside the first fragment) is this (while I have tried various others ways as well):
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container,secondFragment, "secondFragment")
.addToBackStack(null)
.commit();
-- EDIT #2 --
Below is the FragmentPagerAdapter code:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
@StringRes
private static final int[] TAB_TITLES = new int[]{R.string.tab_text_1, R.string.tab_text_2};
private final Context mContext;
public SectionsPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
if (position == 1) {
return firstFragment.newInstance("One", "Two");
}
return PlaceholderFragment.newInstance(position + 1);
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return mContext.getResources().getString(TAB_TITLES[position]);
}
@Override
public int getCount() {
// Show 2 total pages.
return 2;
}
}
And this code is from the mainActivity:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}