com.bitants.wally.fragments.ImageZoomFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.bitants.wally.fragments.ImageZoomFragment.java

Source

/*
 * Copyright (C) 2014 Freddie (Musenkishi) Lust-Hed
 *
 * 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.bitants.wally.fragments;

import android.animation.ValueAnimator;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.MimeTypeMap;
import android.widget.Button;
import android.widget.RelativeLayout;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.musenkishi.wally.R;
import com.bitants.wally.anim.interpolator.LinearOutSlowInInterpolator;
import com.bitants.wally.observers.FileReceiver;

import uk.co.senab.photoview.PhotoView;
import uk.co.senab.photoview.PhotoViewAttacher;

/**
 * Fragment used for letting the user zoom in on the image provided
 * Created by Musenkishi on 2014-03-29.
 */
public class ImageZoomFragment extends DialogFragment {

    public static final String TAG = "com.bitants.wally.fragments.ImageZoomFragment";
    private static final String STATE_BITMAP = TAG + ".bitmap";
    private static final String STATE_TOOLBAR_VISIBILITY = TAG + ".toolBarVisibility";
    private static final String STATE_URI_FILE = TAG + ".fileUri";
    private static final String STATE_URI_CONTENT = TAG + ".contentUri";

    private PhotoView zoomableImageView;
    private PhotoViewAttacher photoViewAttacher;
    private Bitmap bitmap;
    private ViewGroup toolBar;
    private View progressBar;
    private int toolBarVisibility = View.GONE;
    private Uri fileUri;
    private Uri contentUri;
    private Rect rect;
    private int statusBarHeightCorrection;
    private int position;

    public static ImageZoomFragment newInstance(Bitmap bitmap) {
        ImageZoomFragment fragment = new ImageZoomFragment(bitmap);
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    public static ImageZoomFragment newInstance(Bitmap bitmap, Rect rect) {
        ImageZoomFragment fragment = new ImageZoomFragment(bitmap, rect);
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    public static ImageZoomFragment newInstance(Uri fileUri) {
        ImageZoomFragment fragment = new ImageZoomFragment(fileUri);
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    public static ImageZoomFragment newInstance(Uri fileUri, int position) {
        ImageZoomFragment fragment = new ImageZoomFragment(fileUri, position);
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    public ImageZoomFragment() {
    }

    public ImageZoomFragment(Bitmap bitmap, Rect rect) {
        this.bitmap = bitmap;
        this.rect = rect;
    }

    public ImageZoomFragment(Bitmap bitmap) {
        this.bitmap = bitmap;
    }

    public ImageZoomFragment(Uri fileUri) {
        this.fileUri = fileUri;
    }

    public ImageZoomFragment(Uri fileUri, int position) {
        this.fileUri = fileUri;
        this.position = position;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
        if (savedInstanceState != null) {
            if (savedInstanceState.containsKey(STATE_BITMAP)) {
                bitmap = savedInstanceState.getParcelable(STATE_BITMAP);
            }
            if (savedInstanceState.containsKey(STATE_TOOLBAR_VISIBILITY)) {
                toolBarVisibility = savedInstanceState.getInt(STATE_TOOLBAR_VISIBILITY, View.GONE);
            }
            if (savedInstanceState.containsKey(STATE_URI_FILE)) {
                fileUri = savedInstanceState.getParcelable(STATE_URI_FILE);
            }
            if (savedInstanceState.containsKey(STATE_URI_CONTENT)) {
                contentUri = savedInstanceState.getParcelable(STATE_URI_CONTENT);
            }
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        // safety check
        if (getDialog() == null) {
            return;
        }

        // set the animations to use on showing and hiding the dialog
        getDialog().getWindow().setWindowAnimations(R.style.dialog_animation_fade);
        // alternative way of doing it
        //getDialog().getWindow().getAttributes().
        //    windowAnimations = R.style.dialog_animation_fade;

    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        if (getActivity() != null) {
            final Dialog dialog = new Dialog(getActivity());
            dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
            dialog.setContentView(R.layout.activity_image_zoom);
            dialog.getWindow().setBackgroundDrawableResource(R.color.Transparent);
            WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
            layoutParams.copyFrom(dialog.getWindow().getAttributes());
            layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
            layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;
            dialog.getWindow().setAttributes(layoutParams);
            initToolbar(dialog);
            progressBar = dialog.findViewById(R.id.zoom_loader);
            zoomableImageView = (PhotoView) dialog.findViewById(R.id.image_zoom_photoview);
            if (bitmap != null) {
                if (rect != null) {
                    animateIn(dialog);
                }
            } else if (fileUri != null) {
                showLoader();
                Glide.with(getActivity()).load(fileUri).fitCenter()
                        .listener(new RequestListener<Uri, GlideDrawable>() {
                            @Override
                            public boolean onException(Exception e, Uri model, Target<GlideDrawable> target,
                                    boolean isFirstResource) {
                                return false;
                            }

                            @Override
                            public boolean onResourceReady(GlideDrawable resource, Uri model,
                                    Target<GlideDrawable> target, boolean isFromMemoryCache,
                                    boolean isFirstResource) {
                                hideLoader();
                                return false;
                            }
                        }).into(zoomableImageView);
            } else {
                dismiss();
            }
            photoViewAttacher = new PhotoViewAttacher(zoomableImageView);
            photoViewAttacher.setOnViewTapListener(new PhotoViewAttacher.OnViewTapListener() {
                @Override
                public void onViewTap(View view, float x, float y) {
                    dismiss();
                }
            });
            return dialog;
        } else {
            return null;
        }
    }

    private void hideLoader() {
        progressBar.setVisibility(View.GONE);
    }

    private void showLoader() {
        progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        outState.putInt(STATE_TOOLBAR_VISIBILITY, toolBarVisibility);
        if (bitmap != null) {
            outState.putParcelable(STATE_BITMAP, bitmap);
        }
        if (fileUri != null) {
            outState.putParcelable(STATE_URI_FILE, fileUri);
        }
        if (contentUri != null) {
            outState.putParcelable(STATE_URI_CONTENT, contentUri);
        }
        super.onSaveInstanceState(outState);
    }

    @Override
    public void dismiss() {
        if (rect != null) {
            animateOut();
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    dismissParent();
                }
            }, 500);
        } else {
            dismissParent();
        }
    }

    private void dismissParent() {
        super.dismiss();
    }

    private void animateIn(final Dialog dialog) {
        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) zoomableImageView.getLayoutParams();
        params.width = rect.right;
        params.height = rect.bottom;
        zoomableImageView.setLayoutParams(params);

        zoomableImageView.setX(rect.left);
        zoomableImageView.setY(rect.top - statusBarHeightCorrection);
        zoomableImageView.setAlpha(0.0f);
        zoomableImageView.setImageBitmap(bitmap);

        WindowManager win = getActivity().getWindowManager();
        Display d = win.getDefaultDisplay();
        int displayWidth = d.getWidth(); // Width of the actual device
        int displayHeight = d.getHeight() + statusBarHeightCorrection;

        ValueAnimator animWidth = ValueAnimator.ofInt(rect.right, displayWidth);
        animWidth.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int val = (Integer) valueAnimator.getAnimatedValue();
                ViewGroup.LayoutParams layoutParams = zoomableImageView.getLayoutParams();
                layoutParams.width = val;
                zoomableImageView.setLayoutParams(layoutParams);
            }
        });
        animWidth.setDuration(500);
        animWidth.setInterpolator(new LinearOutSlowInInterpolator());
        animWidth.start();

        ValueAnimator animHeight = ValueAnimator.ofInt(rect.bottom, displayHeight);
        animHeight.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int val = (Integer) valueAnimator.getAnimatedValue();
                ViewGroup.LayoutParams layoutParams = zoomableImageView.getLayoutParams();
                layoutParams.height = val;
                zoomableImageView.setLayoutParams(layoutParams);
            }
        });
        animHeight.setDuration(500);
        animHeight.setInterpolator(new LinearOutSlowInInterpolator());

        animHeight.start();

        if (statusBarHeightCorrection > 0) {
            zoomableImageView.animate().y(0.0f).setDuration(300).start();
        }

        ValueAnimator animDim = ValueAnimator.ofFloat(0.0f, 0.5f);
        animDim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
                layoutParams.copyFrom(dialog.getWindow().getAttributes());
                layoutParams.dimAmount = (Float) valueAnimator.getAnimatedValue();
                dialog.getWindow().setAttributes(layoutParams);
            }
        });
        animDim.setDuration(300);
        animDim.setStartDelay(300);
        animDim.start();
        zoomableImageView.animate().alpha(1.0f).setDuration(300).start();
    }

    private void animateOut() {
        ValueAnimator animWidth = ValueAnimator.ofInt(zoomableImageView.getMeasuredWidth(), rect.right);
        animWidth.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int val = (Integer) valueAnimator.getAnimatedValue();
                ViewGroup.LayoutParams layoutParams = zoomableImageView.getLayoutParams();
                layoutParams.width = val;
                zoomableImageView.setLayoutParams(layoutParams);
            }
        });
        animWidth.setDuration(500);
        animWidth.start();

        ValueAnimator animHeight = ValueAnimator.ofInt(zoomableImageView.getMeasuredHeight(), rect.bottom);
        animHeight.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int val = (Integer) valueAnimator.getAnimatedValue();
                ViewGroup.LayoutParams layoutParams = zoomableImageView.getLayoutParams();
                layoutParams.height = val;
                zoomableImageView.setLayoutParams(layoutParams);
            }
        });
        animHeight.setDuration(500);
        animHeight.start();
        if (statusBarHeightCorrection > 0) {
            zoomableImageView.animate().y(-statusBarHeightCorrection).setDuration(300).start();
        }
        zoomableImageView.animate().alpha(0.0f).setDuration(500).start();
    }

    @Override
    public void onDestroyView() {
        if (getDialog() != null && getRetainInstance())
            getDialog().setDismissMessage(null);
        super.onDestroyView();
    }

    private void initToolbar(Dialog dialog) {
        toolBar = (ViewGroup) dialog.findViewById(R.id.zoom_toolbar);
        toolBar.setVisibility(toolBarVisibility);
        if (fileUri != null) {
            Button setAsButton = (Button) toolBar.findViewById(R.id.toolbar_set_as);
            setAsButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    setImageAsWallpaperPicker(fileUri);
                }
            });
        }
        if (contentUri != null) {
            Button deleteButton = (Button) toolBar.findViewById(R.id.toolbar_delete);
            deleteButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    String quantityString = getResources().getQuantityString(R.plurals.wallpapers, 1);
                    String title = String.format(getString(R.string.dialog_delete_title), quantityString);

                    FragmentManager fragmentManager = getFragmentManager();

                    if (fragmentManager != null) {

                        final MaterialDialogFragment materialDialogFragment = new MaterialDialogFragment();
                        materialDialogFragment
                                .setPrimaryColor(getResources().getColor(R.color.Dialog_Button_Delete));
                        materialDialogFragment.setTitle(title);
                        materialDialogFragment.setPositiveButton(R.string.dialog_delete_positive,
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialogInterface, int i) {
                                        delete(contentUri);
                                    }
                                });
                        materialDialogFragment.setNegativeButton(R.string.dialog_delete_negative,
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialogInterface, int i) {
                                        materialDialogFragment.dismiss();
                                    }
                                });
                        materialDialogFragment.show(fragmentManager, MaterialDialogFragment.TAG);
                    }
                }
            });
        }
    }

    public void showFileOptions(Uri fileUri, Uri contentUri) {
        toolBarVisibility = View.VISIBLE;
        this.fileUri = fileUri;
        this.contentUri = contentUri;
    }

    private void setImageAsWallpaperPicker(Uri fileUri) {
        Intent intent = new Intent(Intent.ACTION_ATTACH_DATA);
        intent.setType("image/*");

        MimeTypeMap map = MimeTypeMap.getSingleton();
        String mimeType = map.getMimeTypeFromExtension("png");
        intent.setDataAndType(fileUri, mimeType);
        intent.putExtra("mimeType", mimeType);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

        startActivity(Intent.createChooser(intent, getString(R.string.action_set_as)));
    }

    private void delete(Uri contentUri) {
        getActivity().getContentResolver().delete(contentUri, null, null);

        //Not for SavedImagesFragment, but for the others to know that they should update their content (heart/unheart tiles)
        getActivity().sendBroadcast(new Intent(FileReceiver.GET_FILES));

        dismiss();
    }

}