溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Scala+Eclipse+Android手機(jī)開(kāi)發(fā)的方法是什么

發(fā)布時(shí)間:2021-12-09 09:18:40 來(lái)源:億速云 閱讀:143 作者:iii 欄目:編程語(yǔ)言

本篇內(nèi)容介紹了“Scala+Eclipse+Android手機(jī)開(kāi)發(fā)的方法是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

眾所周知Android平臺(tái)上可以跑Java,因此運(yùn)行在JVM之上的Scala也可以跑。在本文中,我們將創(chuàng)建一個(gè)在 Android 設(shè)備上運(yùn)行的移動(dòng)應(yīng)用程序。您將需要安裝 Android SDK;本文使用 V1.5 SDK。應(yīng)用程序代碼將用 Scala 編程語(yǔ)言編寫(xiě)。如果您從來(lái)沒(méi)用過(guò) Scala,那么沒(méi)有關(guān)系,因?yàn)楸疚膶⒔忉?Scala 代碼。但是,即使您不熟悉 Scala,建議您至少熟悉 Java 語(yǔ)言。本文使用 Scala V2.7.5 進(jìn)行開(kāi)發(fā)。對(duì)于 Android 和 Scala 都提供了很好的 Eclipse 插件。本文使用 Eclipse V3.4.2 和 Android Development Tools(ADT) V0.9.1 以及 Scala IDE 插件 V2.7.5。

設(shè)置

編寫(xiě) Android 應(yīng)用程序聽(tīng)起來(lái)像是一個(gè)復(fù)雜的命題。Android 應(yīng)用程序在它們自己的虛擬機(jī)中運(yùn)行:Dalvik 虛擬機(jī)。但是,Android 應(yīng)用程序的構(gòu)建路徑是開(kāi)放的。下面表明了我們將使用的基本策略。

圖 1. Android 上 Scala 的構(gòu)建路徑

Scala+Eclipse+Android手機(jī)開(kāi)發(fā)的方法是什么

其思想是,我們首先將所有 Scala 代碼編譯成 Java 類(lèi)文件。這是 Scala 編譯器的工作,所以這方面沒(méi)什么太復(fù)雜的事情。接下來(lái),獲取 Java 類(lèi)文件,使用 Android dex 編譯器將類(lèi)文件編譯成 Android 設(shè)備上的 Dalvik VM 使用的格式。這就是所謂的 dexing,也是 Android 應(yīng)用程序的常規(guī)編譯路徑。通常,要經(jīng)歷從 .java 文件到 .class 文件再到 .dex 文件的過(guò)程。在本文,惟一不同的是我們從 .scala 文件開(kāi)始。***,.dex 文件和其他應(yīng)用程序資源被壓縮成一個(gè) APK 文件,該文件可安裝到 Android 設(shè)備上。

那么,如何讓這一切發(fā)生?我們將使用 Eclipse 做大部分工作。但是,此外還有一個(gè)較復(fù)雜的步驟:要讓代碼運(yùn)行,還需要來(lái)自標(biāo)準(zhǔn) Scala 庫(kù)中的代碼。在典型的 Scala 安裝中,這是 /lib/scala-library.jar 中一個(gè)單獨(dú)的 JAR。但是,這個(gè) JAR 包括一些不受 Android 支持的代碼。有些代碼需要稍作調(diào)整,有些代碼則必須移除。scala-library.jar 的定制構(gòu)建是運(yùn)行得***的,至少目前是這樣。請(qǐng)參閱 參考資料,了解這里使用的定制構(gòu)建。我們將把這個(gè) JAR 稱(chēng)作 Android 庫(kù) JAR。

