Last active
February 27, 2022 04:25
-
-
Save mukandrew/6f215791b294901fafab5b5b06f06399 to your computer and use it in GitHub Desktop.
Android Helper Extensions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* To prevent the device to put in sleep after a period of the time | |
* | |
* @param enablePreventSleep ON/OFF prevent sleep | |
*/ | |
internal fun FragmentActivity.setPreventSleep(enablePreventSleep: Boolean) { | |
if (enablePreventSleep) { | |
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) | |
} else { | |
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// region colorByContrast | |
/** | |
* @see (https://www.w3.org/TR/AERT/#color-contrast) | |
* This is an algorithm to resolve a good color for text based on the background color | |
* If the background color has brightness more than [MIN_DARK_BRIGHTNESS] | |
* that returns the black color, otherwise returns the WHITE color | |
*/ | |
private const val RED_VALUE = 299 | |
private const val GREEN_VALUE = 587 | |
private const val BLUE_VALUE = 114 | |
private const val MAGIC_NUMBER = 1000 | |
private const val MIN_DARK_BRIGHTNESS = 130 | |
internal fun Int.getColorByContrast(): Int { | |
if (android.R.color.transparent == this) return Color.BLACK | |
val rgb = intArrayOf(Color.red(this), Color.green(this), Color.blue(this)) | |
val brightness = ( | |
(rgb[0].times(RED_VALUE)) | |
.plus((rgb[1].times(GREEN_VALUE))) | |
.plus((rgb[2].times(BLUE_VALUE))) | |
).div(MAGIC_NUMBER) | |
return if (brightness <= MIN_DARK_BRIGHTNESS) Color.WHITE else Color.BLACK | |
} | |
// endregion |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal val Context.deviceHeight: Int | |
get() = resources.displayMetrics.heightPixels | |
internal val Context.deviceWidth: Int | |
get() = resources.displayMetrics.widthPixels | |
private const val STATUS_BAR_HEIGHT_NAME = "status_bar_height" | |
private const val STATUS_BAR_DEF_TYPE_NAME = "dimen" | |
private const val STATUS_BAR_DEF_PCKG_NAME = "android" | |
internal val Context.statusBarHeight: Int | |
get() { | |
var resultHeight = resources.getDimensionPixelSize( | |
R.dimen.default_status_bar_height | |
) | |
val statusBarHeightResId = resources.getIdentifier( | |
"status_bar_height", | |
"dimen", | |
"android" | |
) | |
if (statusBarHeightResId > 0) { | |
resultHeight = resources.getDimensionPixelSize(statusBarHeightResId) | |
} | |
return resultHeight | |
} | |
internal fun Context.openUrlInBrowser(url: String) { | |
try { | |
val uri = Uri.parse(url) | |
val intent = Intent(Intent.ACTION_VIEW, uri) | |
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) | |
startActivity(intent) | |
} catch (e: Exception) { | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* An extension to add a listener to the back pressed dispatcher from the Activity | |
*/ | |
internal fun Fragment.addBackPressedListener(callback: OnBackPressedCallback) { | |
activity?.onBackPressedDispatcher?.addCallback(viewLifecycleOwner, callback) | |
} | |
private const val MAIL_TO_VALUE = "mailto:" | |
/** | |
* An extension to compose a email for a respective e-mail address | |
* @param email fill with the address to | |
*/ | |
internal fun Fragment.sendMail( | |
email: String, | |
@StringRes chooserTitleRes: Int | |
) { | |
try { | |
val intent = Intent(Intent.ACTION_SENDTO) | |
intent.data = Uri.parse(MAIL_TO_VALUE) | |
intent.putExtra(Intent.EXTRA_EMAIL, arrayOf(email)) | |
requireContext().startActivity( | |
Intent.createChooser( | |
intent, | |
getString(chooserTitleRes) | |
) | |
) | |
} catch (e: Exception) { | |
Toast.makeText(requireContext(), e.message, Toast.LENGTH_SHORT).show() | |
} | |
} | |
/** | |
* An extension to close the keyboard, | |
* creating an workaround when the activity does not have the view with current focus | |
*/ | |
internal fun Fragment.closeKeyboard() { | |
val imm = | |
context?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager ?: return | |
val view = activity?.currentFocus ?: View(activity).apply { | |
requestFocus() | |
} | |
imm.hideSoftInputFromWindow(view.windowToken, 0) | |
} | |
/** | |
* Hide the SystemUI, that is: | |
* - NavigationBar | |
* - StatusBar | |
*/ | |
internal fun Fragment.hideSystemUI(root: View) { | |
ViewCompat.getWindowInsetsController(root)?.apply { | |
systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_SWIPE | |
hide(Type.navigationBars()) | |
hide(Type.statusBars()) | |
} | |
activity?.window?.apply { | |
WindowCompat.setDecorFitsSystemWindows(this, true) | |
} | |
} | |
/** | |
* Show the SystemUI, that is: | |
* - NavigationBar | |
* - StatusBar | |
*/ | |
internal fun Fragment.showSystemUI(root: View) { | |
ViewCompat.getWindowInsetsController(root)?.apply { | |
systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_SWIPE | |
show(Type.navigationBars()) | |
show(Type.statusBars()) | |
} | |
activity?.window?.apply { | |
WindowCompat.setDecorFitsSystemWindows(this, true) | |
} | |
} | |
/** | |
* When there are a lot of nested fragment and needs to get a specific fragment | |
*/ | |
internal inline fun <reified T : Fragment> Fragment.getParentFragmentByType(): T? { | |
var parent = parentFragment | |
while (parent != null && parent !is T) parent = parent.parentFragment | |
return (parent as? T) | |
} | |
/** | |
* Get the value set in the [setValueToSavedStateInBackStackEntry] | |
* | |
* @param removeAfter If you need to remove this value from savedState after get | |
*/ | |
internal fun <T> Fragment.getValueFromSavedStateInCurrentBackStackEntry( | |
key: String, | |
removeAfter: Boolean | |
): T? { | |
return findNavController().currentBackStackEntry?.savedStateHandle?.let { savedState -> | |
savedState.get<T>(key).also { if (removeAfter) savedState.remove<T>(key) } | |
} | |
} | |
/** | |
* When needs to send value to a back stack fragment | |
* | |
* This setter will put the value in the savedState to the backStack navigation entry, | |
* so you can get this value from any fragment existent in the backStackEntries | |
* | |
* @param keyValue a pair with the key value | |
* @param backStackEntryId The ID for the existent entry in the navigation back stack | |
*/ | |
internal fun <T> Fragment.setValueToSavedStateInBackStackEntry( | |
keyValue: Pair<String, T>, | |
backStackEntryId: Int | |
) { | |
findNavController().getBackStackEntry(backStackEntryId).savedStateHandle.set( | |
keyValue.first, | |
keyValue.second | |
) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* There is a problem using the plurals and getting the value for 0 quantity | |
* So, this function resolve this problem using the param zero to return when quantity is 0 | |
*/ | |
internal fun Resources.getQuantityStringZero( | |
@PluralsRes plurals: Int, | |
@StringRes zero: Int, | |
quantity: Int, | |
param: Int | |
): String { | |
if (quantity == 0) return getString(zero) | |
return getQuantityString(plurals, quantity, param) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal fun View.hideKeyboard() { | |
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager | |
imm.hideSoftInputFromWindow(this.windowToken, 0) | |
} | |
internal fun View.showKeyboard() { | |
if (requestFocus()) { | |
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager | |
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment