Scala で Android アプリ開発(ActionBarSherlock 編)
ActionBar は使いたいけれど、ターゲットの API Level が低い場合に重宝する ActionBarSherlock を Scala から使う。
sbt プロジェクト設定
まずは依存するライブラリを指定する。準備編を参考に作成したディレクトリ /path/to/hello-world の直下に main.sbt を作成する。
import sbt._ import Keys._ import AndroidKeys._ libraryDependencies ++= Seq( "com.actionbarsherlock" % "library" % "4.0.0-SNAPSHOT" artifacts(Artifact("library", "apklib", "apklib")), "android" % "compatibility-v4" % "r3-SNAPSHOT" )
次に依存するライブラリの位置を指定する。/path/to/hello-world/project/build.scala を次のように修正する。
import sbt._ import Keys._ import AndroidKeys._ object General { val settings = Defaults.defaultSettings ++ Seq ( name := "Hello World", version := "0.1", versionCode := 0, scalaVersion := "2.9.1", platformName in Android := "android-15", // android-10 から android-15 に変更 resolvers += "ActionBarSherlock snapshots" at "http://r.jakewharton.com/maven/snapshot/" // 新規追加 ) // 以下、変更が無いので省略
最後に依存ライブラリを取得する。
$ cd /path/to/hello-world $ sbt > update // 省略 [info] Resolving com.actionbarsherlock#library;4.0.0-SNAPSHOT ... [info] Resolving android#compatibility-v4;r3-SNAPSHOT ... // 省略 [info] Done updating. [success] Total time: 4 s, completed 20XX/XX/XX XX:XX:XX > exit
API Level の修正
AndroidManifest.xml 内の
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.drops_market.Downloader"> <!-- 変更が無いので省略 --> <!-- android:minSdkVersion="10" から変更 --> <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="15"/> </manifest>
Activity から使用する
package com.github.cooldaemon.HelloWorld import _root_.android.app.Activity import _root_.android.os.Bundle import _root_.android.content.Context // 新規に追加 import _root_.com.actionbarsherlock.app.SherlockActivity import _root_.com.actionbarsherlock.view.{Menu, SubMenu, MenuItem} // Activity を SherlockActivity に変更 class MainActivity extends SherlockActivity with TypedActivity { implicit lazy val c: Context = this override def onCreate(bundle: Bundle) { setTheme(R.style.Theme_Sherlock) // テーマを設定 super.onCreate(bundle) setContentView(R.layout.main) findView(TR.textview).setText("hello, world!") } object MenuID extends Enumeration { val FOO,BAR,BAZ = Value } // 試しにメニューを追加してみる override def onCreateOptionsMenu(menu: Menu): Boolean = { menu .add(0, MenuID.FOO.id, Menu.NONE, "Foo") .setIcon(android.R.drawable.ic_menu_view) .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM) val subMenu = menu.addSubMenu(0, MenuID.BAR.id, Menu.NONE, "Bar") subMenu.getItem .setIcon(android.R.drawable.ic_menu_more) .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM) subMenu .add(0, MenuID.BAZ.id, Menu.NONE, "Baz") .setIcon(android.R.drawable.ic_menu_add) .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM) true } override def onOptionsItemSelected(item: MenuItem): Boolean = { item.getItemId match { case id if id == MenuID.FOO.id => AtomicToast.show("Selected Foo") case id if id == MenuID.BAR.id => AtomicToast.show("Selected Bar") case id if id == MenuID.BAZ.id => AtomicToast.show("Selected Baz") case _ => } true } }
Toast 編で作成した AtomicToast を利用している。
テーマとして何が使えるか?SHOW_AS_ACTION_IF_ROOM って何よ?という疑問をお持ちの方は Google 先生にお尋ねください。
/path/to/hello-world/main.sbt に次のような設定していると…
javacOptions ++= Seq("-Xlint:unchecked") scalacOptions ++= Seq("-verbose", "-unchecked", "-deprecation")
ものすごい数の ActionBarSherlock 関連の警告が出力されるが、ご愛嬌という事で。