Merge branch 'master' into remove_buildscripts
This commit is contained in:
commit
65a1076aee
|
|
@ -84,6 +84,7 @@ open class FragmentNavigation(
|
|||
* @param args Bundle to be set as [Fragment.getArguments] of instantiated [Fragment];
|
||||
* @param backStackName Name of [Fragment] in back stack;
|
||||
* @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info.
|
||||
* @param tag Optional tag name for the [Fragment];
|
||||
*/
|
||||
fun addToStack(
|
||||
fragmentClass: Class<out Fragment>,
|
||||
|
|
@ -92,7 +93,8 @@ open class FragmentNavigation(
|
|||
addToStack: Boolean,
|
||||
args: Bundle?,
|
||||
backStackName: String?,
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)?
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)?,
|
||||
tag: String?
|
||||
) {
|
||||
if (fragmentManager.isDestroyed) {
|
||||
Lc.assertion("FragmentManager is destroyed")
|
||||
|
|
@ -104,7 +106,7 @@ open class FragmentNavigation(
|
|||
|
||||
val fragmentTransaction = fragmentManager.beginTransaction()
|
||||
transactionSetup?.invoke(fragmentTransaction)
|
||||
fragmentTransaction.replace(containerViewId, fragment, null)
|
||||
fragmentTransaction.replace(containerViewId, fragment, tag)
|
||||
if (addToStack) {
|
||||
fragmentTransaction
|
||||
.addToBackStack(backStackName)
|
||||
|
|
@ -145,15 +147,17 @@ open class FragmentNavigation(
|
|||
* @param fragmentClass Class of [Fragment] to instantiate;
|
||||
* @param args Bundle to be set as [Fragment.getArguments] of instantiated [Fragment];
|
||||
* @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info.
|
||||
* @param tag Optional tag name for the [Fragment];
|
||||
*/
|
||||
fun push(
|
||||
fragmentClass: Class<out Fragment>,
|
||||
args: Bundle? = null,
|
||||
addToStack: Boolean = true,
|
||||
backStackName: String? = null,
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null,
|
||||
tag: String? = null
|
||||
) {
|
||||
addToStack(fragmentClass, null, 0, addToStack, args, backStackName, transactionSetup)
|
||||
addToStack(fragmentClass, null, 0, addToStack, args, backStackName, transactionSetup, tag)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -163,13 +167,15 @@ open class FragmentNavigation(
|
|||
* @param targetFragment Target fragment to be set as [Fragment.getTargetFragment] of instantiated [Fragment];
|
||||
* @param args Bundle to be set as [Fragment.getArguments] of instantiated [Fragment];
|
||||
* @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info.
|
||||
* @param tag Optional tag name for the [Fragment];
|
||||
*/
|
||||
fun pushForResult(
|
||||
fragmentClass: Class<out Fragment>,
|
||||
targetFragment: Fragment,
|
||||
targetRequestCode: Int,
|
||||
args: Bundle? = null,
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null,
|
||||
tag: String? = null
|
||||
) {
|
||||
addToStack(
|
||||
fragmentClass,
|
||||
|
|
@ -178,7 +184,8 @@ open class FragmentNavigation(
|
|||
true,
|
||||
args,
|
||||
null,
|
||||
transactionSetup
|
||||
transactionSetup,
|
||||
tag
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -189,14 +196,16 @@ open class FragmentNavigation(
|
|||
* @param fragmentClass Class of [Fragment] to instantiate;
|
||||
* @param args Bundle to be set as [Fragment.getArguments] of instantiated [Fragment];
|
||||
* @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info.
|
||||
* @param tag Optional tag name for the [Fragment];
|
||||
*/
|
||||
fun setAsTop(
|
||||
fragmentClass: Class<out Fragment>,
|
||||
args: Bundle? = null,
|
||||
addToStack: Boolean = true,
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null,
|
||||
tag: String? = null
|
||||
) {
|
||||
addToStack(fragmentClass, null, 0, addToStack, args, TOP_FRAGMENT_TAG_MARK, transactionSetup)
|
||||
addToStack(fragmentClass, null, 0, addToStack, args, TOP_FRAGMENT_TAG_MARK, transactionSetup, tag)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -205,15 +214,17 @@ open class FragmentNavigation(
|
|||
* @param fragmentClass Class of [Fragment] to instantiate;
|
||||
* @param args Bundle to be set as [Fragment.getArguments] of instantiated [Fragment];
|
||||
* @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info.
|
||||
* @param tag Optional tag name for the [Fragment];
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun setInitial(
|
||||
fragmentClass: Class<out Fragment>,
|
||||
args: Bundle? = null,
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null,
|
||||
tag: String? = null
|
||||
) {
|
||||
beforeSetInitialActions()
|
||||
setAsTop(fragmentClass, args, false, transactionSetup)
|
||||
setAsTop(fragmentClass, args, false, transactionSetup, tag)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ open class ViewControllerNavigation<TActivity : FragmentActivity>(
|
|||
* @param addToStack Flag to add this transaction to the back stack;
|
||||
* @param backStackName Name of [Fragment] in back stack;
|
||||
* @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info;
|
||||
* @param tag Optional tag name for the [Fragment];
|
||||
* @param TState Type of state of fragment.
|
||||
*/
|
||||
fun <TState : Parcelable> pushViewController(
|
||||
|
|
@ -59,7 +60,8 @@ open class ViewControllerNavigation<TActivity : FragmentActivity>(
|
|||
state: TState,
|
||||
addToStack: Boolean = true,
|
||||
backStackName: String? = null,
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null,
|
||||
tag: String? = null
|
||||
) {
|
||||
addToStack(
|
||||
ViewControllerFragment::class.java,
|
||||
|
|
@ -68,7 +70,8 @@ open class ViewControllerNavigation<TActivity : FragmentActivity>(
|
|||
addToStack,
|
||||
ViewControllerFragment.args(viewControllerClass, state),
|
||||
backStackName,
|
||||
transactionSetup
|
||||
transactionSetup,
|
||||
tag
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -81,6 +84,7 @@ open class ViewControllerNavigation<TActivity : FragmentActivity>(
|
|||
* @param state [Parcelable] of [ViewController]'s fragment;
|
||||
* @param backStackName Name of [Fragment] in back stack;
|
||||
* @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info;
|
||||
* @param tag Optional tag name for the [Fragment];
|
||||
* @param TState Type of state of fragment;
|
||||
* @param TTargetFragment Type of target fragment.
|
||||
*/
|
||||
|
|
@ -90,7 +94,8 @@ open class ViewControllerNavigation<TActivity : FragmentActivity>(
|
|||
targetFragment: TTargetFragment,
|
||||
targetRequestCode: Int,
|
||||
backStackName: String? = null,
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null,
|
||||
tag: String? = null
|
||||
) {
|
||||
addToStack(
|
||||
ViewControllerFragment::class.java,
|
||||
|
|
@ -99,7 +104,8 @@ open class ViewControllerNavigation<TActivity : FragmentActivity>(
|
|||
true,
|
||||
ViewControllerFragment.args(viewControllerClass, state),
|
||||
backStackName,
|
||||
transactionSetup
|
||||
transactionSetup,
|
||||
tag
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -110,13 +116,15 @@ open class ViewControllerNavigation<TActivity : FragmentActivity>(
|
|||
* @param viewControllerClass Class of [ViewController] to be pushed;
|
||||
* @param state [Parcelable] of [ViewController]'s fragment;
|
||||
* @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info;
|
||||
* @param tag Optional tag name for the [Fragment];
|
||||
* @param TState Type of state of fragment.
|
||||
*/
|
||||
fun <TState : Parcelable> setViewControllerAsTop(
|
||||
viewControllerClass: Class<out ViewController<out TActivity, TState>>,
|
||||
state: TState,
|
||||
addToStack: Boolean = true,
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null,
|
||||
tag: String? = null
|
||||
) {
|
||||
addToStack(
|
||||
ViewControllerFragment::class.java,
|
||||
|
|
@ -125,7 +133,8 @@ open class ViewControllerNavigation<TActivity : FragmentActivity>(
|
|||
addToStack,
|
||||
ViewControllerFragment.args(viewControllerClass, state),
|
||||
TOP_FRAGMENT_TAG_MARK,
|
||||
transactionSetup
|
||||
transactionSetup,
|
||||
tag
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -136,15 +145,17 @@ open class ViewControllerNavigation<TActivity : FragmentActivity>(
|
|||
* @param viewControllerClass Class of [ViewController] to be pushed;
|
||||
* @param state [Parcelable] of [ViewController]'s fragment;
|
||||
* @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info;
|
||||
* @param tag Optional tag name for the [Fragment];
|
||||
* @param TState Type of state of fragment.
|
||||
*/
|
||||
fun <TState : Parcelable> setInitialViewController(
|
||||
viewControllerClass: Class<out ViewController<out TActivity, TState>>,
|
||||
state: TState,
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null
|
||||
transactionSetup: ((FragmentTransaction) -> Unit)? = null,
|
||||
tag: String? = null
|
||||
) {
|
||||
beforeSetInitialActions()
|
||||
setViewControllerAsTop(viewControllerClass, state, false, transactionSetup)
|
||||
setViewControllerAsTop(viewControllerClass, state, false, transactionSetup, tag)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,300 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
|
||||
*
|
||||
* This file is part of RoboSwag library.
|
||||
*
|
||||
* 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 ru.touchin.roboswag.components.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
import android.text.Html;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.style.URLSpan;
|
||||
import android.text.util.Linkify;
|
||||
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 android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* Created by Gavriil Sitnikov on 13/11/2015.
|
||||
* General utilities related to UI (Inflation, Views, Metrics, Activities etc.).
|
||||
*/
|
||||
public final class UiUtils {
|
||||
|
||||
/**
|
||||
* Method to inflate view with right layout parameters based on container and add inflated view as a child to it.
|
||||
*
|
||||
* @param layoutId Id of layout resource;
|
||||
* @param parent Container to rightly resolve layout parameters of view in XML;
|
||||
* @return Inflated view.
|
||||
*/
|
||||
@NonNull
|
||||
public static View inflateAndAdd(@LayoutRes final int layoutId, @NonNull final ViewGroup parent) {
|
||||
LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, true);
|
||||
return parent.getChildAt(parent.getChildCount() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to inflate view with right layout parameters based on container but not adding inflated view as a child to it.
|
||||
*
|
||||
* @param layoutId Id of layout resource;
|
||||
* @param parent Container to rightly resolve layout parameters of view in XML;
|
||||
* @return Inflated view.
|
||||
*/
|
||||
@NonNull
|
||||
public static View inflate(@LayoutRes final int layoutId, @NonNull final ViewGroup parent) {
|
||||
return LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert text with 'href' tags and raw links to spanned text with clickable URLSpan.
|
||||
*/
|
||||
@NonNull
|
||||
public static Spanned getSpannedTextWithUrls(@NonNull final String text) {
|
||||
final Spannable spannableText = new SpannableString(Html.fromHtml(text));
|
||||
// Linkify removes all previous URLSpan's, we need to save all created spans for reapply after Linkify
|
||||
final URLSpan[] spans = spannableText.getSpans(0, text.length(), URLSpan.class);
|
||||
final int[] starts = new int[spans.length];
|
||||
final int[] ends = new int[spans.length];
|
||||
for (int index = 0; index < spans.length; index++) {
|
||||
starts[index] = spannableText.getSpanStart(spans[index]);
|
||||
ends[index] = spannableText.getSpanEnd(spans[index]);
|
||||
}
|
||||
Linkify.addLinks(spannableText, Linkify.WEB_URLS);
|
||||
for (int index = 0; index < spans.length; index++) {
|
||||
spannableText.setSpan(spans[index], starts[index], ends[index], Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
return spannableText;
|
||||
}
|
||||
|
||||
private UiUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Utilities methods related to metrics.
|
||||
*/
|
||||
public static class OfMetrics {
|
||||
|
||||
private static final int MAX_METRICS_TRIES_COUNT = 5;
|
||||
|
||||
/**
|
||||
* Returns right metrics with non-zero height/width.
|
||||
* It is common bug when metrics are calling at {@link Application#onCreate()} method and it returns metrics with zero height/width.
|
||||
*
|
||||
* @param context {@link Context} of metrics;
|
||||
* @return {@link DisplayMetrics}.
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply converts DP to pixels.
|
||||
*
|
||||
* @param context {@link Context} of metrics;
|
||||
* @param sizeInDp Size in DP;
|
||||
* @return Size in pixels.
|
||||
*/
|
||||
public static float dpToPixels(@NonNull final Context context, final float sizeInDp) {
|
||||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sizeInDp, getDisplayMetrics(context));
|
||||
}
|
||||
|
||||
public static int pixelsToDp(@NonNull final Context context, final int pixels) {
|
||||
return (int) (pixels * getDisplayMetrics(context).density + 0.5f);
|
||||
}
|
||||
|
||||
private OfMetrics() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Utilities methods related to activities and it'sintents.
|
||||
*/
|
||||
public static class OfActivities {
|
||||
|
||||
/**
|
||||
* Returns action bar (on top like toolbar or appbar) common height (56dp).
|
||||
*
|
||||
* @param activity Activity of action bar;
|
||||
* @return Height of action bar.
|
||||
*/
|
||||
public static int getActionBarHeight(@NonNull final Activity activity) {
|
||||
return (int) OfMetrics.dpToPixels(activity, 56);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns status bar (on top where system info is) common height.
|
||||
*
|
||||
* @param activity Activity of status bar;
|
||||
* @return Height of status bar.
|
||||
*/
|
||||
public static int getStatusBarHeight(@NonNull final Activity activity) {
|
||||
final int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
|
||||
return resourceId > 0 ? activity.getResources().getDimensionPixelSize(resourceId) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns navigation bar (on bottom where system buttons are) common height.
|
||||
* Be aware that some devices have no software keyboard (check it by {@link #hasSoftKeys(Activity)}) but this method will return you
|
||||
* size like they are showed.
|
||||
*
|
||||
* @param activity Activity of navigation bar;
|
||||
* @return Height of navigation bar.
|
||||
*/
|
||||
public static int getNavigationBarHeight(@NonNull final Activity activity) {
|
||||
if (hasSoftKeys(activity)) {
|
||||
final int resourceId = activity.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
|
||||
return resourceId > 0 ? activity.getResources().getDimensionPixelSize(resourceId) : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if device has software keyboard at navigation bar or not.
|
||||
*
|
||||
* @param activity Activity of navigation bar;
|
||||
* @return True if software keyboard is showing at navigation bar.
|
||||
*/
|
||||
//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;
|
||||
}
|
||||
|
||||
final boolean hasMenuKey = ViewConfiguration.get(activity).hasPermanentMenuKey();
|
||||
final boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
|
||||
return !hasMenuKey && !hasBackKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if {@link Intent} could be handled by system.
|
||||
*
|
||||
* @param context {@link Context} of application;
|
||||
* @param intent {@link Intent} to be handled;
|
||||
* @return True if there are handlers for {@link Intent} (e.g. browser could handle URI intent).
|
||||
*/
|
||||
public static boolean isIntentAbleToHandle(@NonNull final Context context, @NonNull final Intent intent) {
|
||||
return !context.getPackageManager().queryIntentActivities(intent, 0).isEmpty();
|
||||
}
|
||||
|
||||
private OfActivities() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Utilities methods related to views.
|
||||
*/
|
||||
public static class OfViews {
|
||||
|
||||
/**
|
||||
* Returns string representation of {@link View}'s ID.
|
||||
*
|
||||
* @param view {@link View} to get ID from;
|
||||
* @return Readable ID.
|
||||
*/
|
||||
@NonNull
|
||||
public static String getViewIdString(@NonNull final View view) {
|
||||
try {
|
||||
return view.getResources().getResourceName(view.getId());
|
||||
} catch (final Resources.NotFoundException exception) {
|
||||
return String.valueOf(view.getId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides device keyboard for target activity.
|
||||
*/
|
||||
public static void hideSoftInput(@NonNull final Activity activity) {
|
||||
final View focusedView = activity.getCurrentFocus();
|
||||
if (focusedView != null) {
|
||||
hideSoftInput(focusedView);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides device keyboard for target view.
|
||||
*/
|
||||
public static void hideSoftInput(@NonNull final View view) {
|
||||
view.clearFocus();
|
||||
final InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (inputManager != null) {
|
||||
inputManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows device keyboard over {@link Activity} and focuses {@link View}.
|
||||
* Do NOT use it if keyboard is over {@link android.app.Dialog} - it won't work as they have different {@link Activity#getWindow()}.
|
||||
* Do NOT use it if you are not sure that view is already added on screen.
|
||||
*
|
||||
* @param view View to get focus for input from keyboard.
|
||||
*/
|
||||
public static void showSoftInput(@NonNull final View view) {
|
||||
view.requestFocus();
|
||||
final InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (inputManager != null) {
|
||||
inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
|
||||
}
|
||||
}
|
||||
|
||||
private OfViews() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
|
||||
*
|
||||
* This file is part of RoboSwag library.
|
||||
*
|
||||
* 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 ru.touchin.roboswag.components.utils
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.res.Resources
|
||||
import android.os.Build
|
||||
import android.util.DisplayMetrics
|
||||
import android.util.TypedValue
|
||||
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 android.view.inputmethod.InputMethodManager
|
||||
import androidx.annotation.LayoutRes
|
||||
import ru.touchin.roboswag.components.utils.spans.getSpannedTextWithUrls
|
||||
|
||||
/**
|
||||
* Created by Gavriil Sitnikov on 13/11/2015.
|
||||
* General utilities related to UI (Inflation, Views, Metrics, Activities etc.).
|
||||
*/
|
||||
object UiUtils {
|
||||
|
||||
/**
|
||||
* Method to inflate view with right layout parameters based on container and add inflated view as a child to it.
|
||||
*
|
||||
* @param layoutId Id of layout resource;
|
||||
* @param parent Container to rightly resolve layout parameters of view in XML;
|
||||
* @return Inflated view.
|
||||
*/
|
||||
fun inflateAndAdd(@LayoutRes layoutId: Int, parent: ViewGroup): View {
|
||||
LayoutInflater.from(parent.context).inflate(layoutId, parent, true)
|
||||
return parent.getChildAt(parent.childCount - 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to inflate view with right layout parameters based on container but not adding inflated view as a child to it.
|
||||
*
|
||||
* @param layoutId Id of layout resource;
|
||||
* @param parent Container to rightly resolve layout parameters of view in XML;
|
||||
* @return Inflated view.
|
||||
*/
|
||||
fun inflate(@LayoutRes layoutId: Int, parent: ViewGroup): View = LayoutInflater.from(parent.context).inflate(layoutId, parent, false)
|
||||
|
||||
/**
|
||||
* Convert text with 'href' tags and raw links to spanned text with clickable URLSpan.
|
||||
*/
|
||||
@Deprecated(
|
||||
"use extension in SpanUtils",
|
||||
ReplaceWith("text.getSpannedTextWithUrls(removeUnderline = false)", "ru.touchin.roboswag.components.utils.spans.getSpannedTextWithUrls")
|
||||
)
|
||||
fun getSpannedTextWithUrls(text: String) = text.getSpannedTextWithUrls(removeUnderline = false)
|
||||
|
||||
/**
|
||||
* Utilities methods related to metrics.
|
||||
*/
|
||||
object OfMetrics {
|
||||
|
||||
private const val MAX_METRICS_TRIES_COUNT = 5
|
||||
|
||||
/**
|
||||
* Returns right metrics with non-zero height/width.
|
||||
* It is common bug when metrics are calling at [Application.onCreate] method and it returns metrics with zero height/width.
|
||||
*
|
||||
* @param context [Context] of metrics;
|
||||
* @return [DisplayMetrics].
|
||||
*/
|
||||
fun getDisplayMetrics(context: Context): DisplayMetrics {
|
||||
var result = context.resources.displayMetrics
|
||||
// it is needed to avoid bug with invalid metrics when user restore application from other application
|
||||
var metricsTryNumber = 0
|
||||
while (metricsTryNumber < MAX_METRICS_TRIES_COUNT && (result.heightPixels <= 0 || result.widthPixels <= 0)) {
|
||||
try {
|
||||
Thread.sleep(500)
|
||||
} catch (ignored: InterruptedException) {
|
||||
return result
|
||||
}
|
||||
|
||||
result = context.resources.displayMetrics
|
||||
metricsTryNumber++
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply converts DP to pixels.
|
||||
*
|
||||
* @param context [Context] of metrics;
|
||||
* @param sizeInDp Size in DP;
|
||||
* @return Size in pixels.
|
||||
*/
|
||||
fun dpToPixels(context: Context, sizeInDp: Float): Float =
|
||||
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sizeInDp, getDisplayMetrics(context))
|
||||
|
||||
fun pixelsToDp(context: Context, pixels: Int): Int = (pixels * getDisplayMetrics(context).density + 0.5f).toInt()
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Utilities methods related to activities and it'sintents.
|
||||
*/
|
||||
object OfActivities {
|
||||
|
||||
/**
|
||||
* Returns action bar (on top like toolbar or appbar) common height (56dp).
|
||||
*
|
||||
* @param activity Activity of action bar;
|
||||
* @return Height of action bar.
|
||||
*/
|
||||
fun getActionBarHeight(activity: Activity): Int = OfMetrics.dpToPixels(activity, 56f).toInt()
|
||||
|
||||
/**
|
||||
* Returns status bar (on top where system info is) common height.
|
||||
*
|
||||
* @param activity Activity of status bar;
|
||||
* @return Height of status bar.
|
||||
*/
|
||||
fun getStatusBarHeight(activity: Activity): Int {
|
||||
val resourceId = activity.resources.getIdentifier("status_bar_height", "dimen", "android")
|
||||
return if (resourceId > 0) activity.resources.getDimensionPixelSize(resourceId) else 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns navigation bar (on bottom where system buttons are) common height.
|
||||
* Be aware that some devices have no software keyboard (check it by [.hasSoftKeys]) but this method will return you
|
||||
* size like they are showed.
|
||||
*
|
||||
* @param activity Activity of navigation bar;
|
||||
* @return Height of navigation bar.
|
||||
*/
|
||||
fun getNavigationBarHeight(activity: Activity): Int {
|
||||
if (hasSoftKeys(activity)) {
|
||||
val resourceId = activity.resources.getIdentifier("navigation_bar_height", "dimen", "android")
|
||||
return if (resourceId > 0) activity.resources.getDimensionPixelSize(resourceId) else 0
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if device has software keyboard at navigation bar or not.
|
||||
*
|
||||
* @param activity Activity of navigation bar;
|
||||
* @return True if software keyboard is showing at navigation bar.
|
||||
*/
|
||||
//http://stackoverflow.com/questions/14853039/how-to-tell-whether-an-android-device-has-hard-keys/14871974#14871974
|
||||
fun hasSoftKeys(activity: Activity): Boolean {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
val display = activity.windowManager.defaultDisplay
|
||||
|
||||
val realDisplayMetrics = DisplayMetrics().also(display::getRealMetrics)
|
||||
|
||||
val displayMetrics = DisplayMetrics().also(display::getMetrics)
|
||||
|
||||
|
||||
return realDisplayMetrics.widthPixels - displayMetrics.widthPixels > 0
|
||||
|| realDisplayMetrics.heightPixels - displayMetrics.heightPixels > 0
|
||||
}
|
||||
|
||||
val hasMenuKey = ViewConfiguration.get(activity).hasPermanentMenuKey()
|
||||
val hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK)
|
||||
return !hasMenuKey && !hasBackKey
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if [Intent] could be handled by system.
|
||||
*
|
||||
* @param context [Context] of application;
|
||||
* @param intent [Intent] to be handled;
|
||||
* @return True if there are handlers for [Intent] (e.g. browser could handle URI intent).
|
||||
*/
|
||||
fun isIntentAbleToHandle(context: Context, intent: Intent): Boolean = context.packageManager.queryIntentActivities(intent, 0).isNotEmpty()
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Utilities methods related to views.
|
||||
*/
|
||||
object OfViews {
|
||||
|
||||
/**
|
||||
* Returns string representation of [View]'s ID.
|
||||
*
|
||||
* @param view [View] to get ID from;
|
||||
* @return Readable ID.
|
||||
*/
|
||||
fun getViewIdString(view: View): String = try {
|
||||
view.resources.getResourceName(view.id)
|
||||
} catch (exception: Resources.NotFoundException) {
|
||||
view.id.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides device keyboard for target activity.
|
||||
*/
|
||||
fun hideSoftInput(activity: Activity) {
|
||||
activity.currentFocus?.let(this::hideSoftInput)
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides device keyboard for target view.
|
||||
*/
|
||||
fun hideSoftInput(view: View) {
|
||||
view.clearFocus()
|
||||
val inputManager = view.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
inputManager.hideSoftInputFromWindow(view.windowToken, 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows device keyboard over [Activity] and focuses [View].
|
||||
* Do NOT use it if keyboard is over [android.app.Dialog] - it won't work as they have different [Activity.getWindow].
|
||||
* Do NOT use it if you are not sure that view is already added on screen.
|
||||
*
|
||||
* @param view View to get focus for input from keyboard.
|
||||
*/
|
||||
fun showSoftInput(view: View) {
|
||||
view.requestFocus()
|
||||
val inputManager = view.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -17,12 +17,10 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package ru.touchin.roboswag.components.utils.spans;
|
||||
package ru.touchin.roboswag.components.utils.spans
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.text.TextPaint;
|
||||
import android.text.style.URLSpan;
|
||||
import android.text.TextPaint
|
||||
import androidx.annotation.ColorInt
|
||||
|
||||
/**
|
||||
* Created by Anton Arhipov on 05/07/2017.
|
||||
|
|
@ -32,21 +30,11 @@ import android.text.style.URLSpan;
|
|||
* and
|
||||
* textView.setText(spannableString, TextView.BufferType.SPANNABLE);
|
||||
*/
|
||||
public class ColoredUrlSpan extends URLSpan {
|
||||
class ColoredUrlSpan(@ColorInt private val textColor: Int, url: String) : URLSpanWithoutUnderline(url) {
|
||||
|
||||
@ColorInt
|
||||
private final int textColor;
|
||||
|
||||
public ColoredUrlSpan(@ColorInt final int textColor, @NonNull final String url) {
|
||||
super(url);
|
||||
this.textColor = textColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDrawState(@NonNull final TextPaint ds) {
|
||||
super.updateDrawState(ds);
|
||||
ds.setUnderlineText(false);
|
||||
ds.setColor(textColor);
|
||||
override fun updateDrawState(ds: TextPaint) {
|
||||
super.updateDrawState(ds)
|
||||
ds.color = textColor
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
package ru.touchin.roboswag.components.utils.spans;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.text.TextPaint;
|
||||
import android.text.style.URLSpan;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Created by Gavriil Sitnikov on 14/11/2015.
|
||||
* Span that is opening phone call intent.
|
||||
*/
|
||||
public class PhoneSpan extends URLSpan {
|
||||
|
||||
public PhoneSpan(@NonNull final String phoneNumber) {
|
||||
super(phoneNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(@NonNull final View widget) {
|
||||
super.onClick(widget);
|
||||
try {
|
||||
final Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||
intent.setData(Uri.parse(getURL()));
|
||||
widget.getContext().startActivity(intent);
|
||||
} catch (final ActivityNotFoundException exception) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDrawState(@NonNull final TextPaint ds) {
|
||||
super.updateDrawState(ds);
|
||||
ds.setUnderlineText(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package ru.touchin.roboswag.components.utils.spans
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.view.View
|
||||
|
||||
/**
|
||||
* Created by Gavriil Sitnikov on 14/11/2015.
|
||||
* Span that is opening phone call intent.
|
||||
*/
|
||||
class PhoneSpan(phoneNumber: String) : URLSpanWithoutUnderline(phoneNumber) {
|
||||
|
||||
override fun onClick(widget: View) {
|
||||
super.onClick(widget)
|
||||
try {
|
||||
val intent = Intent(Intent.ACTION_DIAL)
|
||||
intent.data = Uri.parse(url)
|
||||
widget.context.startActivity(intent)
|
||||
} catch (exception: ActivityNotFoundException) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package ru.touchin.roboswag.components.utils.spans
|
||||
|
||||
import android.text.SpannableString
|
||||
import android.text.Spanned
|
||||
import android.text.style.URLSpan
|
||||
import android.text.util.Linkify
|
||||
import androidx.core.text.HtmlCompat
|
||||
|
||||
/**
|
||||
* Convert text with 'href' tags and raw links to spanned text with clickable URLSpan.
|
||||
*/
|
||||
fun String.getSpannedTextWithUrls(
|
||||
removeUnderline: Boolean = true,
|
||||
flags: Int = HtmlCompat.FROM_HTML_MODE_COMPACT
|
||||
): Spanned {
|
||||
|
||||
val spannableText = SpannableString(HtmlCompat.fromHtml(this, flags))
|
||||
|
||||
// Linkify removes all previous URLSpan's, we need to save all created spans for reapply after Linkify
|
||||
val spans = spannableText.getUrlSpans()
|
||||
Linkify.addLinks(spannableText, Linkify.WEB_URLS)
|
||||
spans.forEach {
|
||||
spannableText.setSpan(it.span, it.start, it.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
|
||||
if (!removeUnderline) {
|
||||
spannableText.getUrlSpans()
|
||||
.forEach { urlSpan ->
|
||||
spannableText.removeSpan(urlSpan.span)
|
||||
spannableText.setSpan(
|
||||
URLSpanWithoutUnderline(urlSpan.span.url),
|
||||
urlSpan.start,
|
||||
urlSpan.end,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
}
|
||||
}
|
||||
return spannableText
|
||||
}
|
||||
|
||||
private fun SpannableString.getUrlSpans() = getSpans(0, length, URLSpan::class.java)
|
||||
.map { UrlSpanWithBorders(it, this.getSpanStart(it), this.getSpanEnd(it)) }
|
||||
|
||||
private data class UrlSpanWithBorders(val span: URLSpan, val start: Int, val end: Int)
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
|
||||
*
|
||||
* This file is part of RoboSwag library.
|
||||
*
|
||||
* 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 ru.touchin.roboswag.components.utils.spans;
|
||||
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.text.TextPaint;
|
||||
import android.text.style.MetricAffectingSpan;
|
||||
|
||||
/**
|
||||
* Created by Ilia Kurtov on 15/02/2016.
|
||||
* Span for typefaces in texts.
|
||||
* http://stackoverflow.com/a/15181195
|
||||
*/
|
||||
public class TypefaceSpan extends MetricAffectingSpan {
|
||||
|
||||
@NonNull
|
||||
private final Typeface typeface;
|
||||
|
||||
public TypefaceSpan(@NonNull final Typeface typeface) {
|
||||
super();
|
||||
this.typeface = typeface;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMeasureState(@NonNull final TextPaint textPaint) {
|
||||
textPaint.setTypeface(typeface);
|
||||
textPaint.setFlags(textPaint.getFlags() | Paint.SUBPIXEL_TEXT_FLAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDrawState(@NonNull final TextPaint textPaint) {
|
||||
textPaint.setTypeface(typeface);
|
||||
textPaint.setFlags(textPaint.getFlags() | Paint.SUBPIXEL_TEXT_FLAG);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
|
||||
*
|
||||
* This file is part of RoboSwag library.
|
||||
*
|
||||
* 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 ru.touchin.roboswag.components.utils.spans
|
||||
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Typeface
|
||||
import android.text.TextPaint
|
||||
import android.text.style.MetricAffectingSpan
|
||||
|
||||
/**
|
||||
* Created by Ilia Kurtov on 15/02/2016.
|
||||
* Span for typefaces in texts.
|
||||
* http://stackoverflow.com/a/15181195
|
||||
*/
|
||||
class TypefaceSpan(private val typeface: Typeface) : MetricAffectingSpan() {
|
||||
|
||||
override fun updateMeasureState(textPaint: TextPaint) {
|
||||
textPaint.typeface = typeface
|
||||
textPaint.flags = textPaint.flags or Paint.SUBPIXEL_TEXT_FLAG
|
||||
}
|
||||
|
||||
override fun updateDrawState(textPaint: TextPaint) {
|
||||
textPaint.typeface = typeface
|
||||
textPaint.flags = textPaint.flags or Paint.SUBPIXEL_TEXT_FLAG
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package ru.touchin.roboswag.components.utils.spans
|
||||
|
||||
import android.text.TextPaint
|
||||
import android.text.style.URLSpan
|
||||
|
||||
open class URLSpanWithoutUnderline(url: String) : URLSpan(url) {
|
||||
|
||||
override fun updateDrawState(ds: TextPaint) {
|
||||
super.updateDrawState(ds)
|
||||
ds.isUnderlineText = false
|
||||
}
|
||||
}
|
||||
|
|
@ -82,10 +82,10 @@ public class MaterialLoadingBar extends AppCompatImageView {
|
|||
final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MaterialLoadingBar,
|
||||
defStyleAttr,
|
||||
0);
|
||||
final int size = (int) typedArray.getDimension(R.styleable.MaterialLoadingBar_size, UiUtils.OfMetrics.dpToPixels(context, 48));
|
||||
final int size = (int) typedArray.getDimension(R.styleable.MaterialLoadingBar_size, UiUtils.OfMetrics.INSTANCE.dpToPixels(context, 48));
|
||||
final int color = typedArray.getColor(R.styleable.MaterialLoadingBar_color, getPrimaryColor(context));
|
||||
final float strokeWidth = typedArray.getDimension(R.styleable.MaterialLoadingBar_strokeWidth,
|
||||
UiUtils.OfMetrics.dpToPixels(context, 4));
|
||||
UiUtils.OfMetrics.INSTANCE.dpToPixels(context, 4));
|
||||
typedArray.recycle();
|
||||
|
||||
progressDrawable = new MaterialProgressDrawable(context, size);
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public class MaterialProgressDrawable extends Drawable implements Runnable, Anim
|
|||
this.size = size;
|
||||
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
paint.setStrokeWidth(UiUtils.OfMetrics.dpToPixels(context, DEFAULT_STROKE_WIDTH_DP));
|
||||
paint.setStrokeWidth(UiUtils.OfMetrics.INSTANCE.dpToPixels(context, DEFAULT_STROKE_WIDTH_DP));
|
||||
paint.setColor(Color.BLACK);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -326,8 +326,8 @@ public class TypefacedTextView extends AppCompatTextView {
|
|||
@SuppressLint("WrongCall")
|
||||
//WrongCall: actually this method is always calling from onMeasure
|
||||
private void computeScalableTextSize(final int maxWidth, final int maxHeight) {
|
||||
final int minDifference = (int) UiUtils.OfMetrics.dpToPixels(getContext(), 1);
|
||||
int difference = (int) UiUtils.OfMetrics.dpToPixels(getContext(), START_SCALABLE_DIFFERENCE);
|
||||
final int minDifference = (int) UiUtils.OfMetrics.INSTANCE.dpToPixels(getContext(), 1);
|
||||
int difference = (int) UiUtils.OfMetrics.INSTANCE.dpToPixels(getContext(), START_SCALABLE_DIFFERENCE);
|
||||
ScaleAction scaleAction = ScaleAction.DO_NOTHING;
|
||||
ScaleAction previousScaleAction = ScaleAction.DO_NOTHING;
|
||||
do {
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ public final class AttributesUtils {
|
|||
*/
|
||||
@NonNull
|
||||
public static String viewError(@NonNull final View view, @NonNull final String errorText) {
|
||||
return "Errors for view id=" + UiUtils.OfViews.getViewIdString(view) + ":\n" + errorText;
|
||||
return "Errors for view id=" + UiUtils.OfViews.INSTANCE.getViewIdString(view) + ":\n" + errorText;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue