Ответ 1
Вот решение, чтобы использовать Android с Eclipse 3.7 и Scala 3.0.0 без проблем.
- Установите Eclipse 3.7 (для меня 3.7.2) и Android SDK - плюс Java SDK 7v22, если это еще не в вашей системе. Внимание: специальный пакет Android ADT Bundle не позволяет установить Scala (по состоянию на июнь 2013 года, Linux-станция).
- Установите плагин Android ADT версии 22 для Eclipse, указав Eclipse на этот сайт:
- Установите Scala версию IDE версии 3.0.0, указав Eclipse на этот сайт:
- Установите плагин AndroidProguardScala v47, указав Eclipse на этот сайт:
https://androidproguardscala.s3.amazonaws.com/UpdateSiteForAndroidProguardScala
Теперь, чтобы создать проект Scala,
- Создайте проект Android как обычно
- Щелкните правой кнопкой мыши проект,
Configure
,Add Scala nature
- Щелкните правой кнопкой мыши проект,
Add AndroidProguardScala nature
Вы закончили.
Scalafying android code
Теперь хорошие вещи случаются. Во-первых, вы можете масштабировать любую активность, и вы получите доступ к Scala уникальным функциям, таким как:
- ленивые оценки для определения представлений внутри тела класса
- Неявные функции преобразования, чтобы настроить взаимодействие представления с вашим кодом.
- Точка с запятой и весь синтаксический сахар 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))
}
Теперь, после всего предыдущего шаблона, очень полезно написать краткие действия. Обратите внимание, как мы можем напрямую работать с идентификаторами, как если бы они были представлениями. Несознание необходимо как (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 в качестве проекта библиотеки, использовать его в качестве базы для приложений, имеющих разные ресурсы, следуйте регулярному способу создания проекта библиотеки. Щелкните правой кнопкой мыши проект Scala, который вы хотите в качестве проекта базовой библиотеки, Properties
, Android
и отметьте isLibrary
.
Чтобы создать деривационный проект с использованием этой библиотеки и для которого вы можете создать APK, создайте новый проект для Android и не добавляя никакой природы Scala или orroidproguardscala, просто щелкните правой кнопкой мыши, Properties
, Android
и добавьте предыдущий Scala проект как библиотека.
ОБНОВЛЕНИЕ. В новой версии Android-модуля вы должны перейти на Project Properties > Build Päth > Order and Export
и проверить Android Private Libraries
. Это позволит экспортировать библиотеку Scala как в проект библиотеки, так и в главный проект, даже если главный проект не назначен scala.
ТЕСТИРОВАНИЕ Использование плагина Robolectric позволяет легко протестировать ваш проект Android w60. Просто выполните шаги для создания тестового проекта, добавьте к нему внешний вид Scala. Вы даже можете использовать новый отладчик Scala, и, добавив библиотеку scalatest, вы можете использовать символы соответствия и многие другие функции Scala.