Skip to content

Instantly share code, notes, and snippets.

View alexmaryin's full-sized avatar
🐕
Fuck the war

Alex Maryin alexmaryin

🐕
Fuck the war
View GitHub Profile
@alexmaryin
alexmaryin / login_validation.kt
Created March 1, 2021 10:13
Minimal example with validation form
import androidx.compose.desktop.Window
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Done
import androidx.compose.material.icons.filled.Warning
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
@HiltViewModel
class SpaceXViewModel @Inject constructor(
repository: SpacexDataRepository,
private val settings: Settings,
private val translator: TranslatorApi
) : ViewModel() {
private suspend fun translateLastUpdate(items: List<HasLastUpdate>) {
if (settings.translateToRu)
translator.translate(viewModelScope.coroutineContext, items, HasLastUpdate::lastUpdate, HasLastUpdate::lastUpdateRu)
// in Fragment/Activity, literally, ui layer
binding.recyclerView.addItemShaker(position)
// in animations utils package with extensions
fun RecyclerView.addItemShaker(position: Int) {
val shaker = object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
@alexmaryin
alexmaryin / medium1_backpressed.kt
Created June 3, 2021 06:53
medium1_backpressed
private var backPressedTime: Long = 0
private val backPressHandler = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (mainViewModel.currentScreen is MainScreen) {
if (backPressedTime + 2000 > System.currentTimeMillis()) {
activity?.finishAndRemoveTask()
} else {
Toast.makeText(requireContext(), "Press again to exit", Toast.LENGTH_SHORT).show()
backPressedTime = System.currentTimeMillis()
}
@alexmaryin
alexmaryin / medium1_add-callback.kt
Created June 3, 2021 07:06
medium1 adding callback to dispatcher
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
// ...
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, backPressHandler)
// ...
}
@alexmaryin
alexmaryin / events_on_ashley.kt
Last active June 18, 2021 08:26
Implementing events system in Libgdx/Ashley
// Game Events
sealed class GameEvent
class GameOver(val score: Int) : GameEvent()
class CopCatchEnemy(val cop: Entity, val enemy: Entity) : GameEvent()
class PlayerRestoresCop(val cop: Entity) : GameEvent()
object EnemyMissed : GameEvent()
object EnemyCaught : GameEvent()
object CopMissed : GameEvent()
// On ViewModel we need to return position to scroll. Good practice is delegate it to responsible class:
fun getScrollPosition(items: List<Any>) = currentScreen.getPositionToScroll(items)
// On Fragment we need to observe event of scroll triggering:
viewModel.getScrollTrigger().collectOnFragment(this) { state ->
when (state) {
false -> {} // Other actions if scrolling is not available, i.e. show a SnackBar
true -> {
viewModel.getScrollPosition(referenceList)?.let { (position, snackText) ->
binding.recyclerView.addItemShaker(position)
// BaseAdapter -> inner class DataViewHolder -> method bind
fun bind(item: Any, clickListener: AdapterClickListenerById) {
holder.bind(binding, item, clickListener)
binding.root.animation = AnimationUtils.loadAnimation(binding.root.context, R.anim.recycler_item_arrive)
}
// Animation file in resources
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
val shakeInterpolator = TimeInterpolator { delta ->
val freq = 6f
val decay = 2f
(sin(freq * delta * Math.PI) * exp((-delta * decay).toDouble())).toFloat()
}
fun RecyclerView.addItemShaker(position: Int) {
val shaker = object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
@alexmaryin
alexmaryin / commonRes.kt
Created October 30, 2021 08:00
Common resources in Kotlin multiplatform project
// 1. In Common-level gradle file set source dir for assets to one folder both for desktop and android modules
sourceSets {
named("commonMain") {
resources.srcDirs("resources")
// ...
}
}
android { //...
sourceSets { //...