有了這個(gè) JAR,剩下的事情就很容易了。只需使用 Eclipse 的 ADT 插件創(chuàng)建一個(gè) Android 項(xiàng)目。然后將一個(gè) Scala 特性(nature)添加到項(xiàng)目中。用前面談到的 Android 庫(kù)替代標(biāo)準(zhǔn)的 Scala 庫(kù)。***,將輸出目錄添加到類(lèi)路徑中?,F(xiàn)在,可以開(kāi)始了。現(xiàn)在,我們有了基本的設(shè)置,接下來(lái)看看我們將使用 Scala 創(chuàng)建的 Android 應(yīng)用程序。

UnitsConverter

現(xiàn)在,我們知道如何利用 Scala 代碼,將它轉(zhuǎn)換成將在 Android 設(shè)備上運(yùn)行的二進(jìn)制格式,接下來(lái)可以使用 Scala 創(chuàng)建一個(gè)移動(dòng)應(yīng)用程序。我們將創(chuàng)建的應(yīng)用程序是一個(gè)簡(jiǎn)單的單位轉(zhuǎn)換應(yīng)用程序。通過(guò)這個(gè)應(yīng)用程序可以方便地在英制單位與公制單位之間來(lái)回轉(zhuǎn)換。這是一個(gè)非常簡(jiǎn)單的應(yīng)用程序,但是我們將看到,即使是最簡(jiǎn)單的應(yīng)用程序也可以從使用 Scala 中獲益。我們首先看看 UnitsConverter 的布局元素。

創(chuàng)建布局

您也許對(duì)編寫(xiě)手機(jī)上運(yùn)行的 Scala 感到興奮,但是并非所有的移動(dòng)開(kāi)發(fā)編程都應(yīng)該用 Scala 或 Java 語(yǔ)言完成。Android SDK 提供了一種很好的方式,使用基于 XML 的布局系統(tǒng)將用戶界面代碼與應(yīng)用程序邏輯分離。我們來(lái)看看本文中的應(yīng)用程序的主要布局文件,如清單 1 所示。

清單 1. Converter 應(yīng)用程序的主要布局

< ?xml version="1.0" encoding="utf-8"?>
< RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:gravity="center_horizontal" android:padding="10px"
    >
    < TextView android:id="@+id/prompt_label" android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:text="@string/prompt_metric"/>
    < EditText android:id="@+id/amount" android:layout_below="@id/prompt_label"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"/>
    < TextView android:id="@+id/uom_label"  
        android:layout_below="@id/amount"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:text="@string/uom"/>
    < Spinner android:id="@+id/uom_value"
        android:layout_below="@id/uom_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    < Button android:id="@+id/convert_button"
        android:layout_below="@id/uom_value"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/convert_button_label"/>
    < TextView android:id="@+id/result_value"
        android:layout_below="@id/convert_button"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"/>        
< /RelativeLayout>

以上代碼非常簡(jiǎn)潔地創(chuàng)建了該應(yīng)用程序的主 UI。它的根節(jié)點(diǎn)是一個(gè) RelativeLayout 容器元素。Android SDK 中有很多布局選項(xiàng)。RelativeLayout 指示運(yùn)行時(shí)使用相對(duì)定位對(duì)不同的 UI 小部件進(jìn)行布局。要使用相對(duì)定位,可添加可見(jiàn)元素 — 在這里是一個(gè) TextView 元素。這是用于顯示文本的一個(gè)簡(jiǎn)單的元素。它被賦予一個(gè) ID prompt_label。接下來(lái)的元素,即一個(gè) EditText 元素(一個(gè)文本輸入框)將用到它。這個(gè)元素有一個(gè) layout_below 屬性,它的值等于 prompt_label ID。換句話說(shuō),EditText 應(yīng)該放在名為 prompt_label 的元素的下方。

布局代碼剩下的部分非常簡(jiǎn)單。有一個(gè)帶標(biāo)簽的文本輸入框、一個(gè)帶標(biāo)簽的微調(diào)器(一個(gè)組合框或下拉框)、一個(gè)按鈕和一個(gè)用于輸出的文本框。圖 2 顯示正在運(yùn)行的應(yīng)用程序的一個(gè)截圖,其中標(biāo)出了不同的元素。

