📜 ⬆️ ⬇️

Kotlin for Android

Probably, of those who are interested in developing for Android, only the lazy have not heard about Kotlin. On Habré about him already wrote: here is the article , here is the video with MBLTdev . The language is actively developing, but there are still no new articles. I decided it was time to fix it.

If you're wondering what happened lately in this beautiful language, as well as its capabilities that were not previously covered in the Habré, I ask for a cat.

Anko


Undoubtedly, a very important library for any Kotlin user who is still in development (current version 0.6). Consider its capabilities.

Anko dsl

As you know, you can create an interface not only with xml, but also directly in the Java code. However, this hellish pain is not very easy. The Anko library provides another way to create a user interface that has a lot in common with Groovy builders (however, they also exist in Kotlin).
As a simple example, let's rewrite the standard HelloWorld from xml to Anko DSL:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) relativeLayout { padding = dip(16) textView("Hello world!") { } } } 

I can not say that I myself was a little surprised when I wrote these 5 lines while rewriting xml in Anko DSL and I suddenly realized that it was all.
Equivalent xml markup
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin"> <TextView android:text="@string/hello_world" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout> 


Of course, this approach can also be used to create a more complex UI:
 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) relativeLayout { padding = dip(16) val w = dip(200) val loginEditId = 155; val loginEdit = editText { id = loginEditId hint = "Login" }.layoutParams { centerInParent(); width = w } button("Sign up") { textSize = 18f onClick { doWork(loginEdit.getText().toString()) } }.layoutParams { below(loginEditId); sameLeft(loginEditId); width = w; topMargin = dip(8) } } } 

Result:

')
Anko DSL has another interesting feature - an abbreviated interface implementation. For example, the standard TextWatcher interface contains 3 methods, and we need to implement them all, even if we want only one:
 val edit = EditText(this) edit.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { toast(s) } override fun afterTextChanged(s: Editable) { } }) 

With the help of Anko DSL, we can only implement what we need (write as less code as possible):
 val edit = editText { textChangedListener { onTextChanged { text, start, before, count -> toast(text.toString()) } } }.layoutParams { centerInParent() } 


As a small conclusion, I can say that Anko DSL is rather an alternative to xml, but not an unequivocal replacement. A replacement can be to create a UI from Java code. Anko DSL does not give a tangible advantage in speed, so for the sake of performance you should not use it.

In my opinion, using Anko DSL is good because you write the properties and event handlers for the elements in one place (I mean that usually the style / positioning of the elements is usually done using xml, and the event handlers are assigned in Java code) can give a plus to logic. In addition, you can try to use Anko DSL in the trendy MVP pattern.

It is also possible that for someone such builders-style is more enjoyable than xml.
And one more important point - Anko is just developing. Perhaps in the future we will see new cool features from this library. Therefore, it is worth paying attention to it.

Anko features

In addition to DSL, the Anko library allows us to write much less standard code.
Consider some code snippets and how Anko allows you to change them. I will just give examples - comments, in my opinion, are superfluous.

Thus, the Anko library provides a set of useful goodies that will undoubtedly benefit your Kotlin project. So go ahead:
 compile 'org.jetbrains.anko:anko:0.6.1-19s' 

For Android with love


It is impossible not to mention that the Kotlin team tries very well in the name of Android and adds very important features for any Android developer to the language.

Annotation Processing

Just a few days ago, Android developers finally had the opportunity to use various DI frameworks in combination with Kotlin. On this occasion, an article appeared in the Kotlin developers blog that explains some of the details. In addition, you can see an example using the Dagger. So far, this opportunity is still damp and will be refined, but the general direction pleases.
I do not think that I can add something useful to the links above, so this item will just go as news.

Secondary constructors

Initially, Kotlin planned to use only one primary constructor for each class. This is reasoned by the fact that this is always enough. In general, it is almost always true. However, with this limitation, Android developers could not create their own View classes.
Now it is possible:
 public class MyView : LinearLayout { public constructor(context: Context) : super(context) { } public constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { } //... } 

Naturally, the use of secondary constructors is not limited to View classes only.

Delegated properties

In general, delegation was not created specifically for Android, this feature appeared in the M5.3 language version, but since this topic has not yet been covered in Habré, I’ll touch on it.

Delegation in this context means the transfer of field / variable processing to a specific class. This class contains get and set methods for this field. This transfer allows you to implement some concepts, for example:

Kotlin defines a set of standard important delegates that are in the Delegation.kt file in the delegates object. For example, you can use lazy initialization very easily:
 val someBigValue by Delegates.lazy { var result = BigInteger.ONE //some hard computations result } 

When accessing the field someBigValue for the first time, its value will be calculated and saved, the second and next time the stored value will be returned.
Note: do not use this construction to create different singletones, for this Kotlin has object declarations .
Other examples can be found in the documentation .

What is so great delegation for Android? We recall one of the key features of Kotlin - null-safety. Usually we declare UI elements as Activity / Fragment fields, like this:
 private var mHelloWorldTextView : TextView = //??? 

However, in Kotlin, we cannot set a TextView type field to null. Therefore, we write something like this:
 private var mHelloWorldTextView : TextView? = null 

But this leads to terrible constructions with the ubiquitous use of the "?." Operators. and "!!.", which does not add beauty to the code:
 override fun onCreate(savedInstanceState: Bundle?) { //... mHelloWorldTextView = findViewById(R.id.helloWorldTextView) as TextView? mHelloWorldTextView?.setOnClickListener { /*...*/ } val text = mHelloWorldTextView!!.getText() } 

And here a very useful method notNull of the Delegates object hurries to the rescue:
 private var mHelloWorldTextView : TextView by Delegates.notNull() override fun onCreate(savedInstanceState: Bundle?) { //... mHelloWorldTextView = findViewById(R.id.helloWorldTextView) as TextView mHelloWorldTextView.setOnClickListener { /*...*/ } val text = mHelloWorldTextView.getText() } 

When we try to access the mHelloWorldText field before initializing it, we get an IllegalStateException. Very similar to Optional from Java 8.

UPD 1.
In Activity, you can use an alternative:
 private val mHelloWorldTextView : TextView by Delegates.lazy { findViewById(R.id.helloWorldTextView) as TextView } 

Thanks to Sp0tted_0wl

UPD 2.
In general, use Kotlin Android Extensions for View.
Thank you abreslav and kivsiak

Conclusion


This concludes my consideration of the main interesting features of Kotlin for Android development. Thank you for reading to the end.
Learn Kotlin, write to Kotlin, love Kotlin!

PS Join the world's largest community of Android developers in Slack.
PPS Want to chat with other developers interested in Kotlin? Welcome to gitter.

Source: https://habr.com/ru/post/258683/


All Articles