Without property delegationclass UserSettings( private val prefs: SharedPreferences) { var name: String get() = prefs.getString("name", "") ?: "" set(value) { prefs.edit { putString("name", value) } } var age: Int get() = prefs.getInt("age", 0) ?:0 set(value) { prefs.edit { putInt("name", value) } } } Using del..
Use case When we have filter/search functionality in our app, we often want to trigger an operation whenver user enters query in an EditText and we want to reduce network calls by using debouncing. Kotlin Flow supports debouce operation but it's still preview until 1.6. https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/debounce.html debounce debounce com..
import java.time.LocalDate; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Date; /** * This pattern has the following benefits: * * - Date formats are referenced as a strong type * - Code completion on patterns * - Patterns can be javadoc'ed */ public enum Dates { /** * Format: yyyy-MM-dd * Example: 2022-03-30 */ yyyy_MM_dd("yyyy-MM-dd"), /** * Format: MMM d..
리사이클러뷰를 사용할 때 성능향상을 위해 DiffUtil을 이용할 것이다. 그런데, DiffUtil을 사용하면서 주의해야할 중의 하나는 ArrayList나 var 멤버가 포함된 mutable한 데이터 타입을 사용하는 것이다. 결론적으로 말하면, 이런 데이터 타입을 사용할 경우 데이터를 변경했음 해도 불구하고 리사이클러뷰가 업데이트 되지 않게 되는 현상에 직면하게 된다. 관련 코드를 통해 해당 증상을 살펴보자. 아래와 같이 ListAdapter를 이용해 사용자를 추가하는 간단한 앱이 있다. Add를 누르면 사용자를 리사이클러뷰에 추가할 것이다. 레이아웃과 관련코드이다. class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanc..
I have read about Liskov Substitute Principle(LSP, https://en.wikipedia.org/wiki/Liskov_substitution_principle) few times and tried to understand correctly but it's clear sometimes but ambiguous other times. I confess it's not still 100 clear. I might need to revisit when I have a problem. We can easily find long discussions about LSP(https://stackoverflow.com/questions/56860/what-is-an-example-..
It's cleaner and easier to handle not to throw Exception often in Kotlin. Particulary when we call Http call, we are like to use Coroutines. Coroutine has complicating cancellation and exception handling mechanism and it might not work well in caese if you use the same apporach to Java by throwing Exceptoin. Coroutine propagates Cancellation Exception to top most coroutine context and this makes..
Android SDK introduced Result API recently and it looks better than just passing target fragment and get the result in onActivityResult. onActivityResult sounds bit weird when we receive the result from a Fragment. This API works with Fragments and we can use it for DialogFragment as well because DialogFragment is also Fragment. We need to register listener to FragmentManager to observe from a F..
We have use cases when we have to pass String message from ViewModel to View often. In Android, the system support String resources and it would be nice to use String resource instead of hard coded strings whenever possible. You might have had some situations you need to pass String resources from your ViewModel to activity or fragment but you don't want to pass Context to your ViewModel. You mi..
Favor read-time convenience to write-time convenience. Code is read far more times than it's written, even during initial development. Favoring a technique that speeds write-time convenience at the expense of read-time convenience is a false economy. This is especially applicable to creation of class interfaces. Even if a routine doesn't quite fit the interface's abstraction, sometimes it's temp..
Kotlin사용자라면 Sythetic pulgin이 deprecated되고 ViewBinding(구글의 권장사항)으로 마이그레이션 해야된다는 걸 알고 있을 것이다. 그런데 ViewBinding을 프레그먼트에서 사용하게 될 경우 Memory leak과 관련된 이슈가 있는 것도 아마 알 것이다. (구글 문서에 나와있으므로) 아래는 개발자 문서의 샘플코드이다.(https://developer.android.com/topic/libraries/view-binding) private var _binding: ResultProfileBinding? = null // This property is only valid between onCreateView and // onDestroyView. private val b..