Skip to content

Instantly share code, notes, and snippets.

View Jeff-Soares's full-sized avatar

Jeff Jeff-Soares

  • Rio de Janeiro - RJ
View GitHub Profile
@Jeff-Soares
Jeff-Soares / density.ps1
Last active July 28, 2023 23:51
powershell script to change device pixel density and font scale through shortcuts (target: pwsh -command "& 'C:\..\density.ps1' +")
$param = $args[0]
$density_output = adb shell wm density
$matches = ([regex]'\d+').Matches($density_output)
$current_density = [int] $matches[$matches.size - 1].Value
if ($param -eq "-") {
adb shell wm density ($current_density - 50)
} elseif ($param -eq "+") {
adb shell wm density ($current_density + 50)
@Jeff-Soares
Jeff-Soares / EnumSerializer.kt
Last active June 17, 2023 18:15
generic enum kserializer for kotlinx.serialization
abstract class EnumSerializer<T : Enum<T>>(values: Array<out T>, private val defaultValue: T) : KSerializer<T> {
private val lookup = values.associateBy({ it }, { it.serialName })
private val revLookup = values.associateBy { it.serialName.uppercase() }
override val descriptor = PrimitiveSerialDescriptor(values.first()::class.qualifiedName!!, PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: T) = encoder.encodeString(lookup.getValue(value))
override fun deserialize(decoder: Decoder) = revLookup[decoder.decodeString().uppercase()] ?: defaultValue
fun View.expandOrCollapse(expand: Boolean) {
if (expand) expand() else collapse()
}
fun View.expand() {
val matchParentMeasureSpec = View.MeasureSpec.makeMeasureSpec((parent as View).width, View.MeasureSpec.EXACTLY)
val wrapContentMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
measure(matchParentMeasureSpec, wrapContentMeasureSpec)
val targetHeight = measuredHeight
@Jeff-Soares
Jeff-Soares / LiveDataUtils.kt
Created August 11, 2022 17:18
combine operator for livedata
fun <T, K, R> LiveData<T>.combineWith(
liveData: LiveData<K>,
block: (T?, K?) -> R
): LiveData<R> {
val result = MediatorLiveData<R>()
result.addSource(this) {
result.value = block(this.value, liveData.value)
}
result.addSource(liveData) {
result.value = block(this.value, liveData.value)
import kotlin.time.ExperimentalTime
import kotlin.time.measureTimedValue
@OptIn(ExperimentalTime::class)
fun main() {
val time = measureTimedValue {
(1L..50L).map(::fibRec).let(::println)
}
println(time)
}
inline fun Fragment.launchAndRepeatWithViewLifecycle(
minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
crossinline block: suspend CoroutineScope.() -> Unit
) {
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.lifecycle.repeatOnLifecycle(minActiveState) {
block()
}
}
}
@Jeff-Soares
Jeff-Soares / SingleLiveEvent.kt
Created March 4, 2022 00:58
A lifecycle-aware observable that sends only new updates after subscription, used for events like navigation and Snackbar messages.
class SingleLiveEvent<T> : MutableLiveData<T>() {
private val mPending = AtomicBoolean(false)
@MainThread
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
if (hasActiveObservers()) {
Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
}
@Jeff-Soares
Jeff-Soares / BounceEdgeEffectFactory.kt
Last active February 24, 2025 08:03
Recyclerview EdgeEffect SpringAnimation
import android.graphics.Canvas
import android.widget.EdgeEffect
import androidx.dynamicanimation.animation.SpringAnimation
import androidx.dynamicanimation.animation.SpringForce
import androidx.recyclerview.widget.RecyclerView
/** The magnitude of translation distance while the list is over-scrolled. */
private const val OVERSCROLL_TRANSLATION_MAGNITUDE = 0.2f
/** The magnitude of translation distance when the list reaches the edge on fling. */
@ExperimentalCoroutinesApi
class CoroutinesTestRule(
val testDispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()
) : TestWatcher() {
override fun starting(description: Description?) {
super.starting(description)
Dispatchers.setMain(testDispatcher)
}
@Jeff-Soares
Jeff-Soares / CustomAdapter.kt
Created September 18, 2021 21:49
RecyclerView Adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class CustomAdapter : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
private var list: MutableList<String> = mutableListOf()