168 lines
7.0 KiB
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() {
|
|
}
|
|
|
|
}
|