/** * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.waz.zclient.utils; import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.ShapeDrawable; import android.graphics.drawable.shapes.RoundRectShape; import android.support.annotation.IdRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.StringRes; import android.support.v4.app.Fragment; import android.support.v7.app.AlertDialog; import android.util.DisplayMetrics; import android.view.Display; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import java.lang.reflect.Field; public class ViewUtils { private static final int DEFAULT_CHILD_ANIMATION_DURATION = 350; public static boolean isInLandscape(@NonNull Context context) { return isInLandscape(context.getResources().getConfiguration()); } public static boolean isInLandscape(@NonNull Configuration configuration) { return configuration.orientation == Configuration.ORIENTATION_LANDSCAPE; } public static boolean isInPortrait(@NonNull Context context) { return isInPortrait(context.getResources().getConfiguration()); } public static boolean isInPortrait(@NonNull Configuration configuration) { return configuration.orientation == Configuration.ORIENTATION_PORTRAIT; } public static void lockCurrentOrientation(Activity activity, SquareOrientation squareOrientation) { activity.setRequestedOrientation(squareOrientation.activityOrientation); } public static void unlockOrientation(Activity activity) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); } public static void lockScreenOrientation(int orientation, Activity activity) { switch (orientation) { case Configuration.ORIENTATION_PORTRAIT: activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); break; case Configuration.ORIENTATION_LANDSCAPE: activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); break; default: activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); break; } } public static void setSoftInputMode(Window window, int softInputMode, String sender) { window.setSoftInputMode(softInputMode); } public static void setBackground(View view, Drawable drawable) { view.setBackground(drawable); } public static void setBackground(Context context, View view, int resource) { view.setBackground(context.getResources().getDrawable(resource)); } public static int getNavigationBarHeight(Context context) { Resources resources = context.getResources(); String name = ViewUtils.isInPortrait(context) ? "navigation_bar_height" : "navigation_bar_height_landscape"; int resourceId = resources.getIdentifier(name, "dimen", "android"); if (resourceId > 0) { return resources.getDimensionPixelSize(resourceId); } return 0; } public static int getStatusBarHeight(Context context) { int result = 0; int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = context.getResources().getDimensionPixelSize(resourceId); } return result; } public static Rect getOrientationDependentDisplayBounds(Context context) { return new Rect( 0, 0, getOrientationDependentDisplayWidth(context), getOrientationDependentDisplayHeight(context) ); } /** * @return everytime the amount of pixels of the (in portrait) horizontal axis of the phone */ public static int getOrientationIndependentDisplayWidth(Context context) { int pixels; if (ViewUtils.isInPortrait(context)) { pixels = context.getResources().getDisplayMetrics().widthPixels; } else { pixels = context.getResources().getDisplayMetrics().heightPixels; } return pixels; } /** * @return the amount of pixels of the horizontal axis of the phone */ public static int getOrientationDependentDisplayWidth(Context context) { return context.getResources().getDisplayMetrics().widthPixels; } /** * @return everytime the amount of pixels of the (in portrait) width axis of the phone */ public static int getOrientationIndependentDisplayHeight(Context context) { int pixels; if (ViewUtils.isInPortrait(context)) { pixels = context.getResources().getDisplayMetrics().heightPixels; } else { pixels = context.getResources().getDisplayMetrics().widthPixels; } return pixels; } /** * @return the amount of pixels of the vertical axis of the phone */ public static int getOrientationDependentDisplayHeight(Context context) { return context.getResources().getDisplayMetrics().heightPixels; } public static int getRealDisplayWidth(Context context) { Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); DisplayMetrics realMetrics = new DisplayMetrics(); display.getRealMetrics(realMetrics); return realMetrics.widthPixels; } public static int toPx(Context context, int dp) { return toPx(context.getResources(), dp); } public static int toPx(Resources resources, int dp) { final float scale = resources.getDisplayMetrics().density; return (int) (dp * scale + 0.5f); } public static int toPx(Context context, double dp) { return toPx(context.getResources(), dp); } public static int toPx(Resources resources, double dp) { final float scale = resources.getDisplayMetrics().density; return (int) (dp * scale + 0.5f); } public static void setPaddingStart(View view, int startPadding) { view.setPaddingRelative(startPadding, view.getPaddingTop(), view.getPaddingEnd(), view.getPaddingBottom()); } public static void setPaddingEnd(View view, int endPadding) { view.setPaddingRelative(view.getPaddingStart(), view.getPaddingTop(), endPadding, view.getPaddingBottom()); } public static void setPaddingLeft(View view, int leftPadding) { view.setPadding(leftPadding, view.getPaddingTop(), view.getPaddingRight(), view.getPaddingBottom()); } public static void setPaddingTop(View view, int topPadding) { view.setPadding(view.getPaddingLeft(), topPadding, view.getPaddingRight(), view.getPaddingBottom()); } public static void setPaddingRight(View view, int rightPadding) { view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), rightPadding, view.getPaddingBottom()); } public static void setPaddingBottom(View view, int bottomPadding) { view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(), bottomPadding); } public static void setPaddingLeftRight(View view, int padding) { view.setPadding(padding, view.getPaddingTop(), padding, view.getPaddingBottom()); } public static Point getLocationOnScreen(View view) { int[] location = new int[2]; view.getLocationOnScreen(location); return new Point(location[0], location[1]); } public static Drawable getRoundedRect(int cornerRadius, int backgroundColor) { RoundRectShape rect = new RoundRectShape( new float[] {cornerRadius, cornerRadius, cornerRadius, cornerRadius, cornerRadius, cornerRadius, cornerRadius, cornerRadius}, null, null); ShapeDrawable background = new ShapeDrawable(rect); background.getPaint().setColor(backgroundColor); return background; } public static void fadeInView(@Nullable final View view) { fadeInView(view, 1, new ValueAnimator().getDuration(), 0); } public static void fadeInView(@Nullable final View view, long duration) { fadeInView(view, 1, duration, 0); } public static void fadeInView(@Nullable final View view, final float targetAlpha, final long duration, final long startDelay) { if (view == null) { return; } view.animate() .alpha(targetAlpha) .setDuration(duration) .setStartDelay(startDelay) .withStartAction(new Runnable() { @Override public void run() { view.setVisibility(View.VISIBLE); } }) .start(); } public static void fadeOutView(@Nullable final View view) { fadeOutView(view, true); } public static void fadeOutView(@Nullable final View view, boolean setToGoneWithEndAction) { fadeOutView(view, new ValueAnimator().getDuration(), 0, setToGoneWithEndAction); } public static void fadeOutView(@Nullable final View view, final long duration) { fadeOutView(view, duration, 0); } public static void fadeOutView(@Nullable final View view, final long duration, final long startDelay) { fadeOutView(view, duration, startDelay, true); } public static void fadeOutView(@Nullable final View view, final long duration, final long startDelay, final boolean setToGoneWithEndAction) { if (view == null) { return; } if (view.getVisibility() == View.GONE || view.getVisibility() == View.INVISIBLE) { return; } view.animate() .alpha(0) .setDuration(duration) .setStartDelay(startDelay) .withEndAction(new Runnable() { @Override public void run() { view.setVisibility(setToGoneWithEndAction ? View.GONE : View.INVISIBLE); } }) .start(); } public static void setHeight(View v, int height) { ((ViewGroup.MarginLayoutParams) v.getLayoutParams()).height = height; v.invalidate(); } public static void setWidth(View v, int width) { ViewGroup.LayoutParams params = v.getLayoutParams(); params.width = width; v.setLayoutParams(params); } public static void setMarginTop(View v, int topMargin) { ((ViewGroup.MarginLayoutParams) v.getLayoutParams()).topMargin = topMargin; v.invalidate(); } public static void setMarginBottom(View v, int bottomMargin) { ((ViewGroup.MarginLayoutParams) v.getLayoutParams()).bottomMargin = bottomMargin; v.invalidate(); } public static void setMarginLeft(View v, int leftMargin) { ((ViewGroup.MarginLayoutParams) v.getLayoutParams()).leftMargin = leftMargin; v.invalidate(); } public static void setMarginRight(View v, int rightMargin) { ((ViewGroup.MarginLayoutParams) v.getLayoutParams()).rightMargin = rightMargin; v.invalidate(); } public static AlertDialog showAlertDialog(Context context, CharSequence title, CharSequence message, CharSequence button, DialogInterface.OnClickListener onClickListener, boolean cancelable) { AlertDialog dialog = new AlertDialog.Builder(context) .setCancelable(cancelable) .setTitle(title) .setMessage(message) .setNeutralButton(button, onClickListener) .create(); dialog.show(); return dialog; } public static AlertDialog showAlertDialog(Context context, @StringRes int title, @StringRes int message, @StringRes int button, DialogInterface.OnClickListener onClickListener, boolean cancelable) { AlertDialog dialog = new AlertDialog.Builder(context) .setCancelable(cancelable) .setTitle(title) .setMessage(message) .setNeutralButton(button, onClickListener) .create(); dialog.show(); return dialog; } public static AlertDialog showAlertDialog(Context context, CharSequence title, CharSequence message, CharSequence positiveButton, CharSequence negativeButton, DialogInterface.OnClickListener positiveAction, DialogInterface.OnClickListener negativeAction) { AlertDialog dialog = new AlertDialog.Builder(context) .setTitle(title) .setMessage(message) .setPositiveButton(positiveButton, positiveAction) .setNegativeButton(negativeButton, negativeAction) .create(); dialog.show(); return dialog; } public static AlertDialog showAlertDialog(Context context, @StringRes int title, @StringRes int message, @StringRes int positiveButton, @StringRes int negativeButton, DialogInterface.OnClickListener positiveAction, DialogInterface.OnClickListener negativeAction) { AlertDialog dialog = new AlertDialog.Builder(context) .setTitle(title) .setMessage(message) .setPositiveButton(positiveButton, positiveAction) .setNegativeButton(negativeButton, negativeAction) .create(); dialog.show(); return dialog; } public static AlertDialog showAlertDialog(Context context, View view, @StringRes int title, @StringRes int message, @StringRes int positiveButton, @StringRes int negativeButton, DialogInterface.OnClickListener positiveAction, DialogInterface.OnClickListener negativeAction) { AlertDialog dialog = new AlertDialog.Builder(context) .setView(view) .setTitle(title) .setMessage(message) .setPositiveButton(positiveButton, positiveAction) .setNegativeButton(negativeButton, negativeAction) .create(); dialog.show(); return dialog; } @SuppressLint("com.waz.ViewUtils") public static <T extends View> T getView(@NonNull View v, @IdRes int resId) { return (T) v.findViewById(resId); } @SuppressLint("com.waz.ViewUtils") public static <T extends View> T getView(@NonNull Dialog d, @IdRes int resId) { return (T) d.findViewById(resId); } @SuppressLint("com.waz.ViewUtils") public static <T extends View> T getView(@NonNull Activity activity, @IdRes int resId) { return (T) activity.findViewById(resId); } public static int getAlphaValue(int opacity) { return (int) (255.00 * ((double) opacity / 100.00)); } public static long getNextAnimationDuration(Fragment fragment) { try { // Attempt to get the resource ID of the next animation that // will be applied to the given fragment. Field nextAnimField = Fragment.class.getDeclaredField("mNextAnim"); nextAnimField.setAccessible(true); int nextAnimResource = nextAnimField.getInt(fragment); Animation nextAnim = AnimationUtils.loadAnimation(fragment.getActivity(), nextAnimResource); // ...and if it can be loaded, return that animation's duration return (nextAnim == null) ? DEFAULT_CHILD_ANIMATION_DURATION : nextAnim.getDuration(); } catch (NoSuchFieldException | IllegalAccessException | Resources.NotFoundException ex) { return DEFAULT_CHILD_ANIMATION_DURATION; } } }