com.agenmate.lollipop.util.ViewUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.agenmate.lollipop.util.ViewUtils.java

Source

/*
 * Copyright 2015 Google Inc.
 *
 * 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.agenmate.lollipop.util;

import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.os.Build;
import android.support.annotation.ColorInt;
import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v4.view.ViewCompat;
import android.support.v7.graphics.Palette;
import android.text.TextPaint;
import android.util.DisplayMetrics;
import android.util.Property;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * Utility methods for working with Views.
 */
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class ViewUtils {

    private ViewUtils() {
    }

    public static int getActionBarSize(@NonNull Context context) {
        TypedValue value = new TypedValue();
        context.getTheme().resolveAttribute(android.R.attr.actionBarSize, value, true);
        int actionBarSize = TypedValue.complexToDimensionPixelSize(value.data,
                context.getResources().getDisplayMetrics());
        return actionBarSize;
    }

    /**
     * Determine if the navigation bar will be on the bottom of the screen, based on logic in
     * PhoneWindowManager.
     */
    public static boolean isNavBarOnBottom(@NonNull Context context) {
        final Resources res = context.getResources();
        final Configuration cfg = context.getResources().getConfiguration();
        final DisplayMetrics dm = res.getDisplayMetrics();
        boolean canMove = (dm.widthPixels != dm.heightPixels && cfg.smallestScreenWidthDp < 600);
        return (!canMove || dm.widthPixels < dm.heightPixels);
    }

    public static RippleDrawable createRipple(@ColorInt int color, @FloatRange(from = 0f, to = 1f) float alpha,
            boolean bounded) {
        color = ColorUtils.modifyAlpha(color, alpha);
        return new RippleDrawable(ColorStateList.valueOf(color), null,
                bounded ? new ColorDrawable(Color.WHITE) : null);
    }

    public static RippleDrawable createRipple(@NonNull Palette palette,
            @FloatRange(from = 0f, to = 1f) float darkAlpha, @FloatRange(from = 0f, to = 1f) float lightAlpha,
            @ColorInt int fallbackColor, boolean bounded) {
        int rippleColor = fallbackColor;
        if (palette != null) {
            // try the named swatches in preference order
            if (palette.getVibrantSwatch() != null) {
                rippleColor = ColorUtils.modifyAlpha(palette.getVibrantSwatch().getRgb(), darkAlpha);

            } else if (palette.getLightVibrantSwatch() != null) {
                rippleColor = ColorUtils.modifyAlpha(palette.getLightVibrantSwatch().getRgb(), lightAlpha);
            } else if (palette.getDarkVibrantSwatch() != null) {
                rippleColor = ColorUtils.modifyAlpha(palette.getDarkVibrantSwatch().getRgb(), darkAlpha);
            } else if (palette.getMutedSwatch() != null) {
                rippleColor = ColorUtils.modifyAlpha(palette.getMutedSwatch().getRgb(), darkAlpha);
            } else if (palette.getLightMutedSwatch() != null) {
                rippleColor = ColorUtils.modifyAlpha(palette.getLightMutedSwatch().getRgb(), lightAlpha);
            } else if (palette.getDarkMutedSwatch() != null) {
                rippleColor = ColorUtils.modifyAlpha(palette.getDarkMutedSwatch().getRgb(), darkAlpha);
            }
        }
        return new RippleDrawable(ColorStateList.valueOf(rippleColor), null,
                bounded ? new ColorDrawable(Color.WHITE) : null);
    }

    public static void setLightStatusBar(@NonNull View view) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int flags = view.getSystemUiVisibility();
            flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            view.setSystemUiVisibility(flags);
        }
    }

    public static void clearLightStatusBar(@NonNull View view) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int flags = view.getSystemUiVisibility();
            flags &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            view.setSystemUiVisibility(flags);
        }
    }

    /**
     * Recursive binary search to find the best size for the text.
     *
     * Adapted from https://github.com/grantland/android-autofittextview
     */
    public static float getSingleLineTextSize(String text, TextPaint paint, float targetWidth, float low,
            float high, float precision, DisplayMetrics metrics) {
        final float mid = (low + high) / 2.0f;

        paint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, mid, metrics));
        final float maxLineWidth = paint.measureText(text);

        if ((high - low) < precision) {
            return low;
        } else if (maxLineWidth > targetWidth) {
            return getSingleLineTextSize(text, paint, targetWidth, low, mid, precision, metrics);
        } else if (maxLineWidth < targetWidth) {
            return getSingleLineTextSize(text, paint, targetWidth, mid, high, precision, metrics);
        } else {
            return mid;
        }
    }

    public static final Property<View, Integer> BACKGROUND_COLOR = AnimUtils
            .createIntProperty(new AnimUtils.IntProp<View>("backgroundColor") {
                @Override
                public void set(View view, int color) {
                    view.setBackgroundColor(color);
                }

                @Override
                public int get(View view) {
                    Drawable d = view.getBackground();
                    if (d instanceof ColorDrawable) {
                        return ((ColorDrawable) d).getColor();
                    }
                    return Color.TRANSPARENT;
                }
            });

    public static final Property<TextView, Integer> TEXT_COLOR = AnimUtils
            .createIntProperty(new AnimUtils.IntProp<TextView>("textColor") {
                @Override
                public void set(TextView textView, int textColor) {
                    textView.setTextColor(textColor);
                }

                @Override
                public int get(TextView textView) {
                    return textView.getCurrentTextColor();
                }
            });

    public static final Property<Drawable, Integer> DRAWABLE_ALPHA = AnimUtils
            .createIntProperty(new AnimUtils.IntProp<Drawable>("alpha") {
                @Override
                public void set(Drawable drawable, int alpha) {
                    drawable.setAlpha(alpha);
                }

                @Override
                public int get(Drawable drawable) {
                    return drawable.getAlpha();
                }
            });

    public static final Property<ImageView, Integer> IMAGE_ALPHA = AnimUtils
            .createIntProperty(new AnimUtils.IntProp<ImageView>("imageAlpha") {
                @Override
                public void set(ImageView imageView, int alpha) {
                    imageView.setImageAlpha(alpha);
                }

                @Override
                public int get(ImageView imageView) {
                    return imageView.getImageAlpha();
                }
            });

    public static final ViewOutlineProvider CIRCULAR_OUTLINE = new ViewOutlineProvider() {
        @Override
        public void getOutline(View view, Outline outline) {
            outline.setOval(view.getPaddingLeft(), view.getPaddingTop(), view.getWidth() - view.getPaddingRight(),
                    view.getHeight() - view.getPaddingBottom());
        }
    };

    /**
     * Determines if two views intersect in the window.
     */
    public static boolean viewsIntersect(View view1, View view2) {
        if (view1 == null || view2 == null)
            return false;

        final int[] view1Loc = new int[2];
        view1.getLocationOnScreen(view1Loc);
        final Rect view1Rect = new Rect(view1Loc[0], view1Loc[1], view1Loc[0] + view1.getWidth(),
                view1Loc[1] + view1.getHeight());
        int[] view2Loc = new int[2];
        view2.getLocationOnScreen(view2Loc);
        final Rect view2Rect = new Rect(view2Loc[0], view2Loc[1], view2Loc[0] + view2.getWidth(),
                view2Loc[1] + view2.getHeight());
        return view1Rect.intersect(view2Rect);
    }

    public static void setPaddingStart(View view, int paddingStart) {
        view.setPaddingRelative(paddingStart, view.getPaddingTop(), view.getPaddingEnd(), view.getPaddingBottom());
    }

    public static void setPaddingTop(View view, int paddingTop) {
        view.setPaddingRelative(view.getPaddingStart(), paddingTop, view.getPaddingEnd(), view.getPaddingBottom());
    }

    public static void setPaddingEnd(View view, int paddingEnd) {
        view.setPaddingRelative(view.getPaddingStart(), view.getPaddingTop(), paddingEnd, view.getPaddingBottom());
    }

    public static void setPaddingBottom(View view, int paddingBottom) {
        view.setPaddingRelative(view.getPaddingStart(), view.getPaddingTop(), view.getPaddingEnd(), paddingBottom);
    }

    public static float centerX(View view) {
        return ViewCompat.getX(view) + view.getWidth() / 2f;
    }

    public static float centerY(View view) {
        return ViewCompat.getY(view) + view.getHeight() / 2f;
    }

    public static int getRelativeTop(View myView) {
        if (myView.getParent() == myView.getRootView()) {
            return myView.getTop();
        } else {
            return myView.getTop() + getRelativeTop((View) myView.getParent());
        }
    }

    public static void setColor(final Drawable drawable, final int color) {
        drawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
    }

    public static void setLeftMargin(final View view, final int leftMargin) {
        final RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams();
        params.leftMargin = leftMargin;
        view.setLayoutParams(params);
    }

    public static void waitForLayoutPrepared(final View view, final LayoutPreparedListener listener) {
        final ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
        if (viewTreeObserver != null) {
            viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    invokeLayoutListener();
                    removeGlobalOnLayoutListenerIfNeeded();
                }

                private void invokeLayoutListener() {
                    if (listener != null) {
                        listener.onLayoutPrepared(view);
                    }
                }

                private void removeGlobalOnLayoutListenerIfNeeded() {
                    final ViewTreeObserver laterViewTreeObserver = view.getViewTreeObserver();
                    if (laterViewTreeObserver != null && laterViewTreeObserver.isAlive()) {
                        laterViewTreeObserver.removeGlobalOnLayoutListener(this);
                    }
                }
            });
        }
    }

    public interface LayoutPreparedListener {
        public void onLayoutPrepared(final View preparedView);
    }

}