com.andrewreitz.encryptedcamera.ui.adapter.GalleryAdapter.java Source code

Java tutorial

Introduction

Here is the source code for com.andrewreitz.encryptedcamera.ui.adapter.GalleryAdapter.java

Source

/*
 * Copyright (C) 2014 Andrew Reitz
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.andrewreitz.encryptedcamera.ui.adapter;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.v4.util.LruCache;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import butterknife.ButterKnife;
import com.andrewreitz.encryptedcamera.R;
import com.andrewreitz.encryptedcamera.image.ImageRotation;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import timber.log.Timber;

public class GalleryAdapter extends BindableAdapter<File> {
    private final int viewSize;
    private final LruCache<String, Bitmap> cache;
    private final List<File> images;

    public GalleryAdapter(@NonNull Context context, @NonNull List<File> images,
            @NonNull LruCache<String, Bitmap> cache) {
        super(context);
        this.viewSize = context.getResources().getDimensionPixelSize(R.dimen.gridview_image);
        this.images = images;
        this.cache = cache;
    }

    @Override
    public int getCount() {
        return images.size();
    }

    @Override
    public File getItem(int position) {
        return images.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View newView(LayoutInflater inflater, int position, ViewGroup container) {
        return inflater.inflate(R.layout.gallery_item, container, false);
    }

    @Override
    public void bindView(File file, int position, View view) {
        ImageView imageView = ButterKnife.findById(view, R.id.gallery_imageview);
        // Cancel any pending thumbnail task, since this view is now bound
        // to new thumbnail
        final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) view.getTag();
        if (oldTask != null) {
            oldTask.cancel(false);
        }

        // Cache enabled, try looking for cache hit
        final Bitmap cachedResult = cache.get(file.getName());
        if (cachedResult != null) {
            imageView.setImageBitmap(cachedResult);
            return;
        }

        int rotation = 0;
        try {
            rotation = ImageRotation.getRotation(file);
        } catch (IOException e) {
            Timber.e(e, "Error using exif data");
        }

        // If we arrived here, either cache is disabled or cache miss, so we
        // need to kick task to load manually
        final ThumbnailAsyncTask task = new ThumbnailAsyncTask(imageView, viewSize, cache, rotation);
        imageView.setImageBitmap(null);
        task.execute(file);
    }

    private static class ThumbnailAsyncTask extends AsyncTask<File, Void, Bitmap> {

        private final static Matrix matrix = new Matrix();

        private final ImageView target;
        private final int viewSize;
        private final int rotation;
        private final LruCache<String, Bitmap> cache;

        ThumbnailAsyncTask(ImageView target, int viewSize, LruCache<String, Bitmap> cache, int rotation) {
            this.target = target;
            this.viewSize = viewSize;
            this.cache = cache;
            this.rotation = rotation;
        }

        @Override
        protected void onPreExecute() {
            target.setTag(this);
        }

        @Override
        protected Bitmap doInBackground(File... params) {
            Bitmap result = null;
            File file = params[0];
            try {
                FileInputStream fis = new FileInputStream(file.getAbsolutePath());
                Bitmap imageBitmap = BitmapFactory.decodeStream(fis);

                final int width = imageBitmap.getWidth();
                final int height = imageBitmap.getHeight();
                final float sx = viewSize / (float) width;
                final float sy = viewSize / (float) height;
                matrix.setScale(sx, sy);
                matrix.postRotate(rotation);
                result = Bitmap.createBitmap(imageBitmap, 0, 0, width, height, matrix, false);
                cache.put(file.getName(), result);
            } catch (Exception e) {
                Timber.e(e, "Error resizing image");
            }
            return result;
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            if (target.getTag() == this) {
                target.setImageBitmap(result);
                target.setTag(null);
            }
        }
    }
}