What's up with Anko?


#1

Good day. It seems like Anko hasn’t been updated for a while. It has lots of pending issues and even pull requests are not processed. I wonder what’s the status of the library?


#2

I myself wanted to add to the library support for constraintLayout, but the lack of activity discourages me from trying.


#3

Are you planning to add DSL for constraintLayout? That sounds cool.


#4

The developer working on Anko has other tasks in addition to Anko, and at this time those other tasks have higher priority. He’ll get back to Anko soon.


#5

Good to hear that. Thanks for reply.


#6

And what is the long-term vision for Anko? Are you at JetBrains convinced this is a good way to do Android development?

I’m asking because I gave it a try on a small UI and saw a number of problems. I generated a new project in IntelliJ based on a tabbed activity template and then did my best to convert it into Anko.

  1. The conversion turned out to be much more difficult than converting every XML tag into a matching function call. There are missing tags and attributes. For example, tabItem function does not accept “text” attribute, and I found no easy way to assign it other than implementing my own tab builder function that does not use tabItem at all. Another example is there are some missing “fooResource” properties to match “foo”, e.g. “Tab.textResource” is missing. Yet another example is the complete lack of support for writing menus in Anko. Finally, I found that Anko doesn’t support the ConstraintLayout.
  2. There is some mess with naming. Anko adds View.topPadding (presumably because Android’s paddingTop is in the same namespace, and it’s a read-only property), but does not add endPadding or startPadding.
  3. There are missing bits of functionality, e.g. support for an equivalent of the “?attr” syntax. I was lucky to find this bit of code to fill that gap: https://github.com/fboldog/AnkoMaterialSamples/blob/master/src/main/java/com/ferencboldog/ankomaterial/extensions/AnkoExtensions.kt
  4. The worst part for me were the side effects of Anko being a DSL on top of Kotlin. Specifically, when you build the GUI by using nested functions, every subsequent nested scope can access higher scopes’ properties. So sometimes you want to set a property of the current scope, and that property isn’t there, but there is a property with the same name higher up in the hierarchy, and you end up setting that one instead! Note that this problem does not exist with Android’s XML layouts, because scoping works differently. Even looking at the declaration of the property often does nothing to tell you it’s in the wrong scope, because it’s all built on extension function magic and difficult to follow. I fell into this trap several times and ended up adding “this.” to every attribute assignment and member function call to make sure I operate in the correct scope.
  5. There is no equivalent of “@+id/foo” syntax. This is compounded by the fact there is no support for ids declared in ids.xml in the DSL.
  6. There are cases of incorrect default behavior. I found experimentally that I had to set “scrollFlags = 0” in tabLayout’s lparams to have it behave the same way as the corresponding XML tag.
  7. Fragment API is still quite cumbersome (of course, it’s extremely cumbersome in Java to begin with).

Note that I ran into all the above problems just trying to convert a stock project generated from template into Anko. But even at this point, I have to say that it crossed my mind that it might be better to use a special DSL not based on a general-purpose programming language to avoid semantics-related problems above (name collision and scoping rules). Furthermore, I believe that in order to support “+@id” attributes and other kinds of metadata processing, as well as allow building of reliable tools (e.g. visual editor), the DSL should be “declarative with optional scripting”, as opposed to “declaratively-looking, but procedural under the hood”. Thoughts?


#7

Anko consists of multiple different components, of which the layouts DSL is just one thing. We’re totally convinced that using Anko as a whole is a very good way to do Android development.

As for the layout DSL, it’s one possible way to build layouts, and we do not claim that it’s the right tool for all UI building usecases. If it works for you, use it. If it doesn’t, there’s nothing wrong with XML.

Item #4 on your list is, as far as I understand, resolved in Kotlin 1.1 which supports the @DslMarker annotation specifically to address this problem.

We see the use of Kotlin in the Anko layout DSLs as its key advantage, because it gives you access to the full range of abstraction tools in the language. We have no plans to develop an alternative external DSL for building Android views.


#8

This is a good point, but I guess you should propose this feature to Google rather than JetBrains

What kind of support do you expect from DSL? You already can use it as easiliy as this:

textView("Text"){
    id = R.id.text_view
}