圖 2. Android lLayout — 分解圖

Scala+Eclipse+Android手機(jī)開(kāi)發(fā)的方法是什么

那么,以上視圖中看到的不同文本值來(lái)自哪里呢?注意,清單 1 中的一些元素有一個(gè) text 屬性。例如,prompt_label 元素有一個(gè)等于 @string/prompt_metric 的 text 屬性。這表明它將使用 Android 應(yīng)用程序中一個(gè)標(biāo)準(zhǔn)的資源文件:strings.xml 文件,如清單 2 所示。

清單 2. strings.xml 資源

< ?xml version="1.0" encoding="utf-8"?>
< resources>
    < string name="prompt_metric">Enter amount (KM, g, L, C)< /string>
    < string name="prompt_english">Enter amount (miles, lbs, gallons,F)< /string>
    < string name="uom">Units of Measure< /string>
    < string name="convert_button_label">Convert< /string>
    < string name="app_name">Converter< /string>
    < string name="english_units">English< /string>
    < string name="metric_units">Metric< /string>
< /resources>

現(xiàn)在可以看到,圖 2 中所有的文本來(lái)自何處。微調(diào)器有一個(gè)下拉框,其中包含可用于度量的單位,那些單位在清單 2 中沒(méi)有列出。相反,它們來(lái)自另一個(gè)文件 arrays.xml,如清單 3 所示。

清單 3. arrays.xml 資源

< ?xml version="1.0" encoding="utf-8"?>
< resources>
    < array name="english_units">
        < item>Fahrenheit< /item>
        < item>Pounds< /item>
        < item>Ounces< /item>
        < item>Fluid Ounces< /item>
        < item>Gallons< /item>
        < item>Miles< /item>
        < item>Inches< /item>
    < /array>
    < array name="metric_units">
        < item>Celsius< /item>
        < item>Kilograms< /item>
        < item>Grams< /item>
        < item>Millileters< /item>
        < item>Liters< /item>
        < item>Kilometers< /item>
        < item>Centimeters< /item>
    < /array>    
< /resources>

現(xiàn)在,我們可以看到將用于微調(diào)器的那些值。那么,這些值如何出現(xiàn)在微調(diào)器中,應(yīng)用程序如何在英制單位與公制單位之間切換?要回答這些問(wèn)題,我們需要看看應(yīng)用程序代碼本身。

Scala 應(yīng)用程序代碼

Converter 應(yīng)用程序的代碼非常簡(jiǎn)單 — 不管用什么語(yǔ)言編寫(xiě)。當(dāng)然,用 Java 編寫(xiě)起來(lái)非常容易,但是用 Scala 編寫(xiě)也同樣不復(fù)雜。首先我們看看前面見(jiàn)過(guò)的 UI 背后的代碼。

視圖背后的代碼

解釋創(chuàng)建 UI 的 Scala 代碼的最簡(jiǎn)單方式是先看看代碼,然后走查一遍。對(duì)于任何應(yīng)用程序,都是在應(yīng)用程序的 AndroidManifest.xml 文件中定義應(yīng)用程序的默認(rèn)活動(dòng)。任何 UI 背后都有一個(gè) Activity 類(lèi),默認(rèn)的 Activity 定義當(dāng)應(yīng)用程序初次裝載時(shí)執(zhí)行的 Activity 類(lèi)。對(duì)于像本文這樣簡(jiǎn)單的應(yīng)用程序,有一個(gè) Converter 類(lèi),清單 4 中顯示了它的源代碼。

清單 4. Converter 活動(dòng)類(lèi)

class Converter extends Activity{
    import ConverterHelper._
    private[this] var amountValue:EditText = null
    private[this] var uom:Spinner= null
    private[this] var convertButton:Button = null
    private[this] var resultValue:TextView = null
    
    override def onCreate(savedInstanceState:Bundle){
      super.onCreate(savedInstanceState)
      setContentView(R.layout.main)
      uom = findViewById(R.id.uom_value).asInstanceOf[Spinner]
      this.setUomChoice(ENGLISH)
      amountValue = findViewById(R.id.amount).asInstanceOf[EditText]
      convertButton = findViewById(R.id.convert_button).asInstanceOf[Button]
      resultValue = findViewById(R.id.result_value).asInstanceOf[TextView]
      convertButton.setOnClickListener( () => {
          val unit = uom.getSelectedItem.asInstanceOf[String]
          val amount = parseDouble(amountValue.getText.toString)
          val result = UnitsConverter.convert(Measurement(unit,amount))
          resultValue.setText(result)
      })
    }
    override def onCreateOptionsMenu(menu:Menu) = {
      super.onCreateOptionsMenu(menu)
      menu.add(NONE, 0, 0, R.string.english_units)
      menu.add(NONE, 1, 1, R.string.metric_units)
      true
    }
    override def onMenuItemSelected(featureId:Int, item:MenuItem) = {
      super.onMenuItemSelected(featureId, item)
      setUomChoice(if (item.getItemId == 1) METRIC else ENGLISH)
      true
    }
    private 
    def setUomChoice(unitOfMeasure:UnitsSystem){
      if (uom == null){
        uom = findViewById(R.id.uom_value).asInstanceOf[Spinner]
      }
      val arrayId = unitOfMeasure match {
        case METRIC => R.array.metric_units
        case _ => R.array.english_units
      }
      val units = new ArrayAdapter[String](this, R.layout.spinner_view, 
        getResources.getStringArray(arrayId))
      uom.setAdapter(units)      
    }
}

我們從這個(gè)類(lèi)的頂部開(kāi)始。它擴(kuò)展 android.app.Activity。這是一個(gè) Java 類(lèi),但是從 Scala 中可以對(duì) Java 類(lèi)輕松地進(jìn)行細(xì)分。接下來(lái),它有一些實(shí)例變量。每個(gè)實(shí)例變量對(duì)應(yīng)前面定義的一個(gè) UI 元素。注意,每個(gè)實(shí)例變量還被限定為 private[this]。這演示了 Scala 中特有的一種訪問(wèn)控制級(jí)別,而 Java 語(yǔ)言中不存在這種訪問(wèn)控制。這些變量不僅是私有的,而且只屬于 Converter 類(lèi)的特定實(shí)例。這種級(jí)別的訪問(wèn)控制對(duì)于移動(dòng)應(yīng)用程序來(lái)說(shuō)有些大材小用,但是如果您是一名 Scala 開(kāi)發(fā)人員,可以放心地在 Android 應(yīng)用程序上使用您熟悉的語(yǔ)法。

回到清單 4 中的代碼,注意,我們覆蓋了 onCreate 方法。這是 Activity 類(lèi)中定義的方法,通常被定制的 Activity 覆蓋。如果用 Java 語(yǔ)言編寫(xiě)該代碼,那么應(yīng)該添加一個(gè) @Override 標(biāo)注。在 Scala 中,override 是一個(gè)關(guān)鍵詞,用于確保正確性。這樣可以防止誤拼方法名之類(lèi)的常見(jiàn)錯(cuò)誤。如果誤拼了方法名,Scala 編譯器將捕捉到方法名并返回一個(gè)錯(cuò)誤。注意,在這個(gè)方法上,以及任何其他方法上,不需要聲明返回類(lèi)型。Scala 編譯器可以輕松推斷出該信息,所以不需要多此一舉。

