Skip to content

Instantly share code, notes, and snippets.

View kakajika's full-sized avatar
🏠
STAY HOME

Keita Kajiwara kakajika

🏠
STAY HOME
View GitHub Profile
@kakajika
kakajika / ConcatObjectAdapter.kt
Created September 13, 2021 09:24
Concat multiple androidx.leanback.widget.ObjectAdapter like androidx.recyclerview.widget.ConcatAdapter
class ConcatObjectAdapter(
private vararg val adapters: ObjectAdapter
) : ObjectAdapter() {
init {
adapters.forEach { adapter ->
adapter.registerObserver(object : DataObserver() {
override fun onChanged() {
super.onChanged()
[email protected]()
}
@kakajika
kakajika / LineHeightSpanCompat.kt
Created April 30, 2021 03:45
LineHeightSpan.Standard for lower API versions
import android.os.Build
import android.text.style.LineHeightSpan
import androidx.annotation.Px
import kotlin.math.roundToInt
object LineHeightSpanCompat {
fun standard(@Px lineHeight: Int): LineHeightSpan =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
LineHeightSpan.Standard(lineHeight)
} else {
@kakajika
kakajika / ReselectAwareNavigationView.kt
Created March 9, 2020 09:38
NavigationView with OnNavigationItemReselectedListener like BottomNavigationView.
class ReselectAwareNavigationView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : NavigationView(context, attrs, defStyleAttr) {
interface OnNavigationItemReselectedListener {
fun onNavigationItemReselected(item: MenuItem)
}
private var selectedListener: OnNavigationItemSelectedListener? = null
@kakajika
kakajika / AnimatedVectorDrawableMarkerIcon.kt
Last active March 9, 2020 09:07
Workaround to use AnimatedVectorDrawable as marker icon on Google Maps SDK.
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
@kakajika
kakajika / OneShotGlobalLayoutListener.kt
Last active January 30, 2020 08:36
Listener for View's global layout event only once like [OneShotPreDrawListener](https://developer.android.com/reference/androidx/core/view/OneShotPreDrawListener).
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)
}
@kakajika
kakajika / Pixel.kt
Last active April 25, 2020 05:16
Number extensions to convert px/dp/sp/pt/mm.
/**
* 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
)
@kakajika
kakajika / _LocaleTimePicker.java
Last active August 1, 2019 23:07
Android TimePicker with custom Locale.
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"));
}
@kakajika
kakajika / DimBehindPopupWindow.kt
Created July 10, 2019 22:21
PopupWindow with dim background
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
@kakajika
kakajika / Rx+mapNotNull.kt
Created December 13, 2018 11:10
mapNotNull operators for Rx Observable/Single/Maybe.
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) {
@kakajika
kakajika / expand.kt
Last active September 24, 2018 05:00
A port of RxJS's expand to RxKotlin.
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> {