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

Android KTX - Tips to strip your Kotlin codebase!

pRaNaY
November 30, 2019

Android KTX - Tips to strip your Kotlin codebase!

#KotlinEverywhere session at #GDGAhmedabad
Google Slide link:
bit.ly/2OzWOf7

pRaNaY

November 30, 2019
Tweet

More Decks by pRaNaY

Other Decks in Technology

Transcript

  1. Android KTX Tips to strip your Kotlin codebase! Organized by

    Ahmedabad Pranay Patel Android @ Simform Solutions #KotlinEverywhere
  2. Motivation What heuristic do you use to know that you

    write maintainable code? In other words ... how do you know that the code you write is maintainable? ~ Donn Felker
  3. Motivation For me, its tests and asking myself the simple

    question of: "If I come back to this code in 6 months, will I understand it in 30 seconds or less and will I feel confident to make a change?" ~ Donn Felker
  4. What we are going to learn... 0. What is android-ktx

    1. Why it is useful? 2. Add Android KTX in your project 3. Explore Android KTX apis 4. Try to build your own KTX 5. “SAMAPAN” - wrap up!
  5. • It’s a collection of Kotlin extension functions that will

    beautify and give a Kotlin-ish touch to existing Android APIs
  6. • Specifically design for Android apis • Kotlin language feature

    • Writing a dot after any object! • Avoid code duplication.
  7. • androidx.fragment:fragment-ktx:$version • androidx.palette:palette-ktx:$version • androidx.sqlite:sqlite-ktx:$version • androidx.collection:collection-ktx:$version • androidx.lifecycle:lifecycle-viewmodel-ktx:$version

    • androidx.lifecycle:lifecycle-reactivestreams-ktx:$version • androidx.navigation:navigation-runtime-ktx:$version • androidx.navigation:navigation-fragment-ktx:$version • androidx.navigation:navigation-ui-ktx:$version • androidx.work:work-runtime-ktx:$version • com.google.android.play:core-ktx:$version Pick the one that you want!
  8. Layout Binding // Activity class MainActivity : AppCompatActivity() { override

    fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } } // Fragment class MainFragment:Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return layoutInflater.inflate(R.layout.my_fragment_layout, container, false) } }
  9. Layout Binding using KTX // Activity class MainActivity : AppCompatActivity(R.layout.activity_main)

    // Fragment class MainFragment : Fragment(R.layout.my_fragment_layout)
  10. val newFragment = ExampleFragment() supportFragmentManager.transaction(now = false, allowStateLoss = true)

    { replace(R.id.fragment_container, newFragment, ExampleFragment.TAG) } val newFragment = ExampleFragment() val transaction = supportFragmentManager.beginTransaction() transaction.replace(R.id.fragment_container, newFragment) transaction.addToBackStack(null) transaction.commitAllowingStateLoss() Fragment Transaction using KTX
  11. db.transaction { // insert, update, delete } db.beginTransaction() try {

    ... db.setTransactionSuccessful() } finally { db.endTransaction() } Database Transaction using KTX
  12. inline fun String.parseAsHtml( flags: Int = FROM_HTML_MODE_LEGACY, imageGetter: ImageGetter? =

    null, tagHandler: TagHandler? = null ): Spanned = HtmlCompat.fromHtml(this, flags, imageGetter, tagHandler) inline fun Spanned.toHtml( option: Int = TO_HTML_PARAGRAPH_LINES_CONSECUTIVE ): String = HtmlCompat.toHtml(this, option) Html parsing KTX code
  13. fun getBitmapFromDrawable(context: Context, userDrawable: Drawable): Bitmap { val bitmap =

    Bitmap.createBitmap( userDrawable.intrinsicWidth, userDrawable.intrinsicHeight, Bitmap.Config.ARGB_8888 ) val canvas = Canvas(bitmap) userDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()) userDrawable.draw(canvas) return bitmap } Get Bitmap from Drawable
  14. val spanValue = SpannableString("Hello Ahmedabad!") spanValue.setSpan( ForegroundColorSpan(Color.RED),6,16, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) spanValue.setSpan(StyleSpan(BOLD),6,16, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

    Hello Ahmedabad! Hello Ahmedabad! val spanValue = "Hello Ahmedabad!".toSpannable() spanValue[6..16] = StyleSpan(BOLD) spanValue[6..16] = ForegroundColorSpan(Color.RED) Get Spannable string using KTX
  15. // val spanValue = SpannableString("Hello Ahmedabad!") // spanValue[6..16] inline operator

    fun Spannable.set(range: IntRange, span: Any) { setSpan(span, range.start, range.endInclusive, SPAN_INCLUSIVE_EXCLUSIVE) } Spannable KTX code
  16. val bundle = Bundle() bundle.putInt("KEY_INT", 21) bundle.putString("KEY_NAME", "PRANAY") bundle.putIntArray("KEY_INT_ARRAY", intArrayOf(8,

    87)) bundle.putBoolean("KEY_BOOLEAN", false) bundle.putStringArrayList("KEY_STRING_ARRAY", arrayListOf("test1", "test2")) Create Bundle
  17. val bundle = Bundle() bundle.putInt("KEY_INT", 21) bundle.putString("KEY_NAME", "PRANAY") bundle.putIntArray("KEY_INT_ARRAY", intArrayOf(8,

    87)) bundle.putBoolean("KEY_BOOLEAN", false) bundle.putStringArrayList("KEY_STRING_ARRAY", arrayListOf("test1", "test2")) bundleOf("KEY_INT" to 21, "KEY_NAME" to "PRANAY", "KEY_INT_ARRAY" to intArrayOf(8, 87), "KEY_BOOLEAN" to false, "KEY_STRING_ARRAY" to arrayListOf("test1", "test2") ) Create Bundle using KTX
  18. val arrayFirst = arraySetOf(1,2,3) val arrayTwo = arraySetOf(4,5,6) arrayFirst.addAll(arrayTwo) arrayFirst.add(7)

    arrayFirst.add(8) arrayFirst.add(9) val arrayTwo = arraySetOf(1, 2, 3) val arrayFirst = arraySetOf(4, 5, 6) + arrayTwo arrayFirst + 7 + 8 + 9 Collection concatenation using KTX
  19. // androidx.collection:collection-ktx public operator fun <T> Set<T>.plus(elements: Iterable<T>): Set<T> {

    val result = LinkedHashSet<T>(mapCapacity( elements.collectionSizeOrNull()?.let { this.size + it } ?: this.size * 2)) result.addAll(this) result.addAll(elements) return result } Plus operator KTX code
  20. class ProfileViewModel : ViewModel() { private val viewModelJob = SupervisorJob()

    private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob) override fun onCleared() { super.onCleared() viewModelJob.cancel() } fun fetchData() { uiScope.launch { getUserDataFromAPI() } } private suspend fun getUserDataFromAPI() = withContext(Dispatchers.Default) { // call api } } View Model Use case
  21. class ProfileViewModel : ViewModel() { fun fetchData() { viewModelScope.launch {

    getUserDataFromAPI() } } private suspend fun getUserDataFromAPI(){ // call api } } View Model using KTX
  22. public fun CoroutineScope.launch( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart =

    CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> Unit ): Job { val newContext = newCoroutineContext(context) val coroutine = if (start.isLazy) LazyStandaloneCoroutine(newContext, block) else StandaloneCoroutine(newContext, active = true) coroutine.start(start, coroutine, block) return coroutine } View Model launch KTX code
  23. val uriString = "https://kotlinlang.org/foo?bar#bla" val uri = uriString.toUri() // Uri

    object from String val fileFromUri = uri.toFile() // File object from Uri object val uriFromFile = fileFromUri.toUri() // Uri object from File object Uri using KTX
  24. 1. Try to figure out a solution to a problem

    2. Try to write extension with Kotlin features How to start?
  25. How to start? 1. Try to figure out a solution

    to a problem 2. Try to write extension with Kotlin features 3. Make module for functionsfunctions
  26. How to start? 1. Try to figure out a solution

    to a problem 2. Try to write extension with Kotlin features 3. Make module for functionsfunctions 4. use/publish your module as library
  27. Summary what we have learned... 1. How KTX make Android

    APIs more pleasant and easy to use 2. Add Android KTX in your project 3. Discussed Android KTX apis 4. Make your own KTX
  28. Pranay Patel Android @ Simform Solutions @pranaypatel_ Thank you! Simform

    Solutions http://gdgahmedabad.com/ https://www.simform.com