onCreate 中的大部分代碼類(lèi)似于 Java 語(yǔ)言編寫(xiě)的代碼。但是有幾點(diǎn)比較有趣。注意,我們使用 findViewById 方法(在 Activity 子類(lèi)中定義)獲得不同 UI 元素的句柄。這個(gè)方法不是類(lèi)型安全的,需要進(jìn)行類(lèi)型轉(zhuǎn)換(cast)。在 Scala 中,要進(jìn)行類(lèi)型轉(zhuǎn)換,可使用參數(shù)化方法 asInstanceOf[T],其中 T 是要轉(zhuǎn)換的類(lèi)型。這種轉(zhuǎn)換在功能上與 Java 語(yǔ)言中的轉(zhuǎn)換一樣。不過(guò) Scala 有更好的語(yǔ)法。接下來(lái),注意對(duì) setUomChoice 的調(diào)用(稍后我們將詳細(xì)談到這個(gè)方法)。***,注意上述代碼獲得一個(gè)在布局 XML 中創(chuàng)建的按鈕的句柄,并添加一個(gè)單擊事件處理程序。

如果用 Java 語(yǔ)言編寫(xiě),那么必須傳入 Android 接口 OnClickListener 的一個(gè)實(shí)現(xiàn)。這個(gè)接口只定義一個(gè)方法:onClick。實(shí)際上,您關(guān)心的只是那個(gè)方法,但是在 Java 語(yǔ)言中無(wú)法直接傳入方法。而在 Scala 中則不同,在 Scala 中可以傳入方法字面量(literal)或閉包。在這里,我們用語(yǔ)法 () => { ... } 表示閉包,其中方法的主體就是花括號(hào)中的內(nèi)容。開(kāi)始/結(jié)束括號(hào)表示一個(gè)不帶參數(shù)的函數(shù)。但是,我將這個(gè)閉包傳遞到 Button 的一個(gè)實(shí)例上的 setOnClickListener 方法,Button 是 Android SDK 中定義的一個(gè) Java 類(lèi)。如何將 Scala 閉包傳遞到 Java API?我們來(lái)看看。

Android 上的函數(shù)式編程

為了理解如何讓 Android API 使用函數(shù)字面量,看看 Converter 類(lèi)定義的***行。這是一條重要的語(yǔ)句。這是 Scala 的另一個(gè)很好的特性。您可以在代碼的任何地方導(dǎo)入包、類(lèi)等,它們的作用域限于導(dǎo)入它們的文件。在這里,我們導(dǎo)入 ConverterHelper 中的所有東西。清單 5 顯示 ConverterHelper 代碼。

清單 5. ConverterHelper

object ConverterHelper{
  import android.view.View.OnClickListener
  implicit def funcToClicker(f:View => Unit):OnClickListener = 
    new OnClickListener(){ def onClick(v:View)=f.apply(v)}
  implicit def funcToClicker0(f:() => Unit):OnClickListener = 
    new OnClickListener() { def onClick(v:View)=f.apply}
}

這是一個(gè) Scala 單例(singleton),因?yàn)樗褂脤?duì)象聲明,而不是類(lèi)聲明。單例模式被直接內(nèi)置在 Scala 中,可以替代 Java 語(yǔ)言中的靜態(tài)方法或變量。在這里,這個(gè)單例存放一對(duì)函數(shù):funcToClicker 和 funcToClicker0。這兩個(gè)函數(shù)以一個(gè)函數(shù)作為輸入?yún)?shù),并返回 OnClickListener 的一個(gè)實(shí)例,OnClickListener 是 Android SDK 中定義的一個(gè)接口。例如,funcToClicker 被定義為以一個(gè)函數(shù) f 為參數(shù)。這個(gè)函數(shù) f 的類(lèi)型為帶一個(gè) View 類(lèi)型(Android 中的另一個(gè)類(lèi))的輸入?yún)?shù)的函數(shù),并返回 Unit,它是 void 在 Scala 中的對(duì)等物。然后,它返回 OnClickListener 的一個(gè)實(shí)現(xiàn),在這個(gè)實(shí)現(xiàn)中,該接口的 onClick 方法被實(shí)現(xiàn)為將輸入函數(shù) f 應(yīng)用到 View 參數(shù)。另一個(gè)函數(shù) funcToClick0 也做同樣的事情,只是以一個(gè)不帶輸入?yún)?shù)的函數(shù)為參數(shù)。

