After reading what extension functions and default values can do for you, you might be wondering what´s next. As we talked in first article about Kotlin, this language makes Android development much simpler and there are still some more things I´d like to talk about.
Custom Views
Kotlin, by default, only uses one constructor per class. This is usually enough, because using optional parameters we can create as many variations of the constructor as we may need. Here it is an example:
[kotlin]
class MyClass(param: Int, optParam1: String = "", optParam2: Int = 1)
{
init {
// Initialization code
}
}
[/kotlin]
With a unique constructor, we now have four ways to create this class:
[kotlin]
val myClass1 = MyClass(1)
val myClass2 = MyClass(1, "hello")
val myClass3 = MyClass(param = 1, optParam2 = 4)
val myClass4 = MyClass(1, "hello", 4)
[/kotlin]
As you see, we get a whole bunch of combinations just by using optional parameters. But this leads to a problem if we are trying to create an Android custom view by extending one of the regular views. Custom views need to override more than one constructor to work properly. Luckily, we have a way to declare more constructors in way similar to what we do in Java. This is an example of an ImageView which preservers a squared ratio:
[kotlin]
class SquareImageView : ImageView {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val width = getMeasuredWidth()
setMeasuredDimension(width, width)
}
}
[/kotlin]
Quite simple. It could probably be less verbose, but at least we have a way to do it.
Kotlin Android Extensions
If you didn’t know about Kotlin Android Extensions, you’re gonna love them. They will help us Android developers to access to the views declared in an XML in a much easier way. Some of you will remember Butterknife when you see it, but it´s even simpler to use.
Kotlin Android Extensions is basically a view binder that will let you use your XML views in your code by just using their id. It will automatically create properties for them without using any external annotation or findViewById methods.
To start using it, you´ll need to include the new plugin into the build.gradle:
[groovy]
apply plugin: ‘com.android.application’
apply plugin: ‘kotlin-android’
apply plugin: ‘kotlin-android-extensions
…
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
}
}
[/groovy]
Imagine you have declared the next layout, called activity_main.xml:
[xml]
<FrameLayout
xmlns:android="…"
android:id="@+id/frameLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/welcomeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>
[/xml]
If you want to use these views in your activity, the only thing you need to do is importing the synthetic properties for that xml:
[kotlin]
import kotlinx.android.synthetic.main.<xml_name>.*
[/kotlin]
In our case, it will be just activity_main:
[kotlin]
import kotlinx.android.synthetic.main.activity_main.*
[/kotlin]
Now you can access your views by using its id:
[kotlin]
override fun onCreate(savedInstanceState: Bundle?) {
super<BaseActivity>.onCreate(savedInstanceState)
setContentView(R.id.main)
frameLayout.setVisibility(View.VISIBLE)
welcomeText.setText("I´m a welcome text!!")
}
[/kotlin]
Conclusion
What it´s really promising about these two features is that it´s clear that the Kotlin team is very interested in making Android developers lives easier. They also released a library called Anko, a DSL to create Android layouts from Kotlin files. I´m not using its main functionality yet, but you can use it to simplify your code when dealing with Android views, and I have some examples of this in the Kotlin project I pushed to Github. You can take a look to see this and many other things.
Next article will cover the use of lambda expressions and how they can help us simplify our code and extend the language. Really interesting one! To me, the most powerful aspect of Kotlin when compared with Java 1.7.
Is there a way that you know of to use the Android Extensions view injections from outside an Activity? I was trying to use it inside a ViewHolder, instead of a View.findById(), to no luck 🙁
I couldn’t either, not sure if there’s a way yet.
Also, it seems support.v4 fragments aren’t supported either yet.
Android Extensions library supports extension properties for View as well as for Activity and Fragment classes. Just import everything in the `kotlinx.android.synthetic..view package and that’s it.
Thanks! I had actually read that in the official docs but I hadn’t understood it properly. For the record, a for-dummies explanation of what you need to do is:
1) Import kotlinx.android.synthetic..view.*
2) Get a base view reference (i.e., view you’d otherwise call .findViewById() on)
3) Reference your view like baseView.yourViewId
hi
i am getting this error
Error:(11, 8) Unresolved reference: kotlinx
and i can not find any solition
can u help
I also have this Problem and i am not able to fix that. I guess it has something to do with mixed up versions of several libs etc. I am using Android Studio 1.2.2 IntelliJ Kotlin Plugin 0.12.1218.Idea141.3 IntelliJ Kotlin Extensions For Android Plugin 0.12.613.Idea141.7 (<- wrong version?) added classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:0.12.1218' and classpath 'org.jetbrains.kotlin:kotlin-android-extensions:0.12.1218' to the main gradle and apply plugin: 'kotlin-android' and compile 'org.jetbrains.kotlin:kotlin-stdlib:0.12.1218' to the app gradle
Me again. I managed to get it running by rearranging the gradle files like this http://pastebin.com/vxDJ0JCB i hope this is helping others with the same problem
Thanks dustin, that solve the issue
Thanks
Good articles , but if u add screenshot it will very good ……..
This is just code, not talking about any visual specifics here. What kind of screenshots would you find useful?
So where is the ‘next article’ ?
You have many more articles here: http://antonioleiva.com/kotlin/
Hi
I have a custom view in my layout but when I try to import it with synthetic and use it it says:
Overload resolution ambiguity. All this functions match.
– View
– CustomView
It have both imports for View and for CustomView class, how can I import the custom view and avoid this warning?
when i define a custom view.I also encount this problem.
how can i bind the view with the id.
How to add a view to an existing layout?
I do following
“`
setContentView(R.layout.activity_dashboard)
val photo = ImageView(this)
“`
Is this right and sufficient?
With that you are creating a new image, not recovering the one in the layout. Not sure if that’s what you need.