View AnimatedVectorDrawableMarkerIcon.kt
class AnimatedVectorDrawableMarkerIcon( | |
marker: Marker, | |
private val avd: AnimatedVectorDrawableCompat, | |
width: Int = avd.intrinsicWidth, | |
height: Int = avd.intrinsicHeight | |
) { | |
private val handler = Handler(Looper.getMainLooper()) | |
private val invalidateTask = Runnable { avd.invalidateSelf() } | |
private var isRunning = false | |
private var isAutoLoop = false |
View OneShotGlobalLayoutListener.kt
class OneShotGlobalLayoutListener private constructor( | |
private val view: View, | |
private val runnable: Runnable | |
) : ViewTreeObserver.OnGlobalLayoutListener, View.OnAttachStateChangeListener { | |
private var viewTreeObserver: ViewTreeObserver = view.viewTreeObserver | |
init { | |
view.viewTreeObserver.addOnGlobalLayoutListener(this) | |
view.addOnAttachStateChangeListener(this) | |
} |
View Pixel.kt
/** | |
* px/dp/sp/pt/mm unit converter. | |
* This is not incompatible with Jetpack Compose. | |
*/ | |
inline class Pixel(private val pxF: Float) { | |
val toPx: Int @Px get() = pxF.roundToInt() | |
fun toDp(res: Resources = Resources.getSystem()): Float = pxF / TypedValue.applyDimension( | |
TypedValue.COMPLEX_UNIT_DIP, 1.0f, res.displayMetrics | |
) |
View _LocaleTimePicker.java
public class LocaleTimePicker extends TimePicker { | |
public LocaleTimePicker(Context context) { | |
this(context, null); | |
} | |
public LocaleTimePicker(Context context, @Nullable AttributeSet attrs) { | |
this(context, attrs, Resources.getSystem().getIdentifier("timePickerStyle", "attr", "android")); | |
} |
View DimBehindPopupWindow.kt
val popup = PopupWindow(...) | |
val container = popup.contentView.takeIf { it.layoutParams is WindowManager.LayoutParams } | |
?: (popup.contentView.parent as? View)?.takeIf { it.layoutParams is WindowManager.LayoutParams } | |
?: (popup.contentView.parent.parent as? View)?.takeIf { it.layoutParams is WindowManager.LayoutParams } | |
?: throw IllegalStateException("NO WindowManager.LayoutParams!") | |
val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager | |
val lp = container.layoutParams as WindowManager.LayoutParams | |
lp.flags = lp.flags or WindowManager.LayoutParams.FLAG_DIM_BEHIND |
View Rx+mapNotNull.kt
fun <T, R> Observable<T>.mapNotNull(mapper: (T) -> R?): Observable<R> { | |
return lift { observer -> | |
object: Observer<T> { | |
override fun onNext(t: T) { | |
mapper(t)?.let { observer.onNext(it) } | |
} | |
override fun onComplete() { | |
observer.onComplete() | |
} | |
override fun onError(e: Throwable) { |
View expand.kt
import io.reactivex.Flowable | |
import io.reactivex.Maybe | |
import io.reactivex.Observable | |
import io.reactivex.Single | |
import io.reactivex.rxkotlin.Flowables | |
import io.reactivex.rxkotlin.Maybes | |
import io.reactivex.rxkotlin.Observables | |
import io.reactivex.rxkotlin.Singles | |
fun <T> Observables.expand(source: Observable<T>, expander: (T) -> Observable<T>): Observable<T> { |
View combinations.kt
fun <T> Collection<T>.combinations(n: Int): List<List<T>> { | |
return when { | |
n < 0 -> throw Error("combinations size cannot be negative") | |
n > size -> emptyList() | |
n == 1 -> map { mutableListOf(it) } | |
else -> foldIndexed<T, List<List<T>>>(mutableListOf()) { index, all, first -> | |
all + drop(index + 1) | |
.combinations(n - 1) | |
.map { it + first } | |
} |
View lazyFast.kt
fun <T> lazyFast(operation: () -> T): Lazy<T> = lazy(LazyThreadSafetyMode.NONE) { | |
operation() | |
} |
NewerOlder