6

In my Activity I've added a Gallery-like View using Dave Smith's PagerContainer example and the code I'm using to instantiate it is very similar to the PagerActivity in his example, while I changed the layout because I needed to use layout weights:

<?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">

    <com.example.myapp.PagerContainer
        android:id="@+id/pager_container"
        android:layout_width="match_parent"
        android:overScrollMode="never"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp"
        android:layout_height="0dp"
        android:layout_weight="0.66"
        >
        <android.support.v4.view.ViewPager
            android:layout_width="150dp"
            android:overScrollMode="never"
            android:layout_height="match_parent"
            android:layout_gravity="center" />
    </com.example.myapp.PagerContainer>

    <ImageView
        android:layout_width="150dp"
        android:layout_height="0dp"
        android:layout_weight="0.34"
        android:id="@+id/current_selection_logo"
        android:layout_gravity="center_horizontal"/>

</LinearLayout>

Now my ViewPager works properly and looks like this (I omitted the bottom ImageView)

current viewpager

But I'd like to resize the unselected items, aiming to emphasize the centered item (selection), something like:

wanted_viewpager

or:

wanted_viewpager_min

I've found the accepted answer to this question, but implementing that solution means that I'll make the selection bigger than its current dimensions (which already are the maximum possible).

So I was thinking to edit instantiateItem in the PagerAdapter  to set reduced width and height, and in onPageSelected use the approach shown in the question.

The problem is that I'm not sure about which kind of LayoutParams I should call and calling getWidth() and getHeight() in instantiateItem returns 0.

Currently I'm using:

View v = container.getChildAt(position);
PagerContainer.LayoutParams params = (PagerContainer.LayoutParams)v.getLayoutParams();

but it sometimes works and sometimes throws a NPE.

Is my approach correct or should I proceed in another way? In both cases, what should I change to achieve what I want?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Vektor88
  • 4,841
  • 11
  • 59
  • 111

3 Answers3

7

To achieve this result, I ended up using PixPlicity's MultiViewPager and coding a simple PageTransformer as suggested by @Blackbelt:

private float mScale = 0.8f;
private class ScalePageTransformer implements ViewPager.PageTransformer{
    @Override
    public void transformPage(View view, float position) {
        if(position==0){
            ViewCompat.setScaleX(view, 1);
            ViewCompat.setScaleY(view, 1);
        }
        else{
            ViewCompat.setScaleX(view, mScale);
            ViewCompat.setScaleY(view, mScale);
        }
    }
}

The result is something like: result

Vektor88
  • 4,841
  • 11
  • 59
  • 111
  • You're welcome @KishanSoni, if you play a bit with the float `position` argument, you can even set different sizes according to the distance from the center item. – Vektor88 Oct 27 '15 at 08:13
5

You have to use a PageTransform for this purpose. The callback you have to implement receives two parameters. The former is the View object, the latter is an int. When its value is zero, it means the view objects refers to the fully visible object to the center. -1 and -1, are the fully visible views to the left and right respectively. You can use this value to implement the transformation you want. Using ViewCompat, for instance, you can change the translationX, translationY and Scale values

Blackbelt
  • 156,034
  • 29
  • 297
  • 305
  • If I understood correctly, PageTransform only affects the selected page and the two adjacent ones. What if I'm on a tablet or landscape mode and I can actually see more than three pages at once? – Vektor88 Dec 13 '14 at 19:12
  • It's true when you use the normal implementation. With the PageContainer trick you'll get more. It's something that I discovered recently. What I can suggest you is to give it try – Blackbelt Dec 13 '14 at 19:15
  • I ended using a custom `PageTransformer`. Even if there's more than three pages visible the effect is shown properly! – Vektor88 Dec 14 '14 at 14:28
  • I am doing exactly the same. But my i want to show 3 pages on screen at a time. I have done it successfully but the problem is that the scaled pages i.e (1st and 3nd) page's views aren't clickable. Middle one isn't scaled and its views are clickable. – Zeeshan Shabbir Jul 13 '17 at 11:02
  • @ZeeshanShabbir, you will have to subclass ViewPager and handle the touch events. You might need to use one between View.getLocationOnScreen() and/or getLocationInWindow() – Blackbelt Jul 13 '17 at 12:03
  • Thanks. @Blackbelt Kindly can you look into this? https://stackoverflow.com/q/45072946/5275639 – Zeeshan Shabbir Jul 13 '17 at 12:08
3

I have the same problem like this. My solution is use MultipleViewPager + PagerTransformer

and it works fine.

hungkk
  • 338
  • 3
  • 11