4

I am using a tablayout inside a fragemnt, the TabLayout has two fragments: one is showing a calendar and the other is just a simple plain text, I can switch between tabs correctly with out triggering any error, the problem is the content (inner fragments) are not showing, they are just "not there"!

  • I tried looking into other threads on StackoverFlow that has the same issue, but most of them they are facing problems with NPEs (Null pointer exceptions) errors, which is not my case.

  • I tried using: getChildFragmentManager() and getFragmentManager() instead of getSupportFragmentManager()

  • Please keep in mind that I am working with Nested fragments(fragments in a fragment)

  • I am using the documentation of AndroidHive and I have used it before but with simple fragments not nested one, it works perfectly

  • I tried using the Layout Inspector tool.

Q: What am I missing and what should I do to get it up and running?!

Here's my code so far:

XML: MainFragment

<LinearLayout
   android:orientation="vertical"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content">
   <android.support.design.widget.TabLayout
       android:id="@+id/tabs"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       app:tabMode="fixed"
       app:tabGravity="fill"/>
       <android.support.v4.view.ViewPager
           android:id="@+id/viewpager"
           android:layout_height="match_parent"
           android:layout_width="match_parent"
           app:layout_behavior="@string/appbar_scrolling_view_behavior">
       </android.support.v4.view.ViewPager>
</LinearLayout>

XML: Calendar fragment

<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="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:animateLayoutChanges="true"
    android:id="@+id/main_content"
    tools:context=".Tabs.CalendarTab">
    <com.github.sundeepk.compactcalendarview.CompactCalendarView
        android:visibility="visible"
        android:id="@+id/compact_calendar"
        android:layout_width="match_parent"
        android:paddingRight="6dp"
        android:paddingLeft="6dp"
        android:layout_height="250dp"
        app:compactCalendarTargetHeight="250dp"
        app:compactCalendarTextSize="12sp"
        app:compactCalendarBackgroundColor="@color/colorWhite"
        app:compactCalendarTextColor="@color/colorDarkGrey"
        app:compactCalendarCurrentDayBackgroundColor="@color/color13"
        app:compactCalendarMultiEventIndicatorColor="@color/textColor2"
        app:compactCalendarShouldSelectFirstDayOfMonthOnScroll="true"
        app:compactCalendarCurrentDayIndicatorStyle="fill_large_indicator"/>
</RelativeLayout>

XML List fragment

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="250dp"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".Tabs.FullListTab">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="You Are In Tab 2"
        android:id="@+id/textView"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />
</RelativeLayout>

MainFragment JAVA

private TabLayout tabLayout;
private ViewPager viewPager;

//onCreate Method:
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) view.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
/*** end onCreate() ***/

private void setupViewPager(ViewPager viewPager) {
    ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
    adapter.addFragment(new CalendarTab(), "Calendar");
    adapter.addFragment(new FullListTab(), "List");
    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);
    }
}
Thorvald
  • 3,424
  • 6
  • 40
  • 66

3 Answers3

2
adapter.addFragment(new CalendarTab(), "Calendar");
adapter.addFragment(new FullListTab(), "List");

...

class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();

Don't do this, EVER. It can lead to VERY cryptic bugs. You MUST return the new Fragment instance from inside getItem(), and not from elsewhere.



As for your actual question,

XML: MainFragment

<LinearLayout
   android:orientation="vertical"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content">

Change this to match_parent, match_parent.

EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
  • I am using something like your answer. `ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager(); adapter.AddFragment(new FragmentHistory(), ""); adapter.AddFragment(new FragmentBookmark(), ""); adapter.AddFragment(new FragmentSettings(), ""); mViewPager.setAdapter(adapter); mTabLayout.setupWithViewPager(mViewPager);`. Why you said **to never do this**, which is the another way to achieve that ? – TheCoderGuy May 23 '19 at 13:23
  • @Spritzig If you do that, you will have this problem: https://stackoverflow.com/questions/55753099/app-crash-after-activity-has-been-killed-in-background/55754360#55754360 (but you can also find same problem in https://stackoverflow.com/q/53978606/2413303 ) – EpicPandaForce May 23 '19 at 13:25
  • @EpicPandaForce for the first part, thank you for the informative tip, I'll work on improving it! but changing the width and height to `match_parent` didn't solve it, it's like the views visibility is set to `Gone` there's nothing there except the tab titles!! also, are you keeping in mind that all of this is inside another parent fragment ? – Thorvald May 23 '19 at 13:28
  • That it is in another parent fragment should already be solved by using `getChildFragmentManager()`. This sounds like layout size problem. However it wasn't what I thought it would be, so you might want to consider using `Layout Inspector` tool to see which of your views has a `0,0` size instead of something you actually expect. – EpicPandaForce May 23 '19 at 13:28
  • @EpicPandaForce thank you for the tips but for the moment it has been more than a year I use `java` and I have added `fragment` for `viewpager` like comment above and I didn't have any crash or something but I will check your answers there and get which is the best approach again thanks. If do you have time please check for my last question I need an answer there. – TheCoderGuy May 23 '19 at 13:33
  • @Spritzig this comes up in an evident way only if you test for this scenario: https://stackoverflow.com/questions/49046773/singleton-object-becomes-null-after-app-is-resumed/49107399#49107399 – EpicPandaForce May 23 '19 at 13:39
  • @EpicPandaForce I used Layout Inspector, great tool, it just gave me a lot of readings, but the fragments are still not showing in the graphic representation – Thorvald May 23 '19 at 15:21
  • @EpicPandaForce I am facing a problem, can you please have a look at my question https://stackoverflow.com/questions/56324415/realm-greater-than-query-on-a-string-value thanks. – Sudhanshu Gaur May 27 '19 at 10:38
1

I had a similar problem to this in the past. I solved it by nesting the TabLayout in the ViewPager, as seen in the documentation:

<LinearLayout
  android:orientation="vertical"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content">

  <android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <android.support.design.widget.TabLayout
      android:id="@+id/tabs"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      app:tabMode="fixed"
      app:tabGravity="fill"/>

  </android.support.v4.view.ViewPager>
</LinearLayout>
Ricardo Costeira
  • 3,171
  • 2
  • 23
  • 23
  • 1
    What? No you don't – EpicPandaForce May 23 '19 at 13:19
  • I had this problem a few weeks ago, and solved it by nesting the TabLayout. Unless it was another bug that got "fixed" by doing this :P anyway, I followed the documentation: https://developer.android.com/reference/android/support/design/widget/TabLayout#viewpager-integration – Ricardo Costeira May 23 '19 at 13:26
  • Hmm, `as part of a ViewPager's decor`.. I wonder what that means. But yeah, apparently you *can* put it inside a ViewPager. I don't think you have to, though. It works even if it isn't. – EpicPandaForce May 23 '19 at 13:29
  • 1
    Yeah, I was not nesting it to begin with, as most examples online don't as well. I didn't understand the "decor" part too, but I tried to nest it and it fixed my problem. My problem was similar to the one OP has, and hence the "You have to nest". I guess I'll edit the answer to be more clear. – Ricardo Costeira May 23 '19 at 13:33
  • @RicardoCosteira probably that's not the problem, I tried it but no luck – Thorvald May 23 '19 at 13:40
1

I managed to solve this issue by using a third party library called SPager here's the Github link for full documentation. SPager does not use an adapter and it's easier and faster to implement.

HOWEVER I AM STILL LOOKING FOR A ANOTHER WAY WITHOUT USING A THIRD PARTY LIBRARY

This is what I practically did (as mentioned in their Github):

Implementation

implementation 'com.github.alfianyusufabdullah:spager:1.2.0'

in the XML layout file

<com.alfianyusufabdullah.SPager
   android:id="@+id/mPager"
   android:layout_width="match_parent"
   android:layout_height="match_parent" />

in my JAVA class

private SPager myViewPager;

//...

myViewPager = view.findViewById(R.id.mPager);

//...

myViewPager.initFragmentManager(getChildFragmentManager());
myViewPager.addPages("Inner fragment 1", new IFragOne());
myViewPager.addPages("Inner fragment 2", new IFragTwo());
myViewPager.build();

IF you are using a tabLayout you can bind it with SPager like so:

myViewPager.addTabLayout(tabLayout);

I should also mention that SPager is compatible with Kotlin

I decided to post, it might be useful to others, for my case this is a temporary fix until, someone answers this thread!

Thorvald
  • 3,424
  • 6
  • 40
  • 66