網頁

2022年6月19日 星期日

手機 App 程式設計- AppInventor2 -物品點選系統,多 Screen (螢幕,畫面)的應用+ListPicker+TinyDB + File + Texting

註:本專案,不適合初學者學習。

研究動機

        前面介紹的飲料點餐系統或者市面上的系統,如果使用者要改成文具、運動品 等點選系統,還要修改程式,所以開發一個物品點選系統,讓使用者輕易就可更改為想要的系統。 
       飲料點餐系統,祇能選某一物品一件。現在增加使用者可以選某項物品的數量,例如 原子筆 5 支 。

功能

本程式使用到2個 Screen(螢幕,也有稱為畫面)。

  1. 第1個Screen , 可以輸入人數、第1層清單內容(即類別)、第1個類別品名和第2個類別品名,也可以祇輸入第1個類別品名。並可儲存和載入這些設定。
    如果「數量」被勾選,Screen2 會出現數量 清單選擇器。
  2. 第2個Screen,顯示座號 下拉式選單。根據第1個Screen第1層清單內容,有2個類別可選,如「餐點」和「 飲料」 。   每個類別下面還有各種品名可選。如果祇有1個類別,就不用出現類別的選單,直接出現第1個類別品名清單選擇器。
  3. 如果「數量」被勾選,會出現數量 清單選擇器。
  4. 按「點選結果」鈕,顯示每一個人點選的結果。可以直接修改「點選結果」的內容。可以儲存和載入 「點選結果」。
  5. 按「統計結果」鈕,根據「點選結果」的內容,顯示每一種品名被點選的次數。將統計結果,使用簡訊發送給店家。

執行畫面

有2個類別、數量有勾選。




進入點選系統:

按「類別」,有2類。
點「餐點」類,出現餐點品名的選單。

點「飲料」類,出現飲料品名的選單。

點完,再按「數量」,出現數量選單。






點選和統計結果:

送出訂單(簡訊):
如果 祇有1個類別,如文具。數量沒有勾選。

點選和統計結果和送出訂單(簡訊):


素材

本 app的 icon (圖示),可自己繪製或網路搜尋。

進入 Appinventor 

Google 輸入 appinventor,選 「MIT App Inventor」。


選 「Create Apps」。


網址為 :http://ai2.appinventor.mit.edu/

你應該先看此篇文章 「手機 App 程式設計- AppInventor2 -飲料點餐系統,多 screen 元件的應用」,簡單版和修改版都要看,最後修改版的專案,如名稱為 :select_drink_modify。

開啟原來的舊專案(My Projects/My projects),選舊專案,如 select_drink_modify,按一下,打開此專案。另存新專案(My Projects/ Save project  as... ),輸入新專案的名稱,如 select_object,按 「OK」鈕 。

專案的名稱只能使用大小寫字母、數字及「 _」符號,名稱的第一個字元必須是英文字母,不能使用中文字。

Designer  (畫面編排)

Screen1:




Screen1 元件相關屬性表

元件

類別

屬性

功能

Screen1

 

Title:物品點選系統AppName:select_object,可以改成 「物品點選系統」(出現在手機上面的App名稱)
Icon : 可以上傳1個背景透明的 icon圖。

1Screen元件就是1個螢幕 (畫面)

HorizontalArrangement1

Layout(介面配置)

AlignVertical:Center:2(垂直對齊,居中:2 )
Width:Fill Parent (填滿)

水平配置元件,讓裏面的元件可以水平對齊。

Label_NumberOfPeople

User Interface(使用者介面)

Text:人數:

標籤

TextBox_NumberOfPeople

User Interface

Width:50 pixels(像素)
Hint: (清空)
NumbersOnly(僅限數字):勾選  
Text: 35 

文字方塊,可以輸入 人數,預設為35

VerticallArrangement1

Layout

Width:Fill Parent

垂直配置元件,讓裏面的元件可以上下對齊。

Label_Category

User Interface

Text: 1層清單內容,至少要輸入1類內容,\n最多2類內容且中間以半形, 分開

標籤

TextBox_Category

User Interface

Text: 餐點,飲料
Hint: (清空)

 

文字方塊

第一層清單內容,祇能二類,因程式祇用到二個第二層清單選擇器。

預設是分成「餐點,飲料」二類。

VerticalArrangement2

Layout

Width:Fill Parent

垂直配置元件,讓裏面的元件可以上下對齊。

Label_Category1

User Interface

Text: 1個類別內容:

標籤

TextBox_ Category1

User Interface

