Share
Embed
Android KTX - Tips to strip your Kotlin codebase!
#KotlinEverywhere session at #GDGAhmedabad
Google Slide link:
bit.ly/2OzWOf7
pRaNaY
November 30, 2019
Transcript
53 slides
-
Android KTX Tips to strip your Kotlin codebase! Organized by
Ahmedabad Pranay Patel Android @ Simform Solutions #KotlinEverywhere -
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 -
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 -
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! -
• It’s a collection of Kotlin extension functions that will
beautify and give a Kotlin-ish touch to existing Android APIs -
• Specifically design for Android apis • Kotlin language feature
• Writing a dot after any object! • Avoid code duplication. -
repositories { google() } dependencies { // Core KTX implementation
'androidx.core:core-ktx:1.1.1' } -
• 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! -
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) } } -
Layout Binding using KTX // Activity class MainActivity : AppCompatActivity(R.layout.activity_main)
// Fragment class MainFragment : Fragment(R.layout.my_fragment_layout) -
val newFragment = ExampleFragment() val transaction = supportFragmentManager.beginTransaction() transaction.replace(R.id.fragment_container, newFragment)
transaction.addToBackStack(null) transaction.commitAllowingStateLoss() Fragment Transaction -
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 -
// androidx.fragment:fragment-ktx FragmentManager.transaction(now: Boolean = false, allowStateLoss: Boolean = false,
body: FragmentTransaction.() -> Unit) Fragment Transaction KTX Code -
db.transaction { // insert, update, delete } db.beginTransaction() try {
... db.setTransactionSuccessful() } finally { db.endTransaction() } Database Transaction using KTX -
Html parsing using KTX HtmlCompat.fromHtml("<b>HTML</b>", HtmlCompat.FROM_HTML_MODE_LEGACY) HtmlCompat.toHtml(SpannableString.valueOf("TEST VALUE"), HtmlCompat.TO_HTML_PARAGRAPH_LINES_CONSECUTIVE) "<b>HTML</b>".parseAsHtml()
SpannableString.valueOf("TEST VALUE").toHtml() // androidx.core:core-ktx -
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 -
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 -
// androidx.core:core-ktx val drawableUser = ContextCompat.getDrawable(this, R.drawable.ic_launcher_background)?:return val bitmap =
drawableUser.toBitmap() Get Bitmap using KTX -
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! Get Spannable string -
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 -
// 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 -
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 -
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 -
val arrayFirst = arraySetOf(1,2,3) val arrayTwo = arraySetOf(4,5,6) arrayFirst.addAll(arrayTwo) arrayFirst.add(7)
arrayFirst.add(8) arrayFirst.add(9) Collection concatenation -
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 -
// 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 -
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 -
class ProfileViewModel : ViewModel() { fun fetchData() { viewModelScope.launch {
getUserDataFromAPI() } } private suspend fun getUserDataFromAPI(){ // call api } } View Model using KTX -
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 -
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 -
1. Try to figure out a solution to a problem
How to start? -
1. Try to figure out a solution to a problem
2. Try to write extension with Kotlin features How to start? -
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 -
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 -
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 -
Pranay Patel Android @ Simform Solutions @pranaypatel_ Thank you! Simform
Solutions http://gdgahmedabad.com/ https://www.simform.com -
References... 1. https://developer.android.com/kotlin/ktx/extensions-list 2. https://www.youtube.com/watch?v=LP3PaPrIFHo 3. https://www.youtube.com/watch?v=r_19VZ0xRO8 4. Slides Code
Highlighter: https://romannurik.github.io/SlidesCodeHighlighter/ -
Photo by The Phope on Unsplash Android KTX Tips to
strip your Kotlin codebase!