I am setting up a ViewPager
which will render fragments depending of the selected tab in a TabLayout
from material. I have a fragment which will be rendering all of this as the parent view (Which i don't know if this could be the cause.), and i am doing all this flow because i would like to set the data flow to be like Master Detail flow
in which an activity will show 2 fragments, one of this will have a pager that displays another fragment in a ViewPager
So the fragment that has both the TabLayout
and ViewPager
have the class defined like this:
public class InstructionsFragment extends Fragment {
private static final String TAG = InstructionsFragment.class.getSimpleName();
private TabLayout instructionsTab;
private ViewPager instructionsPager;
private int recipeIndex;
public InstructionsFragment(int recipeIndex) {
this.recipeIndex = recipeIndex;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_instructions, container, false);
this.loadViews(rootView);
return rootView;
}
@Override
public void onStart() {
super.onStart();
this.loadPager();
}
private void loadViews(View view) {
Log.i(TAG, "Loading views");
this.instructionsTab = view.findViewById(R.id.recipe_instructions_tabs);
this.instructionsPager = view.findViewById(R.id.recipe_instructions_pager);
this.instructionsTab.setupWithViewPager(this.instructionsPager);
}
private void loadPager() {
Log.i(TAG, "Loading pager");
FragmentManager fragmentManager = this.getFragmentManager();
IngredientsFragment ingredientsFragment = new IngredientsFragment(recipeIndex);
InstructionsPagerAdapter instructionsAdapter = new InstructionsPagerAdapter(fragmentManager, 0);
instructionsAdapter.addFragment(ingredientsFragment);
this.instructionsPager.setAdapter(instructionsAdapter);
}
This fragment makes use of the layout defined like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/instructions_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/recipe_instructions_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/recipe_detail_tab_ingredients_label" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/recipe_detail_tab_steps_label" />
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/recipe_instructions_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
So there's basically 2 static tabs and i want to test with just one, because even when i delete one of the tabs it still doesn't work.
The FragmentPagerAdater
is defined in a class like this:
public class InstructionsPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments = new ArrayList<>();
public InstructionsPagerAdapter(@NonNull FragmentManager fm, int behavior) {
super(fm, behavior);
}
public void addFragment(Fragment fragment) {
this.fragments.add(fragment);
}
@NonNull
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
}
When going to the activity which displayes the InstructionsFragment
, The tabs for some reason are not displaying and neither is the fragment selected by default. I did make some debugging in to see if there's an error or if the selected fragment by the viewPager is running, and i don't see any error logs in logcat
and the selected fragment is actually running, so i don't know how to continue.
This is how the screen is displaying all of the code i've implemented:
And this is how it looks without loading the pager code:
I am running the application on Android 9
and these are the dependencies in my project:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
I was able to make it work by adding tabs dynamically, it looks like TabsLayout
from material doesn't support having a static set of tabs in layout while using a ViewPager
. The ViewPager
must have an adapter which feeds the title of the tab for the selected fragment to display in the ViewPager
.
The end code for the FragmentPagerAdapter
looks like this:
public class InstructionsPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments = new ArrayList<>();
private List<String> pageTitles = new ArrayList<>();
public InstructionsPagerAdapter(@NonNull FragmentManager fm, int behavior) {
super(fm, behavior);
}
public void addFragment(Fragment fragment, String tabTitle) {
this.fragments.add(fragment);
this.pageTitles.add(tabTitle);
}
@NonNull
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return this.pageTitles.get(position);
}
}
Adding a list of titles for the fragments and select it when a fragment is selected.