Width:Fill Parent
Hint: (清空)
MultiLine(允許多行): 要勾選,可多行顯示
Text: 炸排骨飯, 炸雞腿飯,焢肉飯,炸紅糟肉飯

 

文字方塊,可以輸入1個類別內容。

CheckBox_Amount

User Interface

Checked:不勾選
Text: 數量,有勾選會出現數量清單選擇器

複選盒

VerticallArrangement3

Layout

Width:Fill Parent

垂直配置元件,讓裏面的元件可以上下對齊。

Label_ Category2

User Interface

Text: 2個類別內容:

標籤

TextBox_ Category2

User Interface

Width:Fill Parent
Hint: (清空)
MultiLine(允許多行): 要勾選,可多行顯示
Text: 珍珠奶茶,金桔檸檬,綠茶拿鐵,茉莉綠茶

文字方塊,可以輸入1個類別內容

HorizontalArrangement4

Layout

AlignVertical:Center:2(垂直對齊,居中:2 )
Width:Fill Parent (填滿)

水平配置元件,讓裏面的元件可以水平對齊。

Button_Save

User Interface

Text: 儲存設定

按鈕

Button_Load

User Interface

Text: 載入設定

按鈕

Button_Clear

User Interface

Text:清除設定

按鈕

Button_Enter

User Interface

Text: 進入點選系統

按鈕

TinyDB_Argument

Storage(資料儲存)

 

微型資料庫,用來儲存設定。

Notifier1

User Interface

 

對話框元件,用來顯示訊息。


如果是從舊專案修改,祇要選 Screen2,即可。

如果是新專案,按「Add Screen」 ,輸入新的Screen 的名稱如 Screen2,接 「OK」鈕。
Screen2:


    

Screen2 元件相關屬性表

元件

類別

屬性

功能

Screen2

 

Title:點選系統

 

1Screen元件就是1個螢幕(畫面)

HorizontalArrangement1

Layout(介面配置)

AlignVertical:Center:2(垂直對齊,居中:2 )
Width:Fill Parent(填滿)

水平配置元件,讓裏面的元件可以水平對齊。

Label_SeatNumber

User Interface(使用者介面)

Text: 座號

標籤

Spinner_SeatNumber

User Interface

 

下拉式選單,用來選座號。

ListPicker_Category

User Interface

Text(文字):類別
Title(標題):類別

清單選擇器

本例是第1層清單,先選類別。

ListPicker_Category1

User Interface

ShowFilterBar(顯示搜尋框) :勾選,讓使用者可以輸入關鍵字來搜尋
Text:第一個類別
Title:第一個類別
Visible(可見性):勾選

清單選擇器

本例是第2層清單,顯示第1個類別品名的清單。

由程式判斷是否要出現。

ListPicker_Amount

User Interface

Text(文字):數量
Title(標題):數量Visible(可見性):勾選

清單選擇器
由程式判斷是否要出現數量
清單選擇器。

HorizontalArrangement2

Layout(介面配置)

AlignVertical:Center:2(垂直對齊,居中:2 )
Width:Fill Parent(填滿)

水平配置元件,讓裏面的元件可以水平對齊。

Button_SaveResult

User Interface

Text: 儲存結果

按鈕

Button_LoadResult

User Interface

Text: 載入結果

按鈕

Label_FileName

User Interface

Text: 檔名

標籤

TextBox_FileName

User Interface

Hint(提示):可以輸入儲存點選結果的檔名
Text: order_result.txt

文字方塊,用來輸入儲存點選結果的檔名。預設為 : order_result.txt

Label_Result

User Interface

Text: 點選結果:

標籤

TextBox_Result

User Interface

Height: Fill Parent(填滿)
Width:Fill Parent
Hint: (清空)
MultiLine(允許多行): 要勾選,可多行顯示
Text: (清空)

文字方塊,顯示每一個人點選的結果。

Button_Total

User Interface

Text: 統計結果

按鈕

按下去可以顯示每一種品名被點選的次數。

TextBox_Total

User Interface

Height: 150 pixels(像素)

Width:Fill ParentHint: (清空)

MultiLine(允許多行): 要勾選,可多行顯示

Text: (清空)

文字方塊,顯示每一種品名被點選的次數。

HorizontalArrangement3

Layout

Width:Fill Parent

水平配置元件

Label_ StorePhone

User Interface

Text: 店家手機號碼:

標籤

TextBox_StorePhone

User Interface

Text: 0
NumbersOnly(僅限數字):勾選 

文字方塊,輸入店家手機號碼。

Button_Send

User Interface

Text: 送出訂單

按鈕

按下去將訂單結果以簡訊方式送給店家

ListPicker_ Category2

User Interface

ShowFilterBar(顯示搜尋框) : 勾選,讓使用者可以輸入關鍵字來搜尋
Text: 
Title:
Visible(可見性): 取消勾選

清單選擇器

本例是第2層清單,顯示第2個類別品名的清單。

Visible :取消勾選,一開始不會出現在畫面上。

File_Result

Storage(資料儲存)

 

檔案管理元件

Notifier1

User Interface

 

對話框元件

Texting1

Social(社交應用)

 

簡訊元件,將訂單以簡訊通知店家。


輸入文字

餐點,飲料

炸排骨飯, 炸雞腿飯,焢肉飯,炸紅糟肉飯
珍珠奶茶,金桔檸檬,綠茶拿鐵,茉莉綠茶

文具
原子筆,橡皮擦,立可帶,鉛筆

請輸入店家手機電話號碼,至少為10碼
簡訊已傳送!\n

Blocks(程式設計)拼塊

跟元件有關的拼塊,要先點選該元件後,再選擇是那一個拼塊;不是元件的拼塊,可以根據拼塊的顏色,判斷是屬於那一個類別。

Screen1:

----------------------------------------------------------------
說明:
全域性變數 Separator,類別分隔字元預設為半形的逗號「, 」。
----------------------------------------------------------------

----------------------------------------------------------------
說明:
GetValue  :從TinyDB_Argument (微型資料庫)中取得tag 標籤名稱的資料。如果 這個tag 標籤沒有資料,預設傳回空字串。
如果 傳回值不是空字串 (表示有將設定值存在 TinyDB_Argument ),就取出  NumberofPeople (人數)、Category (第1層清單內容,有幾個類別,最少是1個,最多2個)、Category1(第1個類別品名)、Category2(第2個類別品名)、AmountF(有無勾選數量, F :flag , 旗標)。
----------------------------------------------------------------
----------------------------------------------------------------
說明:
當Screen1出現或按了 Button_Load此按鈕,呼叫載入所有設定值程序。
----------------------------------------------------------------


----------------------------------------------------------------
說明:
當按了 Button_Save按鈕,儲存所有設定值。
----------------------------------------------------------------

--------------------------------------------------------------
說明:
當按了 Button_Clear,清除所有設定值。
----------------------------------------------------------------

---------------------------------------------------------------
說明:
當按了 Button_Enter (進入點選系統)按鈕,
設定1個區域性的變數 CategoryNumber,表示有幾個類別。
將 TextBox_Category.Text 以 , 為分隔字元,分割為幾個子字串,也就是有幾個類別。
如果 TextBox_Category.Text 不是空白,然後 
        如果 CategoryNumber =1 or 2,進入點選系統。打開另一個Screen2,起始值是一個清單,內容為「NumberofPeople、Category、Category1、Category2、CheckBox_Amount.Checked( 即Screen2 的AmountF)。
如果是CategoryNumber  >2 也不對,最多祇能2個類別。
----------------------------------------------------------------
Screen2:

----------------------------------------------------------------
說明:
global (全域變數)可用在程式中所有程序。
AmountMax :數量最大值,設為20。
Separator:類別分隔字元預設為半形的逗號「, 」。
seatnumber :座號從1開始編。
NumberofPeople :人數。從Screen1傳來清單中的第1項。
Category:第1層清單內容,類別名稱。從Screen1傳來清單中的第2項,為字串資料。
Category1:第1個類別品名。從Screen1傳來清單中的第3項,為字串資料。
Category2:第2個類別品名。從Screen1傳來清單中的第4項,為字串資料。
AmountF:是否有勾選數量,true 表示有,false 表示沒有。從Screen1傳來清單中的第5項。
----------------------------------------------------------------

----------------------------------------------------------------
說明:
AmountString:數量從1開始編,到 AmountMax,中間以 , 隔開。
Category_list:第1層清單內容,類別名稱清單。預設是空的清單。
Category1_list:第1個類別品名清單。
Category2_list:第2個類別品名清單。
Category1Number:第1個類別的項目(item)(又稱為元素,element)的個數。
Category2Number:第2個類別的項目(元素)的個數。
ItemNumber:所有項目的個數。值為 : Category1Number+Category2Number。
All_ItemName:所有項目的名稱,也就是所有品名。
EachItemSelectedNumber:每一個項目被點選的次數,資料型態為清單。
----------------------------------------------------------------

----------------------------------------------------------------
說明:
Item_Initialize : 此程序先設定一些全域性變數的值。
list from cs row text 

以逗號為分隔字元,將字串轉成清單。

lenght of list list :清單的長度,即清單內有幾個項目。

append to list list 1 list2

