Last active
December 8, 2024 17:01
-
-
Save legobyte/228a39750f5f7eadb7185e675c39137d to your computer and use it in GitHub Desktop.
Android code snippets in Kotlin
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
// Make EditText clickable not editable | |
fun makeEditTextClickable(et:EditText){ | |
et.isFocusableInTouchMode = false | |
et.isLongClickable = false | |
} | |
// extract activity from a given context | |
fun requireActivity(context: Context): Activity { | |
if (context is Activity) { | |
return context | |
} else if (context is ContextWrapper) { | |
return requireActivity(context.baseContext) | |
} | |
throw IllegalArgumentException("Unable to extract activity from $context") | |
} | |
// get uri from a resource id | |
fun resourceToUri(context: Context, resID: Int): Uri { | |
return Uri.parse( | |
ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + | |
context.resources.getResourcePackageName(resID) + '/' + | |
context.resources.getResourceTypeName(resID) + '/' + | |
context.resources.getResourceEntryName(resID) | |
) | |
} | |
// hide keyboard in an activity if present | |
fun hideKeyboard(activity: Activity) { | |
hideKeyboard(activity.currentFocus) | |
} | |
fun hideKeyboard(view: View?, rr: ResultReceiver? = null) { | |
if (view != null) { | |
view.clearFocus() | |
val imm = | |
view.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager | |
imm.hideSoftInputFromWindow(view.windowToken, 0, rr) | |
imm.hideSoftInputFromInputMethod(view.windowToken, 0) | |
} | |
} | |
// show keyboard for this view | |
fun showKeyboard(on: View) { | |
val inputMethodManager = on.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager | |
on.requestFocus() | |
inputMethodManager.toggleSoftInputFromWindow( | |
on.applicationWindowToken, | |
InputMethodManager.SHOW_IMPLICIT, 0 | |
) | |
// inputMethodManager.showSoftInput(on, InputMethodManager.SHOW_FORCED); | |
} | |
// make view and all children enabled or disabled | |
fun setEnabledRecursive(view:View, enabled: Boolean){ | |
view.isEnabled = enabled | |
if(view is ViewGroup){ | |
for (child in view.children) { | |
setEnabledRecursive(child, enabled) | |
} | |
} | |
} | |
// retreives the unique device id | |
fun deviceId(context: Context): String { | |
return Settings.Secure.getString( | |
context.contentResolver, | |
Settings.Secure.ANDROID_ID | |
) | |
} | |
// calculate the sample size | |
fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int { | |
// Raw height and width of image | |
val (height: Int, width: Int) = options.run { outHeight to outWidth } | |
var inSampleSize = 1 | |
if (height > reqHeight || width > reqWidth) { | |
val halfHeight: Int = height / 2 | |
val halfWidth: Int = width / 2 | |
// Calculate the largest inSampleSize value that is a power of 2 and keeps both | |
// height and width larger than the requested height and width. | |
while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) { | |
inSampleSize *= 2 | |
} | |
} | |
return inSampleSize | |
} | |
// get small bitmap from resource | |
// low memory usage | |
fun decodeSampledBitmapFromResource( | |
res: Resources, | |
resId: Int, | |
reqWidth: Int, | |
reqHeight: Int | |
): Bitmap { | |
// First decode with inJustDecodeBounds=true to check dimensions | |
return BitmapFactory.Options().run { | |
inJustDecodeBounds = true | |
BitmapFactory.decodeResource(res, resId, this) | |
// Calculate inSampleSize | |
inSampleSize = calculateInSampleSize(this, reqWidth, reqHeight) | |
// Decode bitmap with inSampleSize set | |
inJustDecodeBounds = false | |
BitmapFactory.decodeResource(res, resId, this) | |
} | |
} | |
// get small bitmap from file | |
// low memory usage | |
fun decodeSampledBitmapFromFile( | |
file: File, | |
reqWidth: Int, | |
reqHeight: Int | |
): Bitmap { | |
// First decode with inJustDecodeBounds=true to check dimensions | |
return BitmapFactory.Options().run { | |
inJustDecodeBounds = true | |
BitmapFactory.decodeFile(file.absolutePath, this) | |
// Calculate inSampleSize | |
inSampleSize = calculateInSampleSize(this, reqWidth, reqHeight) | |
// Decode bitmap with inSampleSize set | |
inJustDecodeBounds = false | |
BitmapFactory.decodeFile(file.absolutePath, this) | |
} | |
} | |
// return the md5 of the string | |
fun md5(what: String): String { | |
val MD5 = "MD5" | |
try { | |
// Create MD5 Hash | |
val digest: java.security.MessageDigest = java.security.MessageDigest.getInstance(MD5) | |
digest.update(what.toByteArray()) | |
val messageDigest: ByteArray = digest.digest() | |
// Create Hex String | |
val hexString: java.lang.StringBuilder = java.lang.StringBuilder() | |
for (aMessageDigest in messageDigest) { | |
var h: String = java.lang.Integer.toHexString(0xFF and aMessageDigest.toInt()) | |
while (h.length < 2) h = "0$h" | |
hexString.append(h) | |
} | |
return hexString.toString() | |
} catch (e: java.security.NoSuchAlgorithmException) { | |
e.printStackTrace() | |
} | |
return "" | |
} | |
// get distance between two Points | |
fun getDistance(from: Point, to: Point): Double { | |
return Math.sqrt( | |
Math.pow(from.x - to.x.toDouble(), 2.0) + | |
Math.pow(from.y - to.y.toDouble(), 2.0) | |
) | |
} | |
// get distance between two PointFs | |
fun getDistance(from: PointF, to: PointF): Double { | |
return Math.sqrt( | |
Math.pow(from.x - to.x.toDouble(), 2.0) + | |
Math.pow(from.y - to.y.toDouble(), 2.0) | |
) | |
} | |
// get angle from src to target Points | |
fun getAngle(src: Point, target: Point): Float { | |
var angle = Math.toDegrees( | |
Math.atan2( | |
target.y - src.y.toDouble(), | |
target.x - src.x.toDouble() | |
) | |
).toFloat() | |
if (angle < 0) { | |
angle += 360f | |
} | |
return angle | |
} | |
// get angle from src to target PointFs | |
fun getAngle(src: PointF, target: PointF): Float { | |
var angle = Math.toDegrees( | |
Math.atan2( | |
target.y - src.y.toDouble(), | |
target.x - src.x.toDouble() | |
) | |
).toFloat() | |
if (angle < 0) { | |
angle += 360f | |
} | |
return angle | |
} | |
// if @value smaller than the @min then return @min | |
// else if @value bigger than @max then return @max | |
// else return @value it self | |
fun minOrMax(value: Float, min: Float, max: Float): Float { | |
if (value < min) return min | |
return if (value > max) max else value | |
} | |
// check if @v is divisible by @d | |
fun isDivisible(v: Float, d: Float): Boolean { | |
return v % d == 0f | |
} | |
// check if @v is divisible by @d | |
fun isDivisible(v: Int, d: Int): Boolean { | |
return v % d == 0 | |
} | |
// evaluate color from color @startInt to color @endIt in @fraction | |
// fraction is between 0-1 | |
fun evaluateColor(fraction: Float, startInt: Int, endInt: Int): Int { | |
val startA = (startInt shr 24 and 0xff) / 255.0f | |
var startR = (startInt shr 16 and 0xff) / 255.0f | |
var startG = (startInt shr 8 and 0xff) / 255.0f | |
var startB = (startInt and 0xff) / 255.0f | |
val endA = (endInt shr 24 and 0xff) / 255.0f | |
var endR = (endInt shr 16 and 0xff) / 255.0f | |
var endG = (endInt shr 8 and 0xff) / 255.0f | |
var endB = (endInt and 0xff) / 255.0f | |
// convert from sRGB to linear | |
startR = Math.pow(startR.toDouble(), 2.2).toFloat() | |
startG = Math.pow(startG.toDouble(), 2.2).toFloat() | |
startB = Math.pow(startB.toDouble(), 2.2).toFloat() | |
endR = Math.pow(endR.toDouble(), 2.2).toFloat() | |
endG = Math.pow(endG.toDouble(), 2.2).toFloat() | |
endB = Math.pow(endB.toDouble(), 2.2).toFloat() | |
// compute the interpolated color in linear space | |
var a = startA + fraction * (endA - startA) | |
var r = startR + fraction * (endR - startR) | |
var g = startG + fraction * (endG - startG) | |
var b = startB + fraction * (endB - startB) | |
// convert back to sRGB in the [0..255] range | |
a = a * 255.0f | |
r = Math.pow(r.toDouble(), 1.0 / 2.2).toFloat() * 255.0f | |
g = Math.pow(g.toDouble(), 1.0 / 2.2).toFloat() * 255.0f | |
b = Math.pow(b.toDouble(), 1.0 / 2.2).toFloat() * 255.0f | |
return Math.round(a) shl 24 or (Math.round(r) shl 16) or (Math.round( | |
g | |
) shl 8) or Math.round(b) | |
} | |
// convert persian numbers to latin numbers in @text | |
fun persianNumbersToEnglishNumbers(text: String): String { | |
return text | |
.replace("۰", "0") | |
.replace("۱", "1") | |
.replace("۲", "2") | |
.replace("۳", "3") | |
.replace("۴", "4") | |
.replace("۵", "5") | |
.replace("۶", "6") | |
.replace("۷", "7") | |
.replace("۸", "8") | |
.replace("۹", "9") | |
} | |
// convert latin numbers to persian numbers in @text | |
fun englishNumbersToPersianNumbers(text: String): String { | |
return text | |
.replace("0", "۰") | |
.replace("1", "۱") | |
.replace("2", "۲") | |
.replace("3", "۳") | |
.replace("4", "۴") | |
.replace("5", "۵") | |
.replace("6", "۶") | |
.replace("7", "۷") | |
.replace("8", "۸") | |
.replace("9", "۹") | |
} | |
// convert long to readable byte in Binary | |
// Binary (1 K = 1,024) | |
fun humanReadableByteCountBin(bytes: Long): String { | |
val b = if (bytes == Long.MIN_VALUE) Long.MAX_VALUE else java.lang.Math.abs(bytes) | |
return if (b < 1024L) "$bytes B" else if (b <= 0xfffccccccccccccL shr 40) String.format("%.1f KiB", bytes / 0x1 p10 .0) else if (b <= 0xfffccccccccccccL shr 30) String.format("%.1f MiB", bytes / 0x1 p20 .0) else if (b <= 0xfffccccccccccccL shr 20) String.format("%.1f GiB", bytes / 0x1 p30 .0) else if (b <= 0xfffccccccccccccL shr 10) String.format("%.1f TiB", bytes / 0x1 p40 .0) else if (b <= 0xfffccccccccccccL) String.format("%.1f PiB", (bytes shr 10) / 0x1 p40 .0) else String.format("%.1f EiB", (bytes shr 20) / 0x1 p40 .0) | |
} | |
// convert long to readable byte | |
// SI (1 k = 1,000) | |
fun humanReadableByteCountSI(bytes: Long): String { | |
val s = if (bytes < 0) "-" else "" | |
var b = if (bytes == Long.MIN_VALUE) Long.MAX_VALUE else java.lang.Math.abs(bytes) | |
return if (b < 1000L) "$bytes B" else if (b < 999950L) String.format("%s%.1f kB", s, b / 1e3) else if (1000.let { b /= it; b } < 999950L) String.format("%s%.1f MB", s, b / 1e3) else if (1000.let { b /= it; b } < 999950L) String.format("%s%.1f GB", s, b / 1e3) else if (1000.let { b /= it; b } < 999950L) String.format("%s%.1f TB", s, b / 1e3) else if (1000.let { b /= it; b } < 999950L) String.format("%s%.1f PB", s, b / 1e3) else String.format("%s%.1f EB", s, b / 1e6) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment