nl.sebastiaanschool.contact.app.gui.GrabBag.java Source code

Java tutorial

Introduction

Here is the source code for nl.sebastiaanschool.contact.app.gui.GrabBag.java

Source

/*
 Copyright (c) 2014 Barend Garvelink
    
 SebastiaanSchool is licensed under a
 Creative Commons Attribution-NonCommercial 3.0 Unported License.
    
 You should have received a copy of the license along with this
 work.  If not, see <http://creativecommons.org/licenses/by-nc/3.0/>.
 */
package nl.sebastiaanschool.contact.app.gui;

import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Looper;
import android.support.annotation.DrawableRes;
import android.support.graphics.drawable.VectorDrawableCompat;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.util.LruCache;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

import nl.sebastiaanschool.contact.app.R;

/**
 * This class is normally called {@code SomethingUtility}, but that's boring.
 */
final class GrabBag {

    public static void openUri(Context context, String uriString) {
        openUri(context, Uri.parse(uriString));
    }

    public static void openUri(Context context, Uri uri) {
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        openUri(context, intent);
    }

    public static void openUri(Context context, Intent intent) {
        // Need to check if a browser is present, as it can be disabled entirely using child safety features on a tablet.
        List<ResolveInfo> handlers = context.getPackageManager().queryIntentActivities(intent, 0);
        if (!handlers.isEmpty()) {
            context.startActivity(intent);
        } else {
            new AlertDialog.Builder(context).setCancelable(true).setTitle(R.string.open_uri_failed)
                    .setMessage(intent.getData().toString()).setNegativeButton(R.string.close_button, null).show();
        }
    }

    public static void applyBitmapDrawableLeft(TextView view, @DrawableRes int resId) {
        // This could be defined in XML just as easily, but it's here for symmetry at the call site.
        view.setCompoundDrawablesWithIntrinsicBounds(resId, 0, 0, 0);
    }

    /**
     * Apply a vector drawable, using backwards compatibility as needed. This throws an exception
     * if your {@code resId} is actually a bitmap drawable.
     */
    public static void applyVectorDrawableLeft(TextView view, @DrawableRes int resId) {
        if (Build.VERSION.SDK_INT >= 21) {
            view.setCompoundDrawablesRelativeWithIntrinsicBounds(resId, 0, 0, 0);
            view.getCompoundDrawablesRelative()[0].setTint(ResourcesCompat.getColor(view.getResources(),
                    R.color.sebastiaan_blue, view.getContext().getTheme()));
        } else {
            final Context context = view.getContext();
            final Drawable drawable = loadVectorDrawable(context, resId);
            if (Build.VERSION.SDK_INT >= 17) {
                view.setCompoundDrawablesRelativeWithIntrinsicBounds(drawable, null, null, null);
            } else {
                view.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
            }
        }
    }

    private static final LruCache<Integer, Drawable> vectorDrawableCache = new LruCache<>(32);

    /**
     * Apply a vector drawable to an image view.
     * @param imageView the imageView.
     * @param resId the drawable resource.
     */
    public static void applyVectorImage(ImageView imageView, @DrawableRes int resId) {
        imageView.setImageDrawable(loadVectorDrawable(imageView.getContext(), resId));
    }

    private static Drawable loadVectorDrawable(Context context, @DrawableRes int resId) {
        Drawable result = vectorDrawableCache.get(resId);
        if (result == null) {
            result = VectorDrawableCompat.create(context.getResources(), resId, context.getTheme());
            if (result != null) {
                vectorDrawableCache.put(resId, result);
            } else {
                vectorDrawableCache.remove(resId);
            }
        }
        return result;
    }

    static void assertOnMainThread() {
        if (Looper.myLooper() != Looper.getMainLooper()) {
            throw new IllegalStateException("not on main thread");
        }
    }

    static void assertNotOnMainThread() {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            throw new IllegalStateException("on main thread");
        }
    }

    private GrabBag() {
    }
}