Вот решение: без проблем использовать 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 на этот веб-сайт:
https://dl -ssl.google.com / Android / затмение /
http://download.scala -ide.org / SDK / е37 / scala210 / стабильный / сайт
https://androidproguardscala.s3.amazonaws.com/UpdateSiteForAndroidProguardScala
Теперь, чтобы создать проект Scala,
- Создайте проект Android как обычно
- Щелкните правой кнопкой мыши по проекту,
Configure
, Add Scala nature
- Щелкните правой кнопкой мыши по проекту,
Add AndroidProguardScala nature
Готово.
Скалярный код Android
Теперь хорошие вещи случаются.
Во-первых, вы можете скальпировать любое действие и получить доступ к уникальным функциям 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 или androidproguardscala, просто щелкните правой кнопкой мыши, Properties
, Android
и добавьте предыдущий проект scala как библиотека.
ОБНОВЛЕНИЕ В новой версии подключаемого модуля Android перейдите на Project Properties > Build Päth > Order and Export
и отметьте Android Private Libraries
. Это позволит экспортировать библиотеку scala как в проект библиотеки, так и в основной проект, даже если основной проект не назначен Scala.
ТЕСТИРОВАНИЕ Использование плагина Robolectric позволяет легко протестировать ваш проект Scala для Android. Просто следуйте инструкциям по созданию тестового проекта, добавьте в него природу Scala. Вы даже можете использовать новый отладчик scala, и, добавив библиотеку scalatest , вы сможете использовать средства сравнения и многие другие функции, которые есть в Scala.