Provided that you have declared your id in ids.xml (try building your module if ids don’t appear in your generated R class). Or are you talking about synthetic support?

Nevertheless, I see your point, but hey, it’s still under development with version just 0.10.x and just one official maintainer. A lot of android library components are not yet supported in anko, but you can easily add this DSL support according to your own needs (for instance in your case for TabLayout). And if you think that other developers may find your extensions useful - feel free to send pull requests.

For example, this is how I have simplified creating CardView in my API by taking advantage of Kotlin + Anko:

myCard {
	lparams(width = matchParent) { setMargins(dip(24), dip(12), dip(24), dip(12)) }
	id = R.id.my_card_custom
	radius = dip(8).toFloat() // CardView attribute
	
	// Add header
	initHeader {
		// radius = dip(16).toFloat() // This will yield compile error
		
		headerTitle = "PHY 106"
		headerColor = getColor(R.color.green_300)
		headerTitleStyle = R.style.DemoAppTheme_CardTitleAppearance
		
		// Add 3-dot overflow menu
		initMenu(R.menu.my_card_menu) { menuItem ->
			when (menuItem.itemId) {
				R.id.my_card_action_edit -> toast("Edit Click")
				R.id.my_action_remove -> toast("Remove Click")
			}
		}
	}
	
	// Customize rows
	rowEntryStyle = R.style.DemoAppTheme_CardEntryAppearance
	rowValueStyle = R.style.DemoAppTheme_CardValueAppearance
	rowAnimationDuration = 500
	
	// Add rows (dsl methods are under development)
	addRows(MyCardRow("Section", "3"),
			MyCardRow("Classroom", "S-124"),
			MyCardRow("Topics", lipsum, CardRowType.Expandable))
}

The result is:


#9

@yole I think in the last TalkingKotlin episode it was mentioned that Anko is going to be split into the “DSL” part and the “all the other goodies” part, which would allow to advertise them separately. Can you share some details? The progress?


#10

I would second that now that we have contraint layout, a DSL might not be the best solutions.

On top of the limitations mentioned above, Google is working hard on the layout Editor for Android Studio.
Used in conjonction with ConstraintLayout, this allows you to efficiently write layouts and review how the are structured at a glance.

AFAIK, Anko has no similar layout builder integration.

Replacing XML sounds like a very good idea in theory, but in practice it turns out that XML is (surprisingly) a good pick for building layout and has very good tooling.


#11

I actually dislike XML’s verbosity. I much prefer the way Anko looks, just it seems to me it would work better had it been a distinct declarative language with scripting, as opposed to being built on top of Kotlin. Still, my most serious issues have been addressed above, so I would say that Anko will work for me when it becomes more complete (I am trying it out on a pet project right now). I do agree that a layout editor is very desirable (I think there is one bundled with the Anko plugin, but it doesn’t work right now?)


#12

I suppose the optimal way is to use both xml and anko together. XML + ConstraintLayout + Android Studio’s layout builder is good for complex, more or less static layouts. Anko is good for compact dynamic layouts or views.


#13

I don’t think you will find anyone that likes manipulating XML.

However, with Intellij it is ok IMO. the IDE takes care of writing the verbose parts of the format and syntax coloring makes you automatically tune out the noise when reading a layout.

So I begrudgingly have to admit that CL + XML + Layout Editor is the best combinaison right now.


#14

I think it is a great pity that until this day we still have to edit XML by hand. There’s nothing wrong with XML, it’s just the layout editor which is still not reliable.


#15

I’ve committed many, many hours porting UI components and developing new components using Anko/Kotlin. Lots of workarounds were necessary, including using “include” to bring in XML for certain widgets that needed some magic during inflation (for some odd reason). To hear there is a single developer and his other duties pull him away from maintaining Anko leads me to believe I made a huge mistake. This was advertised as the new way to develop and now I see it’s not getting the bare minimum of 1 developer’s time. Is Anko a thought experiment or a product? Maybe you can hire a developer to support this library that has been so highly touted.


#16

I couldn’t agree more. This is amplified by the fact that Anko is being promoted on a weekly basis in Kotlin Weekly newsletter.


#17

There are bugs that have stayed unresolved for a year and a half, e.g. https://github.com/Kotlin/anko/issues/153