这是解决方案,将 Android 与 Eclipse 3.7 和 Scala 3.0.0 一起使用没有任何问题。
- 安装Eclipse 3.7(对我来说是3.7.2)和Android SDK - 如果您的系统中还没有Java SDK 7v22,请安装。 注意:特殊的 Android ADT Bundle 不允许安装 scala(截至 2013 年 6 月,linux 站)。
- 通过将 Eclipse 指向此网站来安装适用于 Eclipse 的 Android ADT 插件版本 22:
https://dl-ssl.google.com/android/eclipse/
http://download.scala-ide.org/sdk/e37/scala210/stable/site
https://androidproguardscala.s3.amazonaws.com/UpdateSiteForAndroidProguardScala
现在,创建一个 scala 项目,
- 照常创建 Android 项目
- 右键项目,
Configure,Add Scala nature
- 右键单击项目,
Add AndroidProguardScala nature
你已经完成了。
缩放安卓代码
现在好事发生了。
首先,您可以对任何活动进行 scalafy,您将可以访问 scala 的独特功能,例如:
这是其中的一些示例。
package com.example.testing;
import android.app.Activity
import android.os.Bundle
import scala.collection.mutable.Map
import android.view.View
import android.widget.SeekBar
import android.widget.ImageButton
import android.graphics.drawable.Drawable
import android.widget.TextView
trait ActivityUtil extends Activity {
implicit def func2OnClickListener(func: (View) => Unit):View.OnClickListener = {
new View.OnClickListener() { override def onClick(v: View) = func(v) }
}
implicit def func2OnClickListener(code: () => Unit):View.OnClickListener = {
new View.OnClickListener() { override def onClick(v: View) = code() }
}
private var customOnPause: () => Unit = null
override def onPause() = {
super.onPause()
if(customOnPause != null) customOnPause()
}
def onPause(f: =>Unit) = {
customOnPause = {() => f}
}
private var customOnCreate: Bundle => Unit = null
override def onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
if(customOnCreate != null) customOnCreate(savedInstanceState)
}
def onCreate(f: Bundle => Unit) = {
customOnCreate = f
}
// Keep references alive when fetched for the first time.
private implicit val vMap = Map[Int, View]()
private implicit val ibMap = Map[Int, ImageButton]()
private implicit val sbMap = Map[Int, SeekBar]()
private implicit val tvMap = Map[Int, TextView]()
private implicit val dMap = Map[Int, Drawable]()
def findView[A <: View](id: Int)(implicit v: Map[Int, A]): A = v.getOrElseUpdate(id, findViewById(id).asInstanceOf[A])
def findDrawable[A <: Drawable](id: Int)(implicit v: Map[Int, A]): A = v.getOrElseUpdate(id, getResources().getDrawable(id).asInstanceOf[A])
implicit class RichView(b: View) { // Scala 2.10 !
def onClicked(f: =>Unit) = b.setOnClickListener{ () => f }
}
// Implicit functions to operate directly on integers generated by android.
implicit def findViewImageButton(id: Int): ImageButton = findView[ImageButton](id)
implicit def findViewSeekBar(id: Int): SeekBar = findView[SeekBar](id)
implicit def findViewTextView(id: Int): TextView = findView[TextView](id)
implicit def findDrawable(id: Int): Drawable = findDrawable[Drawable](id)
implicit def findRichView(id: Int): RichView = toRichView(findView[View](id))
}
现在,在所有以前的样板之后,编写简洁的活动非常有用。请注意我们如何像视图一样直接对 id 进行操作。如果可以从各种结构中推断出方法,则需要使用 (view: TextView).requestFocus() 进行消歧。
// Now after all the boilerplate, it is very useful to write consise activities
class MyActivity extends Activity with ActivityUtil {
import R.id._ // Contains R.id.button, R.id.button2, R.id.button3, R.id.mytextview
lazy val my_button: ImageButton = button //In reality, R.id.button
lazy val his_button: ImageButton = button2
onCreate { savedInstanceState => // The type is automatically inferred.
setContentView(R.layout.main)
my_button.setOnClickListener(myCustomReactClick _)
his_button.setOnClickListener { () =>
//.... Scala code called after clicking his_button
}
button3.onClicked {
// Awesome way of setting a method. Thanks Scala.
}
mytextview.setText("My text") // Whoaaa ! setText on an integer.
(mytextview: TextView).requestFocus() // Disambiguation because the method is ambiguous
// Note that because of the use of maps, the textview is not recomputed.
}
def myCustomReactClick(v: View) = {
// .... Scala code called after clicking my_button
}
onPause{
// ... Custom code for onPause
}
}
确保 scala 文件的名称与其中包含的主要活动相匹配,在这种情况下,它应该是 MyActivity.scala。
其次,将scala项目设置为库项目,以用作具有不同资源的应用程序的基础,请关注regular way of setting up a library project。右键单击要作为基础库项目的 scala 项目Properties、Android,然后选中isLibrary。
要使用这个库创建派生项目并且您可以为其生成APK,创建一个新的android项目,并且不添加任何scala或androidproguardscala性质,只需右键单击,Properties,Android,然后添加以前的scala项目作为图书馆。
更新 使用新版本的 Android 插件,您应该转到Project Properties > Build Päth > Order and Export 并检查Android Private Libraries。这将允许在库项目和主项目中导出 scala 库,即使主项目未分配 Scala。
测试 使用插件Robolectric 可以轻松测试您的android scala 项目。只需按照创建测试项目的步骤,为其添加 Scala 特性。您甚至可以使用新的 scala 调试器,通过添加 scalatest 库,您可以使用应该匹配器和 Scala 的许多其他功能。