位元詩人 [Solar2D] 程式設計教學:使用 PickerWheel 製作多選項清單

Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

[注意事項] Corona 改名為 Solar2D

每個項目有多個選擇時,使用 PickerWheel 就會比用很多 RadioButton 節省應用程式的畫面,畢竟大部分的行動裝置畫面有限;此外,過多的 RadioButton 會使得畫面較不美觀。我們將完整的程式碼放在這裡,本文僅節錄部分內容。

本範例程式的示意圖如下:

{{< figure src="img/corona-sdk/pickerwheel.png" alt="Solar2D 的 PickerWheel" class="phone" >}}

本例用 PickerWheel 製作的選單可從不同大小、顏色、形狀中來選擇,程式會依選擇來繪製相對應的多邊形。一開始時,我們要先設置好相關的數據:

local color = {}
color.red = {255, 0, 0}
color.orange = {255, 165, 0}
color.yellow = {255, 255, 0}
color.green = {0, 255, 0}
color.blue = {0, 0, 255}
color.purple = {128, 0, 128}

local sizeCircle = {}
sizeCircle.small = 30
sizeCircle.medium = 40
sizeCircle.large = 50

local sizeRect = {}
sizeRect.small = {60, 36}
sizeRect.medium = {80, 48}
sizeRect.large = {100, 60}

local sizeTriangle = {}
sizeTriangle.small = {-20, -25, -20, 25, 30, 0}
sizeTriangle.medium = {-30, -35, -30, 35, 40, 0}
sizeTriangle.large = {-40, -45, -40, 45, 50, 0}

local itemLocX = 0.5
local itemLocY = 0.2

這些是繪製多邊形時會用到的參數,請各位讀者自行閱讀。

一開始,我們程式繪製中型、橘色的圓:

-- Init `item`.
local item = display.newCircle(display.contentWidth * itemLocX, display.contentHeight * itemLocY, sizeCircle.medium)
item:setFillColor(color.orange[1] / 255, color.orange[2] / 255, color.orange[3] / 255)

接著,我們製作 pickerWheel 物件:

local columnData = {
  {
    align = "left",
    width = 100,
    startIndex = 2,
    labels = { "small", "medium", "large" }
  },
  {
    align = "left",
    width = 110,
    startIndex = 2,
    labels = { "red", "orange", "yellow", "green", "blue", "purple" }
  },
  {
    align = "left",
    startIndex = 1,
    labels = { "circle", "rectangle", "triangle" }
  }
}

-- Create a PickerWheel widget.
local pickerWheel = widget.newPickerWheel(
  {
    x = display.contentCenterX - 10,
    y = display.contentCenterY + 70,
    columns = columnData,
    fontSize = 18,
    columnColor = {180 / 255, 255 / 255, 255 / 255},
  }
)

在建立 pickerWheel 物件時,要設置每一欄的大小和選項,詳細的設置方式可到這裡觀看。根據這篇文章,可知 PickerWheel 的欄位內容無法動態改變,若需要動態改變內容需動態生成 PickerWheel。

在我們這個例子中,我們用 timer 監控 pickerWheel 物件的變化,並根據 pickerWheel 的值動態改變所繪製出來的多邊形:

-- The event listener for `pickerWheel`.
local onValueSelected = function ()
  item:removeSelf()

  local values = pickerWheel:getValues()

  local _size = values[1].value
  local _color = values[2].value
  local _shape = values[3].value

  if _shape == "circle" then
    item = display.newCircle(display.contentWidth * itemLocX, display.contentHeight * itemLocY, sizeCircle[_size])
  elseif _shape == "rectangle" then
    item = display.newRoundedRect(display.contentWidth * itemLocX, display.contentHeight * itemLocY,
      sizeRect[_size][1], sizeRect[_size][2], 10)
  elseif _shape == "triangle" then
    item = display.newPolygon(display.contentWidth * itemLocX, display.contentHeight * itemLocY,
      {sizeTriangle[_size][1], sizeTriangle[_size][2],
        sizeTriangle[_size][3], sizeTriangle[_size][4],
        sizeTriangle[_size][5], sizeTriangle[_size][6]})
  end

  item:setFillColor(color[_color][1] / 255, color[_color][2] / 255, color[_color][3] / 255)
end

-- Update `item` by current selection.
timer.performWithDelay(100, onValueSelected, -1)

這裡簡單說明一下 timer.performWithDelay 的用法如下:

timer.performWithDelay(delay, listener [, iterations])

delay 的單位為毫秒,像本例為 100 毫秒,即為每 0.1 秒檢查一次 pickerWheel 物件。delay 需考慮 framerate,例如,FPS 為 60 的話,最低不可低於 1000 / 60 = 16.67 毫秒。

listener 是回呼程式,可為函式 (function) 或表 (table),本範例為函式。

iterationstimer 的執行次數。設為 0-1 表示執行無限次,如同本文的範例的做法。

如果不想用 timer,也可以使用按鈕。這時候反而比較簡單,只要使用者按按鈕時,讀取 PickerWheel 的值,接著做出相對應的動作即可。讀者可以試著將本例的 timer 改為按鈕看看。

關於作者

身為資訊領域碩士,位元詩人 (ByteBard) 認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

位元詩人喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,位元詩人將所學寫成文章,放在這個網站上和大家分享。