Introduction to Anko for Android — Part 3

Vaclav Souhrada
4 min readMar 13, 2017

--

In the first article (part 1) you learned how to create a view as AnkoComponent and how to use it in the Activity class. In this post, we will reimplement our sample Anko application that we will start with Fragments and make our Sign-In view a little bit nicer by using paddings, margins, and so on…

List of all articles in this series about Anko:

In the previous post we added more logic to our demo app. Now it’s time to return back and improve our UI.

As the first, we add padding to our core vertical layout by using an extension function dip(dp) which returns dimension value in pixels

(SignInView.createView):

SingInView.kt Without padding!
// SignInView.createViewverticalLayout {
padding
= dip(20)
...
}
SignInView.kt — With Padding 20dip

DSL above is equal to XML definition:

<LinearLayout
android:padding="20dip"
...
/>

In the SignInView.kt, you can see that both EditTexts has same textSize = 24f.

val username = editText {
...

textSize
= 24f
}

val
password = editText {
...

textSize
= 24f
}

Anko has a useful extension function to apply parameters to view and to all of its children recursively:

verticalLayout {
padding
= dip(20)
...
val username = editText {
id = R.id.usernameEditText
hintResource
= R.string.sign_in_username
}.lparams(width = matchParent, height = wrapContent)

val
password = editText {
id = R.id.passwordEditText
hintResource
= R.string.signIn_password
}.lparams(width = matchParent, height = wrapContent)

button {...}.lparams(width = matchParent, height = wrapContent)
}.applyRecursively { view ->
when
(view) {
is EditText -> view.textSize = 24f
}
}

What we did? We set recursively the textSize = 24f to all EditText’s widgets inside of the verticalLayout (LinerLayout with the vertical orientation).

Pretty simple! Do not you think? In the next steps, we will add scroll view and move our login form to center position of view.

There are a few steps what we must to do if we want to move our layout to the center position. The final UI after these steps should be:

I will not describe now what I changed or added by step-by-step. Just copy a whole code and try to run app:

The most important parts of code above are:

  • Line 25: there is a new parent vertical layout (LinearLayout with a vertical orientation) with Gravity.CENTER
  • Line 28: The ScrollView has been added to allow scrolling for small devices
  • Line 30: inner vertical layout for login/sign in form
  • Line 32: the good old vertical layout is now a nested layout for the login form. We defined here id = R.id.formLogin with gravity = Gravity.CENTER
  • Line 37: lparams(width = dip(300), height = matchParent) by this we have login form with dip(300dp)

Note: You may wonder why we have a definition of lparams at line number 37 because you know that in Anko you specify LayoutParams right after a View description. The reason behind this is that if I want to specify width = dip(300) so it doesn’t work in recommended way for me.

It is working only if I moved it to the inside of layout or if I tried to wrap it by apply {} DSL block like this:

...
verticalLayout {
....
}.apply {
lparams
(width = dip(300), height = matchParent) {
this.gravity = Gravity.CENTER
// API >= 16
doFromSdk
(version = Build.VERSION_CODES.JELLY_BEAN) {
background = ContextCompat.getDrawable(
ctx, android.R.color.white)
}
clipToPadding = false
bottomMargin = dip(16)
}
}

At line 40 can see interesting piece of code:

// API >= 16
doFromSdk(version = Build.VERSION_CODES.JELLY_BEAN) {
background = ContextCompat.getDrawable(
ctx,android.R.color.white)
}

The View#setBackground requiers API ≥ 16. Anko offers to us some functions how we could solve this requirement. Also, it provides configuration qualifiers:

// Code inside for this block code is from original Anko //Documentationconfiguration(screenSize = ScreenSize.LARGE, orientation =                     Orientation.LANDSCAPE) {
/*
This code will be only executed
if the screen is large and its orientation is landscape
*/
}

So in our case, you can alternatively use:

configuration(fromSdk = Build.VERSION_CODES.JELLY_BEAN) {
background = ContextCompat.getDrawable(
ctx, android.R.color.white)
}

For detail description and overview of the configuration, qualifiers see official documentation here.

Summary

In this article (part 3) you learned how to add some additional attributes to views such as padding, gravity, and new layout scroll view. Of course, you learned how you can easily apply some view attributes recursively.

In next article (part 4), you will learn how to work with Fragments.

Thank you for reading and stay tuned…

--

--

Vaclav Souhrada

Android Developer | Kotlin enthusiast | Czech Kotlin User Group organizer (www.kotliners.cz)