Kotlinextensions.com
A handy collection of most commonly used Kotlin extensions to boost your productivity.
Install / Use
/learn @ravidsrk/Kotlinextensions.comREADME
Kotlin Extensions
Curated list of Most commonly used Kotlin Extensions.
View
/**
* Extension method to provide simpler access to {@link View#getResources()#getString(int)}.
*/
fun View.getString(stringResId: Int): String = resources.getString(stringResId)
/**
* Extension method to show a keyboard for View.
*/
fun View.showKeyboard() {
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
this.requestFocus()
imm.showSoftInput(this, 0)
}
/**
* Try to hide the keyboard and returns whether it worked
* https://stackoverflow.com/questions/1109022/close-hide-the-android-soft-keyboard
*/
fun View.hideKeyboard(): Boolean {
try {
val inputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
return inputMethodManager.hideSoftInputFromWindow(windowToken, 0)
} catch (ignored: RuntimeException) { }
return false
}
/**
* Extension method to remove the required boilerplate for running code after a view has been
* inflated and measured.
*
* @author Antonio Leiva
* @see <a href="https://antonioleiva.com/kotlin-ongloballayoutlistener/>Kotlin recipes: OnGlobalLayoutListener</a>
*/
inline fun <T : View> T.afterMeasured(crossinline f: T.() -> Unit) {
viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
if (measuredWidth > 0 && measuredHeight > 0) {
viewTreeObserver.removeOnGlobalLayoutListener(this)
f()
}
}
})
}
/**
* Extension method to get ClickableSpan.
* e.g.
* val loginLink = getClickableSpan(context.getColorCompat(R.color.colorAccent), { })
*/
fun View.doOnLayout(onLayout: (View) -> Boolean) {
addOnLayoutChangeListener(object : View.OnLayoutChangeListener {
override fun onLayoutChange(view: View, left: Int, top: Int, right: Int, bottom: Int,
oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int) {
if (onLayout(view)) {
view.removeOnLayoutChangeListener(this)
}
}
})
}
/**
* Extension method to simplify view binding.
*/
fun <T : ViewDataBinding> View.bind() = DataBindingUtil.bind<T>(this) as T
/**
* Extension method to provide quicker access to the [LayoutInflater] from a [View].
*/
fun View.getLayoutInflater() = context.getLayoutInflater()
/**
* Transforms static java function Snackbar.make() to an extension function on View.
*/
fun View.showSnackbar(snackbarText: String, timeLength: Int) {
Snackbar.make(this, snackbarText, timeLength).show()
}
/**
* Extension method to update padding of view.
*
*/
fun View.updatePadding(paddingStart: Int = getPaddingStart(),
paddingTop: Int = getPaddingTop(),
paddingEnd: Int = getPaddingEnd(),
paddingBottom: Int = getPaddingBottom()) {
setPaddingRelative(paddingStart, paddingTop, paddingEnd, paddingBottom)
}
/**
* Triggers a snackbar message when the value contained by snackbarTaskMessageLiveEvent is modified.
*/
fun View.setupSnackbar(lifecycleOwner: LifecycleOwner,
snackbarMessageLiveEvent: SingleLiveEvent<Int>, timeLength: Int) {
snackbarMessageLiveEvent.observe(lifecycleOwner, Observer {
it?.let { showSnackbar(context.getString(it), timeLength) }
})
}
/**
* Extension method to set View's left padding.
*/
fun View.setPaddingLeft(value: Int) = setPadding(value, paddingTop, paddingRight, paddingBottom)
/**
* Extension method to set View's right padding.
*/
fun View.setPaddingRight(value: Int) = setPadding(paddingLeft, paddingTop, value, paddingBottom)
/**
* Extension method to set View's top padding.
*/
fun View.setPaddingTop(value: Int) = setPaddingRelative(paddingStart, value, paddingEnd, paddingBottom)
/**
* Extension method to set View's bottom padding.
*/
fun View.setPaddingBottom(value: Int) = setPaddingRelative(paddingStart, paddingTop, paddingEnd, value)
/**
* Extension method to set View's start padding.
*/
fun View.setPaddingStart(value: Int) = setPaddingRelative(value, paddingTop, paddingEnd, paddingBottom)
/**
* Extension method to set View's end padding.
*/
fun View.setPaddingEnd(value: Int) = setPaddingRelative(paddingStart, paddingTop, value, paddingBottom)
/**
* Extension method to set View's horizontal padding.
*/
fun View.setPaddingHorizontal(value: Int) = setPaddingRelative(value, paddingTop, value, paddingBottom)
/**
* Extension method to set View's vertical padding.
*/
fun View.setPaddingVertical(value: Int) = setPaddingRelative(paddingStart, value, paddingEnd, value)
/**
* Extension method to set View's height.
*/
fun View.setHeight(value: Int) {
val lp = layoutParams
lp?.let {
lp.height = value
layoutParams = lp
}
}
/**
* Extension method to set View's width.
*/
fun View.setWidth(value: Int) {
val lp = layoutParams
lp?.let {
lp.width = value
layoutParams = lp
}
}
/**
* Extension method to resize View with height & width.
*/
fun View.resize(width: Int, height: Int) {
val lp = layoutParams
lp?.let {
lp.width = width
lp.height = height
layoutParams = lp
}
}
/**
* Extension method to access the view's children as a list
*/
val ViewGroup.children: List<View>
get() = (0 until childCount).map { getChildAt(it) }
fun View.animateWidth(toValue: Int, duration: Long = DURATION, interpolator: Interpolator = INTERPOLATOR): AnimatePropsWrapper {
if (toValue == width || layoutParams == null) {
return AnimatePropsWrapper(null)
}
return AnimatePropsWrapper(ValueAnimator().apply {
setIntValues(width, toValue)
setDuration(duration)
setInterpolator(interpolator)
addUpdateListener {
val lp = layoutParams
lp.width = it.animatedValue as Int
layoutParams = lp
}
start()
})
}
/**
* Set an onclick listener
*/
fun <T : View> T.click(block: (T) -> Unit) = setOnClickListener { block(it as T) }
/**
* Extension method to set OnClickListener on a view.
*/
fun <T : View> T.longClick(block: (T) -> Boolean) = setOnLongClickListener { block(it as T) }
/**
* Show the view (visibility = View.VISIBLE)
*/
fun View.show() : View {
if (visibility != View.VISIBLE) {
visibility = View.VISIBLE
}
return this
}
/**
* Show the view if [condition] returns true
* (visibility = View.VISIBLE)
*/
inline fun View.showIf(condition: () -> Boolean) : View {
if (visibility != View.VISIBLE && block()) {
visibility = View.VISIBLE
}
return this
}
/**
* Hide the view. (visibility = View.INVISIBLE)
*/
fun View.hide() : View {
if (visibility != View.INVISIBLE) {
visibility = View.INVISIBLE
}
return this
}
/**
* Hide the view if [predicate] returns true
* (visibility = View.INVISIBLE)
*/
inline fun View.hideIf(predicate: () -> Boolean) : View {
if (visibility != View.INVISIBLE && block()) {
visibility = View.INVISIBLE
}
return this
}
/**
* Remove the view (visibility = View.GONE)
*/
fun View.remove() : View {
if (visibility != View.GONE) {
visibility = View.GONE
}
return this
}
/**
* Remove the view if [predicate] returns true
* (visibility = View.GONE)
*/
inline fun View.removeIf(predicate: () -> Boolean) : View {
if (visibility != View.GONE && block()) {
visibility = View.GONE
}
return this
}
/**
* Toggle a view's visibility
*/
fun View.toggleVisibility() : View {
if (visibility == View.VISIBLE) {
visibility = View.INVISIBLE
} else {
visibility = View.INVISIBLE
}
return this
}
/**
* Extension method to animate View's width by value.
*/
fun View.animateWidthBy(byValue: Int, duration: Long = DURATION, interpolator: Interpolator = INTERPOLATOR)
= animateWidth(width + byValue, duration, interpolator)
/**
* Extension method to animate ViewGroup's childs by height by value.
*/
fun View.ani
