Fork me on GitHub

Monday, January 28, 2013

A CSS-like styling on Android

Android SDK provides styles and themes to reuse common properties on XML layout. However, XML is verbose, and requires endless findByViewId(...) to reference it in your code.

Today I released Scaloid 0.8, which features a new way of styling Android components. Before saying too much words, let's start with an example:
new SVerticalLayout {
  STextView("I am 10 dip tall")
  STextView("Me too")
  STextView("I am taller than you")
  SEditText("Yellow input field")
  SButton("Red alert!")
}

This code displays five components on the screen:



Then, let me add a style:

new SVerticalLayout {
  style {
    case b: SButton => b.textColor(Color.RED).onClick(toast("Bang!"))
    case t: STextView => t.textSize(10 dip)
    case v => v.backgroundColor(Color.YELLOW)
  }

  STextView("I am 10 dip tall")
  STextView("Me too")
  STextView("I am taller than you").textSize(15 dip) // overriding
  SEditText("Yellow input field")
  SButton("Red alert!")
}

This code results the layout shown below:

Even if you are new to Scaloid, you may easily get the point of the code. As you expected, if you clicked the button, the toast message "Bang!" is shown.

In styles of Android SDK or even in CSS, only static properties can be assigned (such as color, margin, font, etc ...). However, Scaloid can do anything with the component, such as assigning onClick behavior, adding a new component, or replacing the component itself with another component.

For example, Scaloid styles can append another view component to the layout. let's start with a very simple code:
new SVerticalLayout {
  SEditText("Name")
  SEditText("Address")
}

Needless to say, this shows an input field with the default value "Name", as shown below:


Then, we add a style like this:
new SVerticalLayout {
  style {
    case t: SEditText =>
      STextView(t.text)
      t.text("").onFocusChange(toast("You entered: " + t.text))
  }
   
  SEditText("Name")
  SEditText("Address")
}
In this time, you can see:

The value "Name" is moved to a new text view. Also, if you moved the focus, the toast "You entered: ..." will be shown.

The signiture of the style function is style(stl: View => View). That means the style specification should return a view component, that is actually visualized on the screen. Therefore you can return another component to replace the original. For example:
new SVerticalLayout {
  style {
    case t: SEditText => new STextView().text(t.text)
  }
 
  SEditText("You cannot edit me")
}

Then every SEditText field is relpaced by a STextView component.


Type-safety for your pleasure

Thanks to Scala language, all of these examples are type-safe, which means that auto-completion of your IDE will suggest valid candidates, and if you made a mistake, IDE will warn you and the code will not be compiled at all.


1 comment: