As an extension of Android’s R class, sbt-android introduces a the TR class. It generates type safe mappings from ids in xml views to their respective class. This is explained best by a simple example:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android">
  <TextView
    android:id="@+id/my_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</LinearLayout>

Java

Based on the xml view definition above, you will typically search for the TextView by its id to specify the title at runtime. This is a very common use case, and in Java it works as shown below:

public class MyActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.view);

        TextView title = (TextView) findViewById(R.id.my_title);
        title.setText("Hello Java!");
    }
}

Scala

It is of course possible to do the exact same thing with Scala:

class MyActivity extends Activity {
  override def onCreate(savedInstanceState: Bundle) = {
    super.onCreate(savedInstanceState)

    setContentView(R.layout.main)

    val title = findViewById(R.id.my_title).asInstanceOf[TextView]
    title.setText("Hello Scala!")
  }
}

But thanks to TR you can get rid off the cast and therefore simplify the code and improve type safety at the same time:

class MyActivity extends Activity with TypedActivity {
  override def onCreate(savedInstanceState: Bundle) = {
    super.onCreate(savedInstanceState)

    setContentView(R.layout.main)

    val title = findView(TR.my_title)
    title.setText("Hello Scala!")
  }
}

The TR mappings are generated on every compile, when sbt-android detects changes in the class. Your IDE usually helps you to keep the R up to date behind the scenes, but it won’t do that for the TR class. You can still achieve a similar effect if you open your project sbt shell and run ~compile. The tilde before the command tells sbt to repeat this task whenever it detects a file change.

TR mappings only work for xml widgets that use the android:id="@+id/xxx" property. If you chose not to use the TR class you may want to disable it for performance reasons in your project’s sbt configuration via typedResources := false.