Skip to content

Instantly share code, notes, and snippets.

@mbobiosio
Last active June 4, 2022 04:30
Show Gist options
  • Save mbobiosio/20a89a0b2927163a6e958b311495b52e to your computer and use it in GitHub Desktop.
Save mbobiosio/20a89a0b2927163a6e958b311495b52e to your computer and use it in GitHub Desktop.
//Get TAG for class name
val Any.TAG: String
get() {
return if (!javaClass.isAnonymousClass) {
val name = javaClass.simpleName
/** First 23 chars */
if (name.length > 23 && Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
name.substring(0, 23) else name
} else {
val name = javaClass.name
/** Last 23 chars */
if (name.length > 23 && Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
name.substring(name.length - 23, name.length) else name
}
}
//Change string from pascal case to snake case
@SuppressLint("DefaultLocale")
fun pascalCaseToSnakeCase(text: String): String {
val matcher = Pattern.compile("(?<=[a-z])[A-Z]").matcher(text)
val sb = StringBuffer()
while (matcher.find()) {
matcher.appendReplacement(sb, "_" + matcher.group().toLowerCase())
}
matcher.appendTail(sb)
return sb.toString().lowercase(Locale.getDefault())
}
/*
*Handle safe click listener to avoid double clicks
*/
fun View.setSafeClickListener(onSafeClick: (View) -> Unit) {
val safeClickListener = SafeClickLister { onSafeClick(it) }
setOnClickListener(safeClickListener)
}
class SafeClickLister(private var defaultInterval: Int = 1000,
private val onSafeClick: (View) -> Unit): View.OnClickListener {
private var lastItemClicked: Long = 0
override fun onClick(v: View) {
if (SystemClock.elapsedRealtime() - lastItemClicked < defaultInterval) return
lastItemClicked = SystemClock.elapsedRealtime()
onSafeClick(v)
}
}
//End safe click listener
/*
* This returns the sum value of a string by getting the alphabet position value
* e.g A=1, B=2, C=3
*/
fun getAlphabetPositionValue(name: String, surname: String): Int {
//Convert name to lower string to treat A and a the same
//replace spaces in name to eliminate 0
val signature = name.plus(surname).toLowerCase(Locale.ROOT).replace(" ", "")
val signatureSum = signature.sumBy {
it - 'a' + 1
}
return signatureSum
}
/*
* Material Dialog Extension
* */
fun Context.alertDialog(
@StyleRes style: Int = 0,
dialogBuilder: MaterialAlertDialogBuilder.() -> Unit
) {
MaterialAlertDialogBuilder(this, style)
.apply {
setCancelable(false)
dialogBuilder()
create()
show()
}
}
fun MaterialAlertDialogBuilder.negativeButton(
text: String? = "No",
onClick: (dialogInterface: DialogInterface) -> Unit = { it.dismiss() }
) {
this.setNegativeButton(text) { dialogInterface, _ ->
onClick(dialogInterface)
}
}
fun MaterialAlertDialogBuilder.positiveButton(
text: String? = "Yes",
onClick: (dialogInterface: DialogInterface) -> Unit = { it.dismiss() }
) {
this.setPositiveButton(text) { dialogInterface, _ ->
onClick(dialogInterface)
}
}
fun MaterialAlertDialogBuilder.neutralButton(
text: String? = "OK",
onClick: (dialogInterface: DialogInterface) -> Unit = { it.dismiss() }
) {
this.setNeutralButton(text) { dialogInterface, _ ->
onClick(dialogInterface)
}
}
/**
*
* Safely run some delayed tasks in a view as they will be tied to the lifecycle.
*
* @param durationInMillis delay task in millisecons
* @param dispatcher CoroutineDispatcher, defaults to Dispatchers.Main as view work is done on Main thread
* @param block the block of work to be done
*
* example:
*
* view.delayOnLifeCycle(500L) {
* // Do something
* }
*
* */
fun View.delayOnLifecycle(
duration: Long,
dispatcher: CoroutineDispatcher = Dispatchers.Main,
block: () -> Unit
): Job? = findViewTreeLifecycleOwner()?.let { lifecycleOwner ->
lifecycleOwner.lifecycle.coroutineScope.launch(dispatcher) {
delay(duration)
block()
}
}
/*
* onActivityResult has been deprecated with updates to androidx.activity:activity-ktx to 1.2.0.
* It has deprecated startActivityForResult in favour of registerForActivityResult
* This is a Kotlin Extension handle results
* Example usage
* private val result = registerForResult {result, data ->
when (result) {
RESULT_OK -> {
//Do something
} else -> {
//Do something
}
}
}
* */
fun AppCompatActivity.registerForResult(
onResult: (resultCode: Int, data: Intent?) -> Unit
): ActivityResultLauncher<Intent> {
return this.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
onResult(result.resultCode, result.data)
}
}
//End registerForResult
/*
* Dealing with TMDB genres?
* This will help you fix that
* This collects a list of Integers(genres ids) and returns a String(genre name)
*/
fun getGenre(ids: List<Int>): String{
var genre=""
for(i in ids ){
when (i) {
28 -> genre+="Action|"
12 -> genre+="Adventure|"
16 -> genre+="Animation|"
35 -> genre+="Comedy|"
80 -> genre+="Crime|"
99 -> genre+="Documentary|"
18 -> genre+="Drama|"
10751 -> genre+="Family|"
14 -> genre+="Fantasy|"
36 -> genre+="History|"
27 -> genre+="Horror|"
10402 -> genre+="Music|"
9648 -> genre+="Mystery|"
10749 -> genre+="Romance|"
878 -> genre+="Science Fiction|"
10770 -> genre+="TV Movie|"
53 -> genre+="Thriller|"
10752 -> genre+="War|"
37 -> genre+="Western|"
else -> genre+="Unresolved symbol:"+i
}
}
if(!genre.equals(""))
genre=genre.substring(0,genre.length-1)
return genre
}
//Get all viewGroup children
fun ViewGroup.getAllChildren(): List<View> {
val children = ArrayList<View>()
for (i in 0 until this.childCount) {
if (getChildAt(i) is ViewGroup) {
children.addAll((getChildAt(i) as ViewGroup).getAllChildren())
}
children.add(this.getChildAt(i))
}
return children
}
//Get End Index for MetaData
fun getMetaDataEndIndex(content: String): Int {
// The "cnt" variable stores how many "---" it has seen.
// It is sure that the meta data will be enclosed by only 2 of them,
var cnt = 0
// idx is the position where the meta data ends.
// We keep on increasing the idx until we are sure that meta data has ended.
var idx = 0
while (content[idx].isWhitespace()) idx++
while (cnt != 2) {
if (content.substring(idx, idx + 3) == "---") cnt++
idx++
}
// Increase idx by 2 because it is still at the
// first index of the second "---" exist
idx += 2
// ignore further whitespaces as they will be added later if needed.
while (content[idx].isWhitespace()) idx++
return idx
}
// Extract domain from email
fun domain(string: String): String? {
return string.indexOf('@').let {
if (it == 1) null else string.substring(it + 1)
}
}
// Convert map to list of maps
fun toListOfMaps(map: Map<String, String>): List<Map<String, String>> {
return map.map { (key, value) ->
mapOf(key to value)
}
}
// Format String as Credit Card Number
/**
* How to use
* val ccFormatted = "1234567890123456".creditCardFormatted
*/
val String.creditCardFormatted: String
get() {
val preparedString = replace(" ", "").trim()
val result = StringBuilder()
for (i in preparedString.indices) {
if (i % 4 == 0 && i != 0) {
result.append(" ")
}
result.append(preparedString[i])
}
return result.toString()
}
/**
Combining 3 different lists together.
val strings = listOf("1", "2", "3")
val ints = listOf(1, 2, 9)
val boolean = listOf(true, false, false)
strings.zipThree(ints, boolean) { one, two, three ->
Timber.d("$one : $two : $three")
}
*/
inline fun <T, R, E, V> Iterable<T>.zipThree(
other1: Iterable<R>,
other2: Iterable<E>,
transform: (T, R, E) -> V
): List<V> {
val first = iterator()
val second = other1.iterator()
val third = other2.iterator()
val list = ArrayList<V>()
while (first.hasNext() && second.hasNext() && third.hasNext()) {
list.add(transform(first.next(), second.next(), third.next()))
}
return list
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment