Skip to content
Ruben Gees edited this page Apr 18, 2016 · 3 revisions

Guide for implementing a custom Transformer

Runtime Permissions example

Transformers add cool animations to the transition between your Slides.
In the following guide we will implement a Transformer to fade the colors between each Slides. (Like in the Gif above)

First, we will add a BasePageTransformer, which makes implementation easier for us:

public abstract class BasePageTransformer implements ViewPager.PageTransformer {

    public static boolean inRange(final float position) {
        return position <= 1.0 && position >= -1.0;
    }

    public static boolean isLeftPage(final float position) {
        return position < 0;
    }

    public static boolean isRightPage(final float position) {
        return position > 0;
    }

    @Override
    public void transformPage(final View page, final float position) {
        final int pageIndex = (Integer) page.getTag();

        transformPage(page, pageIndex, position);
    }

    protected abstract void transformPage(final View page, final int pageIndex, final float position);

    @Override
    public String toString() {
        return getClass().getSimpleName();
    }
}

Next we add a ColorSupplier class to get the color for each Slide, based on the position of each:

public class ColorSupplier {

    private static Integer[] colors = new Integer[]{R.color.green, R.color.indigo, R.color.orange};

    @ColorInt
    public static int getColorResForPosition(int position) {
        if (position > colors.length) {
            throw new IllegalArgumentException("The position cannot be larger than the amount of " +
                    "colors");
        }

        return colors[position];
    }

    @ColorInt
    public static int getColorForPosition(@NonNull Context context, int position) {
        if (position > colors.length) {
            throw new IllegalArgumentException("The position cannot be larger than the amount of " +
                    "colors");
        }

        return ContextCompat.getColor(context, colors[position]);
    }

}

We can use that in the generateSlides() method too!

private List<Slide> generateSlides() {
    List<Slide> result = new ArrayList<>();

    result.add(new Slide().withTitle("Title").withDescription("Description")
        .withColor(ColorSupplier.getColorForPosition(this, 0)).withImage(R.drawable.image1));
    result.add(new Slide().withTitle("Gif").withDescription("This is a Gif")
            .withColor(ColorSupplier.getColorForPosition(this, 1));
    result.add(new Slide().withTitle("Option").withOption(new Option("This is an option", true))
            .withColor(ColorSupplier.getColorForPosition(this, 2)).withImage(R.drawable.image2));

    return result;
}

Now we can implement the Transformer:

public class ColorPageTransformer extends BasePageTransformer {

    private static int blendColors(int color1, int color2, float ratio) {
        final float inverseRation = 1f - ratio;
        float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
        float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
        float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
        return Color.rgb((int) r, (int) g, (int) b);
    }

    @Override
    public void transformPage(final View page, final int pageIndex, final float position) {
        if (inRange(position)) {
            if (isRightPage(position)) {

                final int leftIndex = pageIndex - 1;
                final int rightIndex = pageIndex;

                final int leftColor = ColorSupplier.getColorForPosition(page.getContext(),
                        leftIndex);
                final int rightColor = ColorSupplier.getColorForPosition(page.getContext(),
                        rightIndex);

                final int composedColor = blendColors(leftColor, rightColor, position);
                page.setBackgroundColor(composedColor);
            } else if (isLeftPage(position)) {

                final int leftIndex = pageIndex;
                final int rightIndex = leftIndex + 1;

                final int leftColor = ColorSupplier.getColorForPosition(page.getContext(),
                        leftIndex);
                final int rightColor = ColorSupplier.getColorForPosition(page.getContext(),
                        rightIndex);

                final int composedColor = blendColors(leftColor, rightColor, 1 - Math.abs(position));
                page.setBackgroundColor(composedColor);
            } else {
                page.setBackgroundColor(ColorSupplier.getColorForPosition(page.getContext(),
                        pageIndex));
            }
        } else {
            page.setBackgroundColor(ColorSupplier.getColorForPosition(page.getContext(),
                    pageIndex));
        }
    }
}
Clone this wiki locally