Skip to content

Instantly share code, notes, and snippets.

View afollestad's full-sized avatar
📱

Aidan Follestad afollestad

📱
View GitHub Profile
import android.view.View
import java.lang.System.currentTimeMillis
private const val HALF_SECOND = 500L
/** @author Aidan Follestad (@afollestad) */
abstract class DebouncedOnClickListener(
private val delayBetweenClicks: Long = HALF_SECOND
) : View.OnClickListener {
import android.content.ContentValues
/**
* Returns a [ContentValues] instance which contains only values that have changed between
* the receiver (original) and parameter (new) instances.
*/
fun ContentValues.diffFrom(contentValues: ContentValues): ContentValues {
val diff = ContentValues()
for ((name, oldValue) in this.valueSet()) {
val newValue = contentValues.get(name)
import kotlin.math.ceil
const val SECOND: Long = 1000
const val MINUTE = SECOND * 60
const val HOUR = MINUTE * 60
const val DAY = HOUR * 24
const val WEEK = DAY * 7
const val MONTH = WEEK * 4
fun Long.timeString() = when {
import android.view.View
import android.view.ViewTreeObserver
fun View.onLayout(cb: () -> Unit) {
if (this.viewTreeObserver.isAlive) {
this.viewTreeObserver.addOnGlobalLayoutListener(
object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
cb()
this@onLayout.viewTreeObserver.removeOnGlobalLayoutListener(this)
@afollestad
afollestad / LiveDataDistinct.kt
Created December 7, 2018 06:59
Similar to an Rx operator. Filters out same-values from LiveData streams.
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.Observer
/** @author Aidan Follestad (@afollestad) */
class DistinctLiveData<T>(source1: LiveData<T>) : MediatorLiveData<T>() {
private var isInitialized = false
private var lastValue: T? = null
@afollestad
afollestad / TestLiveData.kt
Created December 7, 2018 07:00
Observe LiveData in a test like you can with Rx test subscribers.
/** @author Aidan Follestad (@afollestad) */
class TestLiveData<T>(data: LiveData<T>) {
private val receivedValues = mutableListOf<T>()
private val observer = Observer<T> { emission ->
emission?.let { receivedValues.add(it) }
}
init {
data.observeForever(observer)
@afollestad
afollestad / gist:e1ada7b0c1d3a390e4b97910846cba69
Created April 19, 2019 00:10
List of components that can be installed on Travis.ci
addon-google_apis-google-10
addon-google_apis-google-11
addon-google_apis-google-12
addon-google_apis-google-13
addon-google_apis-google-14
addon-google_apis-google-15
addon-google_apis-google-16
addon-google_apis-google-17
addon-google_apis-google-18
addon-google_apis-google-19
@afollestad
afollestad / LifecycleAwareDisposable.kt
Created December 14, 2018 19:09
Make an Observable Lifecycle aware - disposing itself when the lifecycle stops
/** @author Aidan Follestad (afollestad) */
class LifecycleAwareDisposable(
private val disposable: Disposable
) : LifecycleObserver {
@OnLifecycleEvent(ON_DESTROY)
fun dispose() = disposable.dispose()
}
/** @author Aidan Follestad (afollestad) */
@afollestad
afollestad / LivedataMap.kt
Created December 14, 2018 18:55
Map and switchMap live data with extension functions instead of method calls.
import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations
fun <X, Y> LiveData<X>.map(mapper: (X) -> Y) =
Transformations.map(this, mapper)!!
fun <X, Y> LiveData<X>.switchMap(mapper: (X) -> LiveData<Y>) =
Transformations.switchMap(this, mapper)!!
@afollestad
afollestad / ViewLifecycleOwner.kt
Created December 14, 2018 18:49
Create a lifecycle owner for a view without any boiler plate
import android.view.View
import android.view.View.OnAttachStateChangeListener
import androidx.lifecycle.LifecycleOwner
/** @author Aidan Follestad (@afollestad) */
class ViewLifecycleOwner(view: View) : LifecycleOwner, OnAttachStateChangeListener {
private val lifecycle = SimpleLifecycle(this)
init {