Channels ▼
RSS

JVM Languages

Developing Android Apps with Scala and Scaloid: Part 1


Working with Styles

The Android SDK allows you to specify styles and themes in XML resources separate from the XML that defines the UI layout. Scaloid takes a different approach — providing the necessary helpers to allow you to define styles with Scala code.

You can change the values of the properties for both the widget and its related LayoutParams object by calling different methods. Scaloid mimics the XML attributes and also provides new methods that reduce the code required to specify values for common properties. For example, the following line sets the text color, the background color, and the text size for the EditText widget. In addition, the code calls the margin method for the related LayoutParams object with a single 25 dip parameter to specify the same value for the margin in the four directions: top, right, bottom, and left.

SEditText().inputType(TEXT_PASSWORD).textColor(Color.BLUE).backgroundColor(Color.WHITE).textSize(30 sp).<<.margin(25 dip).>>

This one line made changes to an individual widget. Scaloid allows you to use a SViewGroup.style(View => View) method to apply styles by taking advantage of Scala's pattern matching and type safety. The style specification must return the view component that has to be shown on the screen; therefore, you can even return a completely new widget. The following lines show a new version of a simple Scaloid UI that uses the style method to set the values of different properties according to the matching widget type and return the actual component that has to be shown on the screen. This way, the style information is in a different block, separated from the UI definition.

import android.graphics.Color
import org.scaloid.common._


class HelloScaloidActivity extends SActivity {

  override def onCreate(savedInstanceState: Bundle) {
    super.onCreate(savedInstanceState)
  
    contentView = new SFrameLayout {
      this += new SVerticalLayout {
          style {
	      case b: SButton => b.textColor(Color.RED).textSize(40 sp).<<.margin(30 dip).>>
	      case e: SEditText => e.textColor(Color.BLUE).backgroundColor(Color.WHITE).textSize(30 sp).<<.margin(25 dip).>>
	      case t: STextView => t.textColor(Color.YELLOW).textSize(30 sp).<<.wrap.>> 
	   }    

        STextView("Enter your password")
        SEditText().inputType(TEXT_PASSWORD)
        STextView("Repeat your password")
        SEditText().inputType(TEXT_PASSWORD)
        SButton("Sign in")
      }.<<.fill.>>
    }
  }
}

Scaloid
Figure 3: An Android device emulator displaying the UI generated with the Scaloid code and the styles applied to each widget.

You can easily override any property value by calling the necessary methods for each widget. For example, the following line would make the text size of the TextView larger than the default value specified by the style pattern matching:

STextView("Enter your password").textSize(45 sp)

As seen in the code, you can easily work with the dip and sp units by adding them after the value. Scaloid defines an internal UnitConversion class and a ConversionImplicits trait that makes it easy to convert from either dip or sp to pixel units. For example, the following line converts 45 sp to pixel units:

val textSizeInpixels:Int = (45 sp)

Scaloid provides other useful implicit conversions such as String to Uri and Int resource IDs to the following types:

  • Array[CharSequence]
  • Array[String]
  • CharSequence
  • Drawable
  • Movie

Working with Listeners

The listener interfaces in the Android API allow you to code actions in callbacks that will be executed when you're notified that a specific event occurs. Scaloid uses many shortcuts to simplify the code required to append code to listeners. For example, the following line defines the code that has to run when the user taps the "Sign in" button. The openUri method opens the URI in a Web browser or in a view assigned to the HTTP protocol. Remember that Scaloid provides an implicit conversion from String to Uri.

SButton("Sign in").onClick(openUri("http://drdobbs.com"))

The onClick method is a listener-appending method that provides a shortcut to the more complex setOnClickListener. As you might guess, Scaloid listener-appending methods remove both the set prefix and the Listener suffix; therefore, you can use onTouch instead of setOnTouchListener and onKey instead of setOnKeyListener. The previous line is equivalent to the following longer code:

SButton("Sign in").setOnClickListener(new View.OnClickListener {
	def onClick(v:View) {
		openUri("http://drdobbs.com")
	}
})

If you have Android development experience, you already know a toast provides simple feedback about an operation in a small popup. The following code uses the default listener callbacks and a call to Toast.makeText to display "You pressed the Sign in button" in a small popup with a short length when you click or tap the "Sign in" button (see Figure 4). Again, forgive me for using hardcoded strings that should be string resources.

SButton("Sign in").setOnClickListener(new View.OnClickListener {
	def onClick(v:View) {
		Toast.makeText(context, "You pressed the Sign in button", Toast.LENGTH_SHORT).show()
	}
})

Scaloid
Figure 4: The popup displayed with the toast method.

Scaloid provides a toast method that displays the popup that will be displayed for a brief period of time by default. The following line uses both the click-listener-appending and the toast methods to reduce the code to a single line:

SButton("Sign in").onClick(toast("You pressed the Sign in button"))

You can call the toast method without worrying about the thread in which you are running because the method makes sure that the call to Toast.makeText runs on the UI thread. This way, the code is easier to read because you don't have to make calls to the Activity.runOnUIThread method.

Conclusion

Scaloid is a good example of how you can use Scala's features to simplify code and implement a new way of creating Android apps with a DSL. Scaloid provides many interesting features to simplify asynchronous task processing and the execution of methods from system services. I'll explore them in the next article. I'll also discuss important classes and traits that you must understand when working with Scaloid. This way, you will have a good idea of many important features offered by Scaloid and can decide whether it is a good fit for your Android projects.


Gaston Hillar is a frequent contributor to Dr. Dobb's.

Related Article

Developing Android Apps with Scala and Scaloid: Part 2


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video