16 development tips for android in Kotlin. Part 2

Hello. In anticipation of the start of the basic course on Android development, we continue to share useful material.

Before reading these tips, you should read the Kotlin documentation and learn the language yourself on the site. try.kotlinlang.org. Since these tips are aimed specifically at using Kotlin in the context of Android development, you should also have experience with the Android SDK. It is also advisable to familiarize yourself with the Kotlin plugin and the use of Kotlin with Android Studio from JetBrains (creators of Kotlin)


Read the first part

Description of objects

Descriptions of objects allow only singleton which cannot be mistaken for a class with the ability to create instances. Therefore, you do not need to store singlets as variables of a static class or in the Application class.

For example, if I have a utility class with static methods associated with threads, and I want to access the entire application, you can do this:

package com.myapps.example.util
import android.os.Handler
import android.os.Looper
// remember this is an object, not a class
object ThreadUtil {
    fun onMainThread (runnable: Runnable) {
        val mainHandler = Handler (Looper.getMainLooper ())
        mainHandler.post (runnable)
    }
}

Threadutil can be called later in the same way as when calling a method of a static class:

ThreadUtil.onMainThread (runnable)

This means that you no longer need to simulate the behavior of a static class using a private constructor and you do not need to figure out where the instance is stored. Objects, in fact, are the original elements of the language. By the same principle, we create objects instead of inner classes:

v

iewPager.addOnPageChangeListener (object: ViewPager.OnPageChangeListener {
    override fun onPageScrollStateChanged (state: Int) {}
    override fun onPageScrolled (position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
    override fun onPageSelected (position: Int) {
        bindUser (position)
    }
});

Both essentially do the same thing – they create one instance of the class as an declared object.

Supporting Objects

At first glance, Kotlin has no static variables and methods. There are no such concepts in this language, but there is a concept of auxiliary objects. They are singleton objects in a class that contain methods and variables that you can access in a static way. A companion object allows for certain constants and methods, similar to static classes in Java. With it, you can follow the pattern of fragments. newInstance.

Take a look at the companion object in its simplest form:

class User {
    companion object {
        const val DEFAULT_USER_AGE = 30
    }
}
// you can access it later like this:
user.age = User.DEFAULT_USER_AGE

On Android, we usually use static methods and variables to create static factories for fragments. For example:

class ViewUserActivity: AppCompatActivity () {
    companion object {
const val KEY_USER = "user"
        fun intent (context: Context, user: User): Intent {
            val intent = Intent (context, ViewUserActivity :: class.java)
            intent.putExtra (KEY_USER, user)
            return intent
        }
    }
    override fun onCreate (savedInstanceState: Bundle?) {
        super.onCreate (savedInstanceState)
        setContentView (R.layout.activity_cooking)
        val user = intent.getParcelableExtra(KEY_USER)
        // ...
    }
}

Creature Intent similar to a similar action in Java:

val intent = ViewUserActivity.intent (context, user)
startActivity (intent)

This pattern is good because it reduces the likelihood that Intent or Fragment There will be no data necessary for displaying user or any other content. Companion objects are a way to preserve the static access form in Kotlin, and should be used to compensate for the lack of classes.

Global constants

Kotlin allows you to define constants that are visible in one place of the application (if applicable). But the scope of the constants should be minimized as much as possible. And in situations where you want a region to be global, Kotlin has a great way to do this without having to use a constant class. Something like:

package com.myapps.example
import android.support.annotation.StringDef
// This is not a class, this is an object!
const val PRESENTATION_MODE_PRESENTING = "presenting"
const val PRESENTATION_MODE_EDITING = "editing"

Then they can be used as constants anywhere in the project:

import com.savvyapps.example.PRESENTATION_MODE_EDITING
val currentPresentationMode = PRESENTATION_MODE_EDITING

The constants in the project should be as small as possible to reduce its complexity. If you have a value that applies only to a custom class, it is best to put it in a helper object.

Extensions

Extensions are useful because they allow you to add class functionality without inheriting it. For example, how to add some method to Activity, like hideKeyboard ()? Using extensions, you can easily do this:

fun Activity.hideKeyboard (): Boolean {
    val view = currentFocus
    view? .let {
        val inputMethodManager = getSystemService (Context.INPUT_METHOD_SERVICE) as InputMethodManager
        return inputMethodManager.hideSoftInputFromWindow (view.windowToken,
                InputMethodManager.HIDE_NOT_ALWAYS)
    }
    return false
}

Extensions are useful in that they:

  • Help improve code readability
  • eliminate the need to create utility classes and methods.

You can go further and improve the architecture of the code. Imagine you have a basic model, for example, Article, which is considered as a class of data extracted from a source by API:

class Article (val title: String, val numberOfViews: Int, val topic: String)

It is necessary to determine the relevance of Article for the user based on some formula. Should you put it directly in the Article class? And if the model should contain only data from the API, nothing more, extensions can be used again:

fun Article.isArticleRelevant (user: User): Boolean {
    return user.favoriteTopics.contains (topic)
}

This is currently an easy way to check for the presence of an Article topic in a list of user favorite topics.

This logic may vary depending on where you want to test these and other attributes of user behavior. Since this logic is supported to some extent regardless of the model Article, you can change it depending on the purpose, method and its ability to be changed.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *