Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android-KTX

 Android-KTX

Small things to make our life easier

E9796ff236c8c73b52480977dc0571ce?s=128

Rostyslav Lesovyi

August 27, 2019
Tweet

More Decks by Rostyslav Lesovyi

Other Decks in Programming

Transcript

  1. + Android-KTX Small things to make our life easier

  2. + Rostyslav Lesovyi

  3. + Android-KTX ➙ Core KTX ➙ Activity KTX ➙ Fragment

    KTX ➙ ViewModel KTX ➙ Reactive Streams KTX
  4. + What and why? sharedPreferences.edit() .putString("key", "value") .apply() sharedPreferences.edit {

    putString("key", "value") } handler.postDelayed({ // do something }, 100) handler.postDelayed(100) { // do something }
  5. + Android-KTX Libraries Core KTX androidx.core.graphics androidx.core.view androidx.core.text …8 more...

    Fragment KTX Palette KTX SQLite KTX Collection KTX ViewModel KTX Reactive Streams KTX Navigation KTX WorkManager KTX
  6. + Core KTX androidx.core:core-ktx

  7. + Core KTX - androidx.core.animation animator.addListener(object : AnimatorListenerAdapter() { override

    fun onAnimationEnd(animation: Animator) { // finished } }) animator.doOnStart { // finished } animator.doOnCancel { // cancelled } animator.doOnEnd { // ended }
  8. + Core KTX - androidx.core.content val array = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView)

    text = array.getString(R.styleable.MyCustomView_someAttr) array.recycle() context.withStyledAttributes(attrs, R.styleable.MyCustomView) { text = getString(R.styleable.MyCustomView_someAttr) }
  9. + Core KTX - androidx.core.content var wifiManager: WifiManager? // From

    Android 1 :) wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager // From Android 23 (Marshmallow) wifiManager = context.getSystemService(WifiManager::class.java) // KTX wifiManager = context.getSystemService()
  10. + Core KTX - androidx.core.util val placeholder = createBitmap(1, 1)

    lruCache<String, Bitmap>( maxSize = 10, sizeOf = { key, value -> key.length + value.byteCount }, create = { placeholder }, onEntryRemoved = { _, _, bitmap, _ -> bitmap.recycle() })
  11. + Core KTX - androidx.core.util val array = SparseArray<String>() val

    value = array[42] array[42] = "abc" 42 in array array.containsKey(42) array.containsValue("abc") array.getOrElse(42) { "abc" } array.forEach { key, value -> ... }
  12. + Core KTX - androidx.core.graphics val color = Color.CYAN val

    a = (color shr 24) and 0xff val r = (color shr 16) and 0xff val g = (color shr 8) and 0xff val b = color and 0xff val color = Color.CYAN val a = color.alpha val r = color.red val g = color.green val b = color.blue
  13. + Core KTX - androidx.core.graphics canvas.save() canvas.translate(10f, 10f) canvas.drawRect(0f, 0f,

    20f, 20f, paint) canvas.restore() canvas.withTranslation(x = 10f, y = 10f) { drawRect(0f, 0f, 20f, 20f, paint) }
  14. + Core KTX - androidx.core.graphics.drawable val bounds = drawable.bounds drawable.setBounds(10,

    bounds.top, bounds.right, bounds.bottom) drawable.updateBounds(left = 10) val bitmap = drawable.toBitmap()
  15. + Core KTX - androidx.core.os TraceCompat.beginSection("my_trace_tag") // some stuff to

    benchmark TraceCompat.endSection() trace("my_trace_tag") { // some stuff to benchmark }
  16. + Core KTX - androidx.core.os val bundle = Bundle() bundle.putInt("key1",

    42) bundle.putString("key2", "my string") val bundle = bundleOf( "key1" to 42, "key2" to "my string") Performance warning
  17. + Core KTX - androidx.core.os (bundleOf) fun bundleOf(vararg pairs: Pair<String,

    Any?>) = Bundle(pairs.size).apply { for ((key, value) in pairs) { when (value) { null -> putString(key, null) // Any nullable type will suffice. // Scalars is Boolean -> putBoolean(key, value) is Byte -> putByte(key, value) is Char -> putChar(key, value) is Double -> putDouble(key, value) is Float -> putFloat(key, value) ...
  18. + Core KTX - androidx.core.os handler.postDelayed({ // do something },

    delay) handler.postDelayed(delay) { // do something } handler.postAtTime({ // do something }, time) handler.postAtTime(time) { // do something }
  19. + Core KTX - androidx.core.text val string = " abc

    " val len = string.trim().length val len = string.trimmedLength() Bad Good
  20. + Core KTX - androidx.core.text Color Italic Bold Red fox

    jumped over the lazy dog
  21. + Core KTX - androidx.core.text val sb = SpannableString("Red fox

    jumped over the lazy dog") sb.setSpan(ForegroundColorSpan(Color.RED), 0, 3, 0) sb.setSpan(StyleSpan(Typeface.ITALIC), 8, 14, 0) sb.setSpan(StyleSpan(Typeface.BOLD), 24, 28, 0) Red fox jumped over the lazy dog Bad
  22. + Core KTX - androidx.core.text fun SpannableStringBuilder.append(text: CharSequence, span: Any)

    = apply { val len1 = length append(text) val len2 = length setSpan(span, len1, len2, 0) } Red fox jumped over the lazy dog Better
  23. + Core KTX - androidx.core.text val sb = SpannableStringBuilder() .append("Red",

    ForegroundColorSpan(Color.RED)) .append(" fox ") .append("jumped", StyleSpan(Typeface.ITALIC)) .append(" over the ") .append("lazy", StyleSpan(Typeface.BOLD)) .append(" dog") Red fox jumped over the lazy dog Better
  24. + Core KTX - androidx.core.text buildSpannedString { color(Color.RED) { append("Red")

    } append(" fox ") italic { append("jumped") } append(" over the ") bold { append("lazy") } append("dog") } Red fox jumped over the lazy dog Good
  25. + Core KTX - androidx.core.widget textView.doAfterTextChanged { text -> //

    do something } textView.doBeforeTextChanged { text, start, count, after -> // do something } textView.doOnTextChanged { text, start, count, after -> // do something }
  26. + Core KTX - androidx.core.view view.isGone = true view.isVisible =

    false view.isInvisible = true val start = view.marginStart val bottom = view.marginBottom view.updatePadding(left = 42) view.updatePaddingRelative(start = 42) view.postDelayed(100) { /* do something */ } val bitmap = view.drawToBitmap()
  27. + Core KTX - androidx.core.view val params = view.layoutParams as

    LinearLayout.LayoutParams params.weight = .42f view.layoutParams = params view.updateLayoutParams<LinearLayout.LayoutParams> { weight = .42f }
  28. + Core KTX - androidx.core.view // instant or delayed view.doOnLayout

    { } // delayed view.doOnNextLayout { } // delayed, avoids memory leaks view.doOnPreDraw { }
  29. + Android - ViewTreeObserver risks View viewTreeObserver viewTreeObserver.addOnPreDrawListener(callback1) Detached

  30. + Android - ViewTreeObserver risks View viewTreeObserver > callback1 Detached

  31. + Window viewTreeObserver Android - ViewTreeObserver risks Detached Detached Attached

    View viewTreeObserver > callback1 Move callbacks
  32. + Window viewTreeObserver > callback1 Android - ViewTreeObserver risks View

    viewTreeObserver View viewTreeObserver onAttachedToWindow onDetachedFromWindow Detached Detached Attached View viewTreeObserver
  33. + Android - ViewTreeObserver risks View viewTreeObserver Detached viewTreeObserver.removeOnPreDrawListener(callback1)

  34. + Activity KTX androidx.activity:activity-ktx

  35. + Activity KTX activity.onBackPressedDispatcher.addCallback(lifecycleOwner) { // do something on back

    press isEnabled = false } class MyActivity : AppCompatActivity() { private val viewModel1 by viewModels<MyViewModel>() }
  36. + Fragment KTX androidx.fragment:fragment-ktx

  37. + Fragment KTX fragmentManager.commit(allowStateLoss = true) { add(MyFragment(), "my_tag") }

    class MyFragment : Fragment() { private val viewModel1 by viewModels<MyViewModel>() private val viewModel2 by activityViewModels<MyViewModel>() }
  38. + ViewModel KTX androidx.lifecycle:lifecycle-viewmodel-ktx

  39. + ViewModel KTX class MyViewModel : ViewModel(), CoroutineScope { private

    val job = SupervisorJob() override val coroutineContext = job + Dispatchers.Main override fun onCleared() { super.onCleared() job.cancel() } fun doWork() = launch { // main thread coroutine } }
  40. + ViewModel KTX class MyViewModel : ViewModel() { fun doWork()

    = viewModelScope.launch { // main thread coroutine } }
  41. + Reactive Streams KTX androidx.lifecycle:lifecycle-reactivestreams-ktx

  42. + Reactive Streams KTX val source: Publisher<String> = ... val

    liveData: LiveData<String> = source.toLiveData() val publisher: Publisher<String> = liveData.toPublisher(lifecycleOwner)
  43. + More info: https://developer.android.com/kotlin/ktx

  44. + Q&A