這兩個(gè)函數(shù)(funcToClicker 和 funcToClicker0)都被定義為隱式函數(shù)(implicit)。這是 Scala 的一個(gè)方便的特性。它可以讓編譯器隱式地將一種類(lèi)型轉(zhuǎn)換成另一種類(lèi)型。在這里,當(dāng)編譯器解析 Converter 類(lèi)的 onCreate 方法時(shí),它遇到一個(gè) setOnClickListener 調(diào)用。這個(gè)方法需要一個(gè) OnClickListener 實(shí)例。但是,編譯器卻發(fā)現(xiàn)一個(gè)函數(shù)。在報(bào)錯(cuò)并出現(xiàn)編譯失敗之前,編譯器將檢查是否存在隱式函數(shù),允許將函數(shù)轉(zhuǎn)換為 OnClickListener。由于確實(shí)還有這樣的函數(shù),所以它執(zhí)行轉(zhuǎn)換,編譯成功?,F(xiàn)在,我們理解了如何使用 Android 中的閉包,接下來(lái)更仔細(xì)地看看應(yīng)用程序邏輯 — 特別是,如何執(zhí)行單位轉(zhuǎn)換計(jì)算。

單位轉(zhuǎn)換和計(jì)算

我們回到清單 4。傳入 onClickListener 的函數(shù)收到用戶輸入的度量單位和值。然后,它創(chuàng)建一個(gè) Measurement 實(shí)例,并將該實(shí)例傳遞到一個(gè) UnitsConverter 對(duì)象。清單 6 顯示相應(yīng)的代碼。

清單 6. Measurement 和 UnitsConverter

case class Measurement(uom:String, amount:Double)

object UnitsConverter{
      // constants
    val lbToKg = 0.45359237D
      val ozToG = 28.3495231
      val fOzToMl = 29.5735296
      val galToL = 3.78541178
      val milesToKm = 1.609344
      val inchToCm = 2.54  
   
      def convert (measure:Measurement)= measure.uom match {
          case "Fahrenheit" => (5.0/9.0)*(measure.amount - 32.0) + " C"
            case "Pounds" => lbToKg*measure.amount + " kg"
            case "Ounces" => ozToG*measure.amount + " g"
            case "Fluid Ounces" => fOzToMl*measure.amount + " mL"
            case "Gallons" => galToL*measure.amount + " L"
            case "Miles" => milesToKm*measure.amount + " km"
            case "Inches" => inchToCm*measure.amount + " cm"
            case "Celsius" => (9.0/5.0*measure.amount + 32.0) + " F"
            case "Kilograms" => measure.amount/lbToKg + " lbs"
            case "Grams" => measure.amount/ozToG + " oz"
            case "Millileters" => measure.amount/fOzToMl + " fl. oz."
            case "Liters" => measure.amount/galToL + " gallons"
            case "Kilometers" => measure.amount/milesToKm + " miles"
            case "Centimeters" => measure.amount/inchToCm + " inches"
            case _ => ""
      }
}

Measurement 是一個(gè) case 類(lèi)。這是 Scala 中的一個(gè)方便的特性。用 “case” 修飾一個(gè)類(lèi)會(huì)導(dǎo)致這個(gè)類(lèi)生成這樣一個(gè)構(gòu)造函數(shù):這個(gè)構(gòu)造函數(shù)需要類(lèi)的屬性,以及 equals、 hashCode 和 toString 的實(shí)現(xiàn)。它對(duì)于像 Measurement 這樣的數(shù)據(jù)結(jié)構(gòu)類(lèi)非常適合。它還為定義的屬性(在這里就是 uom 和 amount)生成 getter 方法。也可以將那些屬性定義為 vars(可變變量),然后也會(huì)生成 setter 方法。僅僅一行 Scala 代碼可以做這么多事情!

