UI frameworks: past and present
We will talk about frameworks in the context of Android and the web, because the problems in the UI that Android developers face are in the web and in other UI areas.
Let’s take a look at HTML. We say that we must have a list, there must be two paragraphs with such and such text. Then a tree is built from this HTML.
HTML is a very declarative thing, it just marks up and doesn’t do anything else. And from this side, you can look at HTML as a function that generates a UI for us without taking any data. It just takes the file and generates the UI.
If I replace the HTML with main_layout.xml, which we all have in our Android app, nothing changes. This is the same markup language converted from HTML for Android. It’s the same UI approach: you call the inflate function and you get the UI tree.
The problem is that we do not live in 1995 and do not write static sites, static applications, where a new page is loaded for each link. We write complex applications that contain a lot of state and animation. This is called a dynamic UI that we apply changes to on the fly.
Let’s take an example. We are making a messenger and want to make a plate with unread messages in it.
When we click on the Read All button, we have 0 unread. To figure it out, consider the tree of our UI (whether it’s Android with things like a TextView, or even HTML elements like a div). And before us is such a person, his name will be Captain Dynamism.
We have 100 unread messages and the user clicks Read All. Captain Dynamism takes the UI, understands what needs to be changed, finds it, removes unnecessary elements, connects the new parent to the child. Well done!
Then a new message arrived. You need to create a UI sub-branch again (hopefully, not in parts, but in one part), you can do this through View.GONE or View.INVISIBLE. And again we get unread messages. The problem is that if an undo button is added or some other new requirement, it becomes difficult to keep track of all the states. And there are not two transitions between them.
Let’s take a look at a real-world example.
val unreadRoot = document.getElementsByClassName (“unreadRoot”);
val count = document.createElement (‘div’);
count.textContent = ‘You have $ count unread messages’; unreadRoot.appendChild (count);
In JavaScript without frameworks, people write something like this: they take elements, imperatively create them, put text on them, append childs – it turns out Captain Dynamism.
The same thing happens on our android:
val unreadIcon = findViewById (R.id.unread)
if (unreadCount == 0) {
unreadIcon.setVisibility (GONE)
} else if (unreadCount> 0) {
unreadIcon.setVisibility (VISIBLE)
unreadIcon.setCount (unreadCount)
var hasImportant = unreadMessages.exists (it.isImportant)
if (hasImportant) {
unreadCount.setTextColor (Red)
} else {
unreadCount.setTextColor (Blue)
}
}
I haven’t checked unreadIcon for null, although I should. Somewhere I have updated the TextColor depending on something. Do not forget to change back in case of any changes.
We can conclude: to be a Captain of Dynamism, you need to keep in mind a lot of things, because there are a lot of states, and there are even more transitions between states. Often, if we are not doing animation, transitions are not important to us, only states are important to us. We want the user to see one, then see the second, and between them, perhaps, there was some kind of transition.
But you can get rid of transitions. Let’s try to build a framework that will allow us to do this.