Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PagerTabStrip position within ViewPager

I have the following code:

 <android.support.v4.view.ViewPager
    android:id="@+id/main_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v4.view.PagerTabStrip
        android:id="@+id/pager_tab_strip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
         />
</android.support.v4.view.ViewPager>

and everything gets layouted like it should.

What I want now is that the PagerTabStrip overlays the ViewPager.

It should be rendered on top without taking up any layouting space. Basically the fragments in the ViewPager should start at 0,0 like the PagerTabStrip is doing.

Any help appreciated. Thanks!

like image 463
ppx Avatar asked Jan 29 '13 15:01

ppx


People also ask

What is difference between ViewPager and ViewPager2?

ViewPager2 is an improved version of the ViewPager library that offers enhanced functionality and addresses common difficulties with using ViewPager . If your app already uses ViewPager , read this page to learn more about migrating to ViewPager2 .

How the ViewPager is implemented?

Implement Swipe Views You can create swipe views using AndroidX's ViewPager widget. To use ViewPager and tabs, you need to add a dependency on ViewPager and on Material Components to your project. To insert child views that represent each page, you need to hook this layout to a PagerAdapter .

Can we add activity in ViewPager?

You can't use ViewPager to swipe between Activities . You need to convert each of you five Activities into Fragments , then combine everything in one FragmentActivity with the Adapter you use with ViewPager .

When should I use ViewPager?

ViewPager in Android is a class that allows the user to flip left and right through pages of data. This class provides the functionality to flip pages in app. It is a widget found in the support library. To use it you'll have to put the element inside your XML layout file that'll contain multiple child views.


1 Answers

I finally found a way to do this.

In the onAttachedToWindow of the PagerTitleStrip, this checks for the parent to be a ViewPager:

final ViewParent parent = getParent();
 if (!(parent instanceof ViewPager)) {
  throw new IllegalStateException("PagerTitleStrip must be a direct child of a ViewPager.");
}   

Therefore this needs to go.

Solution:

I solved it now by creating my own custom PagerTitleStrip/PagerTabStrip. I removed the above behaviour and replaced it by a styleable attribute for my PagerTitleStrip which points to the ViewPager. This is defined in values/attrs.xml like this:

<declare-styleable name="PagerTitleStripCustom">
    <attr name="parentViewPager" format="reference" />
</declare-styleable>

And read in the PagerTitleStrip constructor like this:

TypedArray types = context.obtainStyledAttributes(attrs,R.styleable.PagerTitleStripCustom, 0, 0);   
pagerID = types.getResourceId(R.styleable.PagerTitleStripCustom_parentViewPager, 0);

In the onAttachedToWindow we can now check for the mViewPager variable being null and assign it to our pagerID like this:

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();

    final ViewParent parent = getParent();

    ViewPager pager = null;

    if (pagerID != 0) {
        View test2 = ((View) parent).findViewById(pagerID);
        pager = (ViewPager) test2;
    } else if (pagerID == 0 && (parent instanceof ViewPager)) {
        pager = (ViewPager) parent;
    } else if (pagerID == 0 && !(parent instanceof ViewPager)) {
        throw new IllegalStateException("PagerTitleStrip is neither a direct child of a ViewPager nor did you assign the ID of the ViewPager.");
    } else {
        throw new IllegalStateException("PagerTitleStrip: Something went completely wrong.");
    }

    final PagerAdapter adapter = pager.getAdapter();

    pager.setInternalPageChangeListener(mPageListener);
    pager.setOnAdapterChangeListener(mPageListener);
    mPager = pager;
    updateAdapter(mWatchingAdapter != null ? mWatchingAdapter.get() : null, adapter);
}

Now the PagerTitleStrip/PagerTabStrip control can be freely positioned in the layout like this:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:custom="http://schemas.android.com/apk/res/com.YOUR.PATH"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

 <android.support.v4.view.ViewPager
     android:id="@+id/main_pager"
     android:layout_width="match_parent"
     android:layout_height="match_parent" />

 <android.support.v4.view.PagerTabStripCustom
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     custom:parentViewPager="@id/main_pager" />

</RelativeLayout>

This is just the quick and dirty proof of concept. Hope this helps someone.

like image 75
ppx Avatar answered Oct 03 '22 11:10

ppx