com.shopify.buy.ui.ProductImagePagerAdapter.java Source code

Java tutorial

Introduction

Here is the source code for com.shopify.buy.ui.ProductImagePagerAdapter.java

Source

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Shopify Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.shopify.buy.ui;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.support.v4.view.ViewPager;
import android.support.v7.graphics.Palette;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.shopify.buy.R;
import com.shopify.buy.model.Image;
import com.shopify.buy.utils.ImageUtility;
import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;

import java.util.Arrays;
import java.util.List;

/**
 * A {@link ViewPagerAdapter} that loads images and uses {@link Palette} to set a suitable background color.
 */
public class ProductImagePagerAdapter extends ViewPagerAdapter {

    public interface BackgroundColorListener {
        void onBackgroundColorFound(int color, int position);

        boolean shouldShowBackgroundColor();
    }

    private final int maxWidth;
    private final int maxHeight;
    private final List<Image> images;
    private final BackgroundColorListener bgColorListener;
    private final int defaultBackgroundColor;

    private Bitmap[] bitmaps = null;

    public ProductImagePagerAdapter(List<Image> images, int maxWidth, int maxHeight,
            BackgroundColorListener bgColorListener, int defaultBackgroundColor) {
        this.images = images;
        this.maxWidth = maxWidth;
        this.maxHeight = maxHeight;
        this.bgColorListener = bgColorListener;
        this.defaultBackgroundColor = defaultBackgroundColor;
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

    private String stripQueryFromUrl(String url) {
        return url.substring(0, url.lastIndexOf('?'));
    }

    public List<Image> getImages() {
        return images;
    }

    @Override
    public View getView(final int pos, ViewPager pager) {
        Context context = pager.getContext();
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.view_product_image, pager, false);
        layout.setTag(pos);

        final View imageLoadingIndicator = layout.findViewById(R.id.image_loading_indicator);
        final ImageView imageView = (ImageView) layout.findViewById(R.id.image);

        if (bitmaps == null) {
            bitmaps = new Bitmap[images.size()];
            Arrays.fill(bitmaps, null);
        }

        final boolean needBitmap = bitmaps[pos] == null;
        if (!needBitmap) {
            imageLoadingIndicator.setVisibility(View.INVISIBLE);
            imageView.setImageBitmap(bitmaps[pos]);

        } else {
            // We don't ask Picasso to show a placeholder because we want to scale the placeholder differently than
            // the product image. The placeholder should be displayed using CENTER_INSIDE, while the image should be
            // loaded using Picasso's fit() request method (to reduce memory usage during decoding) and then cropped
            // or fitted into the target view.
            String imageUrl = stripQueryFromUrl(images.get(pos).getSrc());
            ImageUtility.loadRemoteImageIntoViewWithoutSize(Picasso.with(context), imageUrl, imageView, maxWidth,
                    maxHeight, false, new Callback() {
                        @Override
                        public void onSuccess() {
                            bitmaps[pos] = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
                            imageLoadingIndicator.setVisibility(View.INVISIBLE);
                            addBackgroundColor(pos);
                        }

                        @Override
                        public void onError() {
                            imageLoadingIndicator.setVisibility(View.VISIBLE);
                        }
                    });
        }

        return layout;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        Context context = container.getContext();
        if (context != null) {
            View view = container.findViewWithTag(position);
            ImageView imageView = (ImageView) view.findViewById(R.id.image);
            Picasso.with(context).cancelRequest(imageView);
        }
        super.destroyItem(container, position, object);
    }

    @Override
    public int getCount() {
        if (images == null) {
            return 0;
        }
        return images.size();
    }

    private void addBackgroundColor(final int position) {
        // Extract a prominent color from the product image and use it as the background behind the image
        if (bgColorListener != null) {
            if (!bgColorListener.shouldShowBackgroundColor()) {
                return;
            }

            try {
                Palette.from(bitmaps[position]).generate(new Palette.PaletteAsyncListener() {
                    public void onGenerated(Palette palette) {
                        int color = palette.getDarkMutedColor(0);
                        if (color == 0) {
                            color = palette.getDarkVibrantColor(0);
                        }
                        if (color == 0) {
                            color = palette.getLightMutedColor(0);
                        }
                        if (color == 0) {
                            color = palette.getLightVibrantColor(0);
                        }
                        if (color == 0) {
                            color = defaultBackgroundColor;
                        }
                        bgColorListener.onBackgroundColorFound(color, position);
                    }
                });
            } catch (Exception ignored) {
            }
        }
    }

}