接下來(lái),UnitsConverter 也是一個(gè)單例模式,因?yàn)樗鞘褂?object 關(guān)鍵詞定義的。它只有一個(gè) convert 方法。注意,convert 被定義為相當(dāng)于一條單一語(yǔ)句 — 一條 match 語(yǔ)句。它是一個(gè)單一表達(dá)式,所以不需要額外的花括號(hào)。它使用 Scala 的模式匹配。這是函數(shù)式編程語(yǔ)言中常見(jiàn)的一個(gè)強(qiáng)大特性。它類(lèi)似于 Java 語(yǔ)言和很多其他語(yǔ)言中的 switch 語(yǔ)句。但是,我們可以匹配字符串(實(shí)際上,還可以有比這高級(jí)得多的匹配)。如果字符串匹配,則執(zhí)行適當(dāng)?shù)挠?jì)算,并返回格式化的字符串,以供顯示。***,注意與 _ 匹配的***一個(gè) case。Scala 中的很多地方使用下劃線作為通配符。在這里,它表示匹配任何東西,這類(lèi)似于 Java 語(yǔ)言中的 default 語(yǔ)句。

現(xiàn)在,我們理解了應(yīng)用程序中的計(jì)算,***來(lái)看看剩下的 UI 設(shè)置和菜單。

UI 初始化和菜單

回到清單 4。我們說(shuō)過(guò)要看看 setUomChoice。這個(gè)方法被定義為帶有一個(gè) UnitsSystem 類(lèi)型的參數(shù)。我們來(lái)看看如何定義這個(gè)類(lèi)型。

清單 7. UnitsSystem

sealed case class UnitsSystem()
case object ENGLISH extends UnitsSystem
case object METRIC extends UnitsSystem

我們看到,UnitsSystem 是一個(gè)密封的 case 類(lèi),沒(méi)有屬性??瓷先ニ皇呛苡杏?。接下來(lái),我們看看兩個(gè) case 對(duì)象。還記得嗎,object 表示 Scala 中的一個(gè)單例。在這里,有兩個(gè) case 對(duì)象,每個(gè) case 對(duì)象都擴(kuò)展 UnitsSystem。這是 Scala 中的一個(gè)常見(jiàn)的特色,它可以提供更簡(jiǎn)單、更類(lèi)型安全的枚舉方式。

現(xiàn)在 setUomChoice 的實(shí)現(xiàn)更加合理。在獲得微調(diào)器的一個(gè)句柄后,我們匹配傳入的 UnitsSystem 的類(lèi)型。這標(biāo)識(shí)了我們?cè)谇懊嬉?jiàn)到的 arrays.xml 中的一個(gè)數(shù)組。這是使用 Android SDK 生成的 R 類(lèi)表示資源,例如 arrays.xml 文件。一旦知道使用哪個(gè)數(shù)組,我們就通過(guò)創(chuàng)建一個(gè)傳入微調(diào)器的適配器(在這里是一個(gè) ArrayAdapter),使用那個(gè)數(shù)組作為微調(diào)器的數(shù)據(jù)源。

***,看看清單 4 中的 onCreateOptionsMenu 和 onMenuItemSelected 方法。這些方法是在 Activity 中定義的,我們將在 Converter 活動(dòng)中覆蓋這些方法。***個(gè)方法創(chuàng)建一個(gè)菜單。第二個(gè)方法處理用戶從菜單中選擇 English 或 metric 的事件。它再次調(diào)用 setUomChoice。這使用戶可以在從英制單位轉(zhuǎn)換為公制單位與從公制單位轉(zhuǎn)換為英制單位之間進(jìn)行切換。

“Scala+Eclipse+Android手機(jī)開(kāi)發(fā)的方法是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI