0

I have a activity whose content view is a fragment, I added viewpager and viewpagerindicator to this activity. I created an FragmentPagerAdapter for the pager, the adapter constructs three fragments for displaying three tabs. But when I run the project, only see the pager title shows up. Why doesn`t the three fragments show up?

I created the pager and indicator on create of the Activity lifecycle.

    public class BrowserActivity extends SherlockFragmentActivity
                        implements ReposFragment.OnFileSelectedListener, StarredFragment.OnStarredFileSelectedListener, OnBackStackChangedListener {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.seadroid_main);
    adapter = new SeafileTabsAdapter(getSupportFragmentManager());

    pager = (ViewPager) findViewById(R.id.pager);
    pager.setAdapter(adapter);

    TabPageIndicator indicator = (TabPageIndicator)findViewById(R.id.indicator);
    indicator.setViewPager(pager);
    indicator.setOnPageChangeListener(new OnPageChangeListener() {
        @Override
        public void onPageSelected(final int position) {
            currentPosition = position;
            supportInvalidateOptionsMenu();
            disableUpButton();
        }

        @Override
        public void onPageScrollStateChanged(int arg0) {
            // TODO Auto-generated method stub
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
            // TODO Auto-generated method stub
        }
    });

the adapter constructs three fragments for displaying three tabs view

class SeafileTabsAdapter extends FragmentPagerAdapter implements
IconPagerAdapter {
    public SeafileTabsAdapter(FragmentManager fm) {
        super(fm);
    }

    private ReposFragment reposFragment = null;
    private ActivitiesFragment activitieFragment = null;
    private StarredFragment starredFragment = null;

    @Override
    public Fragment getItem(int position) {
        switch (position) {
        case 0:
            if (reposFragment == null) {
                reposFragment = new ReposFragment();
            }
            return reposFragment;
        case 1:
            if (starredFragment == null) {
                starredFragment = new StarredFragment();
            }
            return starredFragment;
        case 2:
            if (activitieFragment == null) {
                activitieFragment = new ActivitiesFragment();
            }
            return activitieFragment;
        default:
            return new Fragment();
        }
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
        case 0:
            return getString(R.string.tabs_library).toUpperCase();
        case 1:
            return getString(R.string.tabs_starred).toUpperCase();
        case 2:
            return getString(R.string.tabs_activity).toUpperCase();

        default:
            return null;
        }
    }

    @Override
    public int getIconResId(int index) {
        return ICONS[index];
    }

    @Override
    public int getCount() {
        return ICONS.length;
    }
}

the layout file seadroid_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.viewpagerindicator.TabPageIndicator
    android:id="@+id/indicator"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    />
<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    />


UPDATE
I have found that ViewPager tutorials used LineaLayout as the root container. So is it necessary to change FragmentLayout to be LineaLayout here. When I changed to LineaLayout, the app crashed, and the log is

    12-02 07:01:13.636: E/AndroidRuntime(3807): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.seafile.seadroid2/com.seafile.seadroid2.ui.activity.BrowserActivity}: android.view.InflateException: Binary XML file line #21: Error inflating class LineaLayout
12-02 07:01:13.636: E/AndroidRuntime(3807):at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
Logan Guo
  • 740
  • 2
  • 14
  • 33

1 Answers1

0

Try switching the root view in your XML to LinearLayout. Right now you are using FrameLayout, which has the effect of putting your ViewPager on top of your TabPageIndicator. Also, since the layout_height is 0, you're not going to see your fragments. I suspect this is your problem -- clearly you meant to use LinearLayout.

Also, be careful with your SeafileTabsAdapter class. Right now it is caching the fragments, which seemed logical to me when I started using FragmentPagerAdapter too. However, FragmentPagerAdapter caches the fragments too, so you have a danger of a memory leak with this approach. If you want to call getItem directly, without auto-creating a fragment each time, then you can first call findFragmentByTag to see if the fragment is there yet. The string Android uses for the tag can be found in the source, or in this SO question: Replace Fragment inside a ViewPager

Hope this helps. I'm still a bit confused about your code, because in the description you say you have a ViewPager inside a fragment, but the posted code seems to show a ViewPager inside your activity.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.viewpagerindicator.TabPageIndicator
        android:id="@+id/indicator"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        />
    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        />
</LinearLayout>

I hope this answers your concern in your comment. If you instead mean that the sherlock code is expecting a FrameLayout as the root view (this would surprise me, although I haven't used it), then all you need to do is put the LinearLayout above as a child of the FrameLayout you had before. Does that make sense?

Community
  • 1
  • 1
Bruce
  • 2,317
  • 1
  • 14
  • 11
  • Thanks for your comments, but I think I can\`t change the root view to be Linealayout because I used SherlockFragmentActivity. The code segment above just didn\`t show the detail dependents on the SherlockFragmentActivity methods, like getSupportFragmentManager. You can see the complete code [here](https://github.com/haiwen/seadroid/blob/master/src/com/seafile/seadroid2/ui/activity/BrowserActivity.java). – Logan Guo Dec 02 '14 at 05:43
  • I think you misunderstood me. I don't want you to change the class of your activity, I want you to change your seadroid_main.xml file. I've added the modified XML to my answer... – Bruce Dec 02 '14 at 05:54
  • I understand you meaning now, but still can not use Linealayout, the app crashes. – Logan Guo Dec 02 '14 at 06:47
  • Please add the crash stack from logcat to your question. – Bruce Dec 02 '14 at 06:57
  • Plz refresh the page, I already updated the question with log added. – Logan Guo Dec 02 '14 at 07:07
  • Sorry, thanks. Looks like you misspelled LinearLayout (the exception, and your comment, is missing the 'r'). – Bruce Dec 02 '14 at 07:11
  • BTW, do you know how to apply the theme to the indicator? – Logan Guo Dec 02 '14 at 07:20
  • I'm afraid I don't use Sherlock, so I don't know. The app I work on is converting to Lollipop, using ViewPager, so I know a bit more about that. – Bruce Dec 02 '14 at 07:55