Why Anko Layouts DSL is better than XML layouts
source link: https://www.kotlindevelopment.com/why-anko-layouts-dsl-better-xml/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Why Anko Layouts DSL is better than XML layouts
Posted on 11 August 2017 by Peter Tokaji
Introduction
In the previous post, you got to know the Anko Android library and its first module, Commons. This time we will take a closer look at another topic: Anko Layouts DSL.
Basics
In Android development, there are two common ways for building UI. First option is the drag-and-drop UI builder in Android Studio (the design tab), and while it is a great tool for assembling a basic layout, it doesn't work that good for more complicated stuff - the boilerplate code it generates is difficult to maintain.
Second, you can build the layout in an XML file by hand. With this approach you have full control, but on the other hand you need to do everything on your own, nothing comes out of the the box. There is a Preview window next to the XML code where it renders the layout on the fly.
Anko Layouts DSL is very similar to XML but you can stick with pure Kotlin. Don't need to switch between languages, context and place, making layout building a breeze.
DSL Hello world sample
verticalLayout {
val name = editText()
button("Say Hello") {
onClick { toast("Hello, ${name.text}!") }
}
}
Let's see the benefits:
-
Forget
findViewById()
No more need for one of the most used lines of code in the history of Android development. IDs, explicit casting, and all the suffering just to get a reference to a View - all gone.
-
Type and null-safe
Saves time, reduces LOC count. In our example, the
name
variable is anEditText
from the the first moment, and you can be sure it won't throw aNullPointerException
orClassCastException
. -
Saves CPU time and battery
Inflating an XML layout involves the XML Parser, which reads the file and parses its contents. With a complicated layout, or on a low-end phone, this process can take hundreds of milliseconds. This way the Layouts DSL saves both CPU- and battery-resources, a win both for you and the users.
More flexibility
Supports existing code
Because the DSL is here, it doesn't mean you have to get rid of your old XML files. You can use them in your DSL layouts with very little effort.
The magic function looks like this: val name = include(R.id.name)
Custom components
You created a custom EditText
subclass, or you customized a Button
for your application? Good news: they are also supported in DSL layouts.
inline fun ViewManager.yourView() = yourView(theme = 0) {}
inline fun ViewManager.yourView(init: YourView.() -> Unit): YourView {
return ankoView({ YourView(it) }, theme = 0, init)
}
Listeners
A lot of UI elements have listeners for specific events, for example for registering clicks. In the previous post, we demonstrated how simple it is to take care of this with Anko - it takes the same effort with the DSL.
Of course, you can use the onClick
function instead of the nested objected .setOnClickListener(object: OnClickListener{....})
, but there is more.
One of the coolest features is that Anko has built-in subclasses for all default listeners, with all abstract methods overridden by an empty function. Using these you'll only have to implement the bare necessities.
A quick comparison:
seekBar.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
// Something
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
// Just an empty method
}
override fun onStopTrackingTouch(seekBar: SeekBar) {
// Another empty method
}
})
vs
seekBar {
onSeekBarChangeListener {
onProgressChanged { seekBar, progress, fromUser ->
// Something
}
}
}
What do you need to know before jumping in
We talked about the positive and convenient features of the DSL layouts, but there are trade-offs as well.
-
No preview
At least not in the stable channel. There's an Anko Support IntelliJ plugin, which can render DSL layouts, but it's available only in Android Studio 2.4+.
-
No ConstraintLayout
Yes, the "new" layout, introduced at Google I/O 2016 is not supported yet. But there is hope: you can find an issue in their tracker for including the ConstraintLayout, so this might change in the future.
DSL 101
For the sake of simplicity, let's create our first DSL layout in the Activity.onCreate
function. No need for calling setContentView(...)
.
As a good software developer, you know the application logic and the layout needs to be separated, and the DSL has an excellent tool for achieving this. Take a look at the code:
class My Activity : AppCompatActivity() {
override fun onCreate (savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val ui = MyActivityUI()
ui.setContentView(this)
ui.name.hint = "Hint"
}
}
class MyActivityUI : AnkoComponent {
lateinit var name: EditText
override fun createView(ui: AnkoContext) = with(ui) {
verticalLayout {
name = editText()
button ("Say Hello") {
onClick { ctx. toast ("Hello, ${name.text} !") }
}
}
}
}
Layouts reside in their own separate classes, extended from the AnkoComponent
interface, with a function that returns with the layout itself. We'll need to instantiate these in the activities, and call setContentView()
with actual context. As mentioned before, calling findViewById()
is not necessary anymore - in the example, the name: EditText
variable is declared in the UI class, and is accessible from the Activity
whenever you need it.
Final words
The Anko Layouts DSL is a powerful tool, a valid substitute for XML layouts in most cases. It is mature and stable enough for production - we've used it in multiple projects, with great satisfaction. Give it a try, and let me know how it goes!
This post is the second in a series about Anko - the first one covered the Commons module, and the third is about the Anko SQLite.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK