RoboSwag-components/src/main/java/ru/touchin/roboswag/components/utils/UiUtils.java

168 lines
7.0 KiB
Java

package ru.touchin.roboswag.components.utils;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Display;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import ru.touchin.roboswag.components.navigation.AbstractBaseFragment;
import rx.functions.Action0;
import rx.functions.Func1;
/**
* Created by Gavriil Sitnikov on 13/11/2015.
* TODO: fill description
*/
public final class UiUtils {
// to enable ripple effect on tap
public static final long RIPPLE_EFFECT_DELAY = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? 150 : 0;
private static final int MAX_METRICS_TRIES_COUNT = 5;
// TODO remove on activity stop
private static final Handler RIPPLE_HANDLER = new Handler(Looper.getMainLooper());
@SuppressWarnings("BusyWait")
@NonNull
public static DisplayMetrics getDisplayMetrics(@NonNull final Context context) {
DisplayMetrics result = context.getResources().getDisplayMetrics();
// it is needed to avoid bug with invalid metrics when user restore application from other application
int metricsTryNumber = 0;
while (metricsTryNumber < MAX_METRICS_TRIES_COUNT && (result.heightPixels <= 0 || result.widthPixels <= 0)) {
try {
Thread.sleep(500);
} catch (final InterruptedException ignored) {
return result;
}
result = context.getResources().getDisplayMetrics();
metricsTryNumber++;
}
return result;
}
public static float dpToPixels(@NonNull final Context context, final float sizeInDp) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sizeInDp, getDisplayMetrics(context));
}
public static int getActionBarHeight(@NonNull final Context context) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 56, getDisplayMetrics(context));
}
public static int getStatusBarHeight(@NonNull final Context context) {
final int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
return resourceId > 0 ? context.getResources().getDimensionPixelSize(resourceId) : 0;
}
public static int getNavigationBarHeight(@NonNull final Context context) {
final int resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
return resourceId > 0 ? context.getResources().getDimensionPixelSize(resourceId) : 0;
}
@NonNull
public static View inflate(@LayoutRes final int layoutId, @NonNull final ViewGroup parent) {
return LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
}
@NonNull
public static View inflateAndAdd(@LayoutRes final int layoutId, @NonNull final ViewGroup parent) {
return LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, true);
}
public static boolean tryForeachFragment(@NonNull final FragmentManager fragmentManager,
@NonNull final Func1<AbstractBaseFragment, Boolean> actionOnChild,
final boolean onlyForResumed) {
if (fragmentManager.getFragments() == null) {
return false;
}
boolean result = false;
for (final Fragment fragment : fragmentManager.getFragments()) {
if (fragment != null
&& (!onlyForResumed || fragment.isResumed())
&& fragment instanceof AbstractBaseFragment) {
result = result || actionOnChild.call((AbstractBaseFragment) fragment);
}
}
return result;
}
public static boolean isIntentAbleToHandle(@NonNull final Context context, @NonNull final Intent intent) {
return !context.getPackageManager().queryIntentActivities(intent, 0).isEmpty();
}
//http://stackoverflow.com/questions/14853039/how-to-tell-whether-an-android-device-has-hard-keys/14871974#14871974
public static boolean hasSoftKeys(@NonNull final Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
final Display display = activity.getWindowManager().getDefaultDisplay();
final DisplayMetrics realDisplayMetrics = new DisplayMetrics();
display.getRealMetrics(realDisplayMetrics);
final DisplayMetrics displayMetrics = new DisplayMetrics();
display.getMetrics(displayMetrics);
return (realDisplayMetrics.widthPixels - displayMetrics.widthPixels) > 0
|| (realDisplayMetrics.heightPixels - displayMetrics.heightPixels) > 0;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
final boolean hasMenuKey = ViewConfiguration.get(activity).hasPermanentMenuKey();
final boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
return !hasMenuKey && !hasBackKey;
}
return false;
}
public static void setOnRippleClickListener(@NonNull final View targetView, @Nullable final Action0 onClickListener, final long delay) {
setOnRippleClickListener(targetView, onClickListener != null ? v -> onClickListener.call() : null, delay);
}
public static void setOnRippleClickListener(@NonNull final View targetView, @Nullable final Action0 onClickListener) {
setOnRippleClickListener(targetView, onClickListener != null ? v -> onClickListener.call() : null, RIPPLE_EFFECT_DELAY);
}
public static void setOnRippleClickListener(@NonNull final View targetView, @Nullable final View.OnClickListener onClickListener) {
setOnRippleClickListener(targetView, onClickListener, RIPPLE_EFFECT_DELAY);
}
public static void setOnRippleClickListener(@NonNull final View targetView,
@Nullable final View.OnClickListener onClickListener,
final long delay) {
if (onClickListener == null) {
targetView.setOnClickListener(null);
return;
}
final Runnable runnable = () -> {
if (targetView.getWindowVisibility() == View.VISIBLE) {
onClickListener.onClick(targetView);
}
};
targetView.setOnClickListener(v -> {
RIPPLE_HANDLER.removeCallbacksAndMessages(null);
RIPPLE_HANDLER.postDelayed(runnable, delay);
});
}
private UiUtils() {
}
}