Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'typed' of github.com:jberkel/android-plugin into typed
  • Loading branch information
Nathan Hamblen committed Jul 15, 2010
2 parents d74f5c4 + c66748f commit c44630b
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 6 deletions.
8 changes: 8 additions & 0 deletions README.markdown
Expand Up @@ -59,6 +59,14 @@ Whenever you change build versions, you'll need to run `update` again to fetch d

[cb]: http://code.google.com/p/simple-build-tool/wiki/CrossBuild

##Typed resources references

As an enhancement to the Android build process, this plugin can generate typed references to application layout elements. To enable, mix the `TypedResources` trait into your sbt project definition. During compilation a file `TR.scala` will be generated under `src_managed/main/scala`.

Typed resource references are created in an object `TR` (similar to Android's standard `R`). These are handled by the method `findView` defined in the traits `TypedView` and `TypedActivity`. There are also implicit conversions defined in the object `TypedResource`; import these to add the method on demand to any views and activities in scope. The `findView` method casts the view to the known resource type before returning it, so that application code can avoid the redundancy of casting a resource to a type it has declared in the resource definition.

Since Android's resource IDs are scoped to the application, a warning is issued by the plugin when the same ID is used for different types of a resources; the type of resources retrieved by that ID will be unpredictable.

##Hacking on the plugin

If you need make modifications to the plugin itself, you can compile and install it locally (you need at least sbt 0.7.x to build it):
Expand Down
1 change: 1 addition & 0 deletions notes/0.5.0.markdown
@@ -0,0 +1 @@
* `TypedResources` trait processes layout definitions to generate typed resource references in a Scala source file
18 changes: 12 additions & 6 deletions src/main/scala/TypedResources.scala
Expand Up @@ -5,15 +5,15 @@ trait TypedResources extends AndroidProject {
def managedScalaPath = "src_managed" / "main" / "scala"
def typedResource = managedScalaPath / "TR.scala"
abstract override def mainSourceRoots = super.mainSourceRoots +++ managedScalaPath
def xmlResources = mainResPath ** "*.xml"
def layoutResources = mainResPath / "layout" ** "*.xml"
override def compileAction = super.compileAction dependsOn generateTypedResources
override def cleanAction = super.cleanAction dependsOn cleanTask(managedScalaPath)
override def watchPaths = super.watchPaths +++ xmlResources
override def watchPaths = super.watchPaths +++ layoutResources

lazy val generateTypedResources = fileTask(typedResource from xmlResources) {
lazy val generateTypedResources = fileTask(typedResource from layoutResources) {
val Id = """@\+id/(.*)""".r
val androidJarLoader = ClasspathUtilities.toLoader(androidJarPath)
val resources = xmlResources.get.flatMap { path =>
val resources = layoutResources.get.flatMap { path =>
XML.loadFile(path.asFile).descendant_or_self flatMap { node =>
// all nodes
node.attribute("http://schemas.android.com/apk/res/android", "id") flatMap {
Expand All @@ -29,7 +29,13 @@ trait TypedResources extends AndroidProject {
}
}
}
}.foldLeft(Map.empty[String, String]) { case (m, (k, v)) => m + (k -> v) }
}.foldLeft(Map.empty[String, String]) {
case (m, (k, v)) =>
m.get(k).foreach { v0 =>
if (v0 != v) log.warn("Resource id '%s' mapped to %s and %s" format (k, v0, v))
}
m + (k -> v)
}
FileUtilities.write(typedResource.asFile,
""" |package %s
|import android.app.Activity
Expand All @@ -51,7 +57,7 @@ trait TypedResources extends AndroidProject {
|trait TypedActivity extends Activity with TypedActivityHolder { def activity = this }
|object TypedResource {
| implicit def view2typed(v: View) = new TypedViewHolder { def view = v }
| implicit def view2typed(act: Activity) = new TypedActivityHolder { def activity = act }
| implicit def activity2typed(act: Activity) = new TypedActivityHolder { def activity = act }
|}
|""".stripMargin.format(
manifestPackage, resources map { case (id, classname) =>
Expand Down

0 comments on commit c44630b

Please sign in to comment.