將list2所有項目 附加至list1 的後面。


此迴圈設定 每一個項目被點選的次數, 初始值為0,因為一開始,都沒被點選。
----------------------------------------------------------------

----------------------------------------------------------------
說明:
Generate_SeatNumberString :此程序產生座號字串,結果為: "1,2,3.....人數"。
----------------------------------------------------------------

----------------------------------------------------------------
說明:
Generate_AmountString :此程序產生數量字串,結果為: "1,2,3.....數量最大值"。
----------------------------------------------------------------

----------------------------------------------------------------
說明:
Screen2_initialize :當Screen2 出現時,要執行的動作。
設定 ListPicker.Category1  的 Text和 Title 為 Category_list 第1個項目(即第1個類別名稱)。
如果  Category2不是空字串而且Category_list 的長度為2 (即類別名稱清單有2個項目) 然後
        設定 ListPicker.Category2  的 Text和 Title 為 Category_list 第2個項目(即第2個類別名稱)。
        ListPicker.Category1.Visible 為 False。( 隱藏 ListPicker.Category1 )。
        (如果有2個類別,將第1個類別品名選單設定為不可見,而第2個類別品名選單本來就是不可見,根據使用者在類別選單挑選的索引值(選中項索引),去打開那個類別下面的品名選單。)
否則
 ListPicker.Category.Visible 為 False。(隱藏 ListPicker.Category)。
 ListPicker.Category1.Visible 為 True。
(既然祇有1個類別,就不用出現類別選單,直接出現Category1(第1個類別品名)選單。)

如果數量有勾選 然後
    ListPicker.Amount.Visible 為 True,出現 數量選單。
否則
    ListPicker.Amount.Visible 為 False,隱藏 數量選單。
----------------------------------------------------------------

----------------------------------------------------------------
說明:
如果 ListPicker.Category 的SelectionIndex(選中項索引)為1,表示選到第1個類別,所以 打開 第1個類別品名選單。
否則 就是選到第2個類別,打開第2個類別品名選單。
----------------------------------------------------------------

----------------------------------------------------------------
說明:




x 的值是 第1個類別品名或是第2個類別品名 選單,被選到的品名(Selection)(選中項)。

「點選結果 」文字方塊的文字 join(合併) 座號 、 分隔字元(即逗號)、挑選到的品名。
如果數量有勾選 然後
    ListPicker.Amount.Open,打開數量選單。(合併數量)
否則
    「點選結果 」文字方塊的文字直接 合併 換行符號。
----------------------------------------------------------------


----------------------------------------------------------------
說明:
ListPicker_Category1, ListPicker_Category2,  ListPicker.Amount 三個選單被挑選後的事件程序。
---------------------------------------------------------------

----------------------------------------------------------------
說明:
從「點選結果 」文字方塊的文字,作統計。有問題,出現錯誤訊息。
說明請參考我的另一篇文章:


如果數量有勾選,Increment (區域性變數,增加量) 是 One_Line_list 此清單的第3個元素。
例如 One_Line_list 的內容為 :1號 ,炸排骨飯,3 ,第3個元素為3。


EachItemSelectedNumber:每一個項目被點選的次數(資料型態為清單),加上Increment 。
---------------------------------------------------------------

----------------------------------------------------------------
說明:
如果此項目被點選的次數大於0 ,然後 顯示項目名稱和此項目被點選的次數。
----------------------------------------------------------------

----------------------------------------------------------------
說明:
讀入(ReadFrom)檔案後,把讀進來的文字(File_Result.GotText程序中的 text),放在 「點選結果 」文字方塊(TextBox_Result.Text)內。
如果檔名,是以 / 開頭的話,則檔案是放在根目錄下。沒有 / , 是放在一般應用程式的私人儲存區。
----------------------------------------------------------------

----------------------------------------------------------------
說明:
訂單以簡訊的方式傳送。
如果  TextBox_StorePhone(店家手機電話號碼)的長度小於10 ,ShowMessageDialog(顯示訊息對話框)的Message(訊息)為  "請輸入店家手機電話號碼,至少為10碼! "
否則   
設定 Texting 簡訊元件的PhoneNumber(電話號碼)為 TextBox_StorePhone.Text。
設定 Texting 簡訊元件的Message(簡訊內容)為 TextBox_order.Text(訂單)。
呼叫 Texting.SendMessage 發送簡訊。
出現 "訂單已透過簡訊送出!" 的訊息。
----------------------------------------------------------------

程式改良

程式並沒有對所有錯誤狀況作判斷,這祇是一個專題實作的雛型,不是很完整。程式的寫法,也有改善的地方。