本篇文章我來手把手教大家做一個HarmonyOS 應用的登錄頁面,逐步講解,非常細致,百分百能學會,并提供全部源碼。頁面使用 DevEco Studio 的低代碼開發。
通過本文的實踐經驗,我想告訴大家, HarmonyOS 應用開發其實并不難,只要了解具體的開發流程和開發思想,大家都可以很快上手。祝愿大家都可以趕上時代浪潮,讓青春隨鴻蒙千帆飄揚!
下面這張圖是我們的目標實現圖,具體實現流程將由我一步一步講解:
一、項目初始化
1、創建低代碼項目
下載安裝 DevEco Studio,新建一個支持 Super Visual 低代碼模式的項目。
具體過程可以參考我上一篇文章:HarmonyOS應用開發-搭建開發環境
2、低代碼項目結構解讀
初始項目目錄如下:
├──entry/src/main/ets // 代碼區
│ ├──entryability
│ │ └──EntryAbility.ets // 程序入口類
│ └──pages
│ └──Index.ets // 首頁的邏輯描述文件
├──entry/src/main/resources // 資源文件
└──entry/src/main/supervisual└──pages└──Index.visual // 首頁的數據模型
其中.ets文件就是我們正常編寫界面邏輯的文件,語言為ArcTS;
.visual為低代碼項目特有的文件,由系統根據我們對界面的可視化設計自動更新,用寫字板打開能看到是存儲界面設計的Json文本;
二、添加靜態文件
1、新增圖片文件
ets 文件下創建 common\images\icon 文件夾,icon內添加我們需要添加的圖片文件,本教程我們用到了3個“其他登錄方式”的圖標。
添加的圖標圖片如下:
增加完三個圖標后,我們的項目結構更新如下:
├──entry/src/main/ets // 代碼區
│ ├──common
│ │ └──images
│ │ └──icon // 圖標圖片
│ │ ├──csdn.png // 圖標A
│ │ ├──huawei.png // 圖標B
│ │ └──openatom.png // 圖標C
│ ├──entryability
│ │ └──EntryAbility.ets // 程序入口類
│ └──pages
│ └──Index.ets // 首頁的邏輯描述文件
├──entry/src/main/resources // 資源文件
└──entry/src/main/supervisual└──pages└──Index.visual // 首頁的數據模型
2、新增常量類
這一步可選,一般意義上,我們會根據系統業務需要把一些固定的參數寫到一個記錄常量的 ArcTS 文件里,比如命名為 Const.ts,本次我們把頁面需要的常量寫到了頁面自帶的 index.ets文件里,所以沒有建立常量類,特此說明。
如果需要添加,我們可以把常量類 Const.ts 放在和 images 文件夾平級的位置,添加 Const.ts 之后的項目結構如下:
├──entry/src/main/ets // 代碼區
│ ├──common
│ │ ├──Const.ts // 常量類
│ │ └──images
│ │ └──icon // 圖標圖片
│ │ ├──csdn.png // 圖標A
│ │ ├──huawei.png // 圖標B
│ │ └──openatom.png // 圖標C│ ├──entryability
│ │ └──EntryAbility.ets // 程序入口類
│ └──pages
│ └──Index.ets // 首頁的邏輯描述文件
├──entry/src/main/resources // 資源文件
└──entry/src/main/supervisual└──pages└──Index.visual // 首頁的數據模型
三、編寫登錄頁界面
1、低代碼設計界面布局
① 放置容器組件
初始話的頁面如圖,Root 根結構下包含一個 Column 的容器,容器里有一個 "Hello World" 的 Text 文本控件。
我們直接復用這個 Column 容器,刪除 Text 控件(左側組件樹或右側可視化屏幕里選中控件然后按Backspace鍵就可以刪除)。
② 放置圖標圖片
如圖,我們需要放置一個水平居中的應用圖標:
思路:下面我們來實現登錄頁面的圖標,我們需要創建一個行容器(Row),然后拖一個圖片組件(Imgae)進去,并使圖片居中。
操作:在列容器(Cloumn)里拖一個行容器(Row)過去,寬度(width)設置為 100%,高度(height)設置為 100vp,設置水平居中、垂直居中,位置為絕對定位(Position),距離頁面上方 95vp 距離。
然后我們拖入圖片組件(Imgae),設置圖片寬高均為 100vp(和Row的高相等)。
圖片的Src(圖片存儲路徑)設置為app自帶的默認圖標,至此我們的登錄頁應用圖標就顯示出來了。
③ 放置描述文字
接下來,我們需要放置描述性文本,如圖:
思路:這里用到的是文本組件(Text),我們需要填寫文字內容、定義字體大小和組件的位置。
操作:拖兩個文本組件(Text)到行容器(Row)下面。
設置內容(Content)為 "用戶登錄",字體大小(FontSize)為 26fp,字體對齊(TextAlign)為居中(Center),文字組件框體大小(Size)為寬度 100%,高度 50vp,位置為絕對定位(Position),距離頁面頂部 200vp。效果圖如下:
同理,我們制作 "登錄賬號以使用更多服務" 文本框。
我們設置文本框內容(Content)為 "登錄賬號以使用更多服務",字體大小(FontSize)為 14fp,字體對齊(TextAlign)為居中(Center),文字組件框體大小(Size)為寬度 100%,高度 30vp,位置為絕對定位(Position),距離頁面頂部 250vp,字體顏色(FontColor)為 #8c8c8c(灰色)。效果圖如下:
④ 放置賬號密碼輸入框
接下來,我們要制作賬號密碼的輸入部分,這里用到的是文本輸入組件(TextInput)。
目標實現效果如下:
思路:我們需要兩個文本輸入組件(TextInput)用來實現賬號、密碼的錄入,下方 "短信驗證碼登錄" 和 "忘記密碼",我們使用普通文本組件(Text)實現,讓兩個普通文本組件(Text)并列在一行,然后一個左對齊,一個右對齊。
操作流程:
首先,我們處理賬號和密碼輸入兩個文本輸入框。
拖兩個文本輸入組件(TextInput)在我們之前拖的組件下面。
設置文本輸入組件一(text-input1):
設置文本占位符(Placeholder)為 "郵箱/手機號/用戶名",類型(Type)為 Normal;
組件框體大小(Size)為寬度(Width)為 100%,高度(Height)為?50vp;
背景顏色(BackgroundColor)為白色(#ffffff);
邊框(Border)只要底邊框,底邊框寬度(BorderBottomWidth)為 1vp,邊框顏色(BorderColor)為深灰色(#4a4a4a);
位置為絕對定位(Position),距離頁面頂部 328vp。
效果圖如下:
設置文本輸入組件二(text-input2):
設置文本占位符(Placeholder)為 "郵箱/手機號/用戶名",類型(Type)為 Password;
組件框體大小(Size)為寬度(Width)為 100%,高度(Height)為?50vp;
背景顏色(BackgroundColor)為白色(#ffffff);
邊框(Border)只要底邊框,底邊框寬度(BorderBottomWidth)為 1vp,邊框顏色(BorderColor)為深灰色(#4a4a4a);
位置為絕對定位(Position),距離頁面頂部 380vp。
效果圖如下:
下一步,我們來制作兩個輸入框下面的 "短信驗證碼登錄" 和?"忘記密碼"。
拖一個行容器(Row)到文本輸入框組件下面,設置行容器(Row)的屬性。
設置組件居中;
設置組件的尺寸(Size),寬度(Width)為 94%,高度(Height)為 30vp;
設置組件位置為絕對定位(Position),距離頁面頂部 430vp,距離左側為 3%;
接著,我們往容器里拖兩個文本組件(Text)。
設置組件屬性如下:
組件一(text5)內容為 "短信驗證碼登錄",字體居左,字體大小為 14fp;
定義尺寸(Size),寬度(Width)為 50%,高度(Height)為 30vp;
組件位置為絕對定位(Position),距離左側為 0%;
組件二(text6)內容為 "忘記密碼",字體居右,字體大小為 14fp;
定義尺寸(Size),寬度(Width)為 50%,高度(Height)為 30vp;
組件位置為絕對定位(Position),距離左側為 50%;
⑤ 放置登錄按鈕
這一步是最簡單的,制作登錄按鈕部分,只需要一個按鈕組件(Button)和一個文本組件(Text)。
目標實現效果如下:
思路:我們拖一個按鈕組件(Button),再在按鈕下方拖一個文本組件(Text)即可。
操作流程:
首先,我們拖一個按鈕組件。
定義組件的屬性:
設置組件寬度(Width)為 90%,高度(Height)為 40vp;
內容為"登錄",字體默認居中,字體大小為 20fp;
組件位置為絕對定位(Position),距離左側為 5%,距離頂部 530vp;
下方再拖一個文本組件(Text),設置組件屬性:
文本組件內容為 "注冊賬號",字體居中,字體大小為 14fp;
定義尺寸(Size),寬度(Width)為 100%,高度(Height)為 30vp;
組件位置為絕對定位(Position),距離頂部為 570vp;
⑥ 放置Grid網格控件
最后,我們來制作其他登錄方式的選擇部分,這里用到的是網格組件(Grid)、網格內單個元素(GridItem)、其他常見組件(圖片、文字、行/列等)。
目標實現效果如下:
思路:我們需要一個網格組件(Grid),組件內包含若干個子元素,這個用Grid內對象組件(GridItem)可以實現,這樣我們就可以根據我們后端傳值的數目來動態顯示登錄方式,而不是把三種登錄方式固定寫死。每個Grid內子元素(GridItem)里放置一個行容器(Row),行容器(Row)里上方放一個圖片組件(Image),下方放一個文本組件(Text)。
操作流程:
首先,我們拖一個網格組件(Grid),設置組件屬性:
組件寬度(width)設置為 100%,高度(height)設置為 10%;
內容居中,絕對定位,距離頂部 90%;
往網格組件(Guid)里拖一個GuidItem組件,這是一個動態顯示的子元素組件,會根據我們提供的參數動態進行內容顯示,由于我們在設計上固定為行內顯示3個,所以寬度就直接定為33.3%了。
設置GridItem組件屬性:
組件寬度(width)設置為 33.3%,高度(height)設置為 100%(因為是相對于Grid);
往GridItem里拖入一個行容器(Row),設置組件屬性:
高度和寬度均為 100%;
然后再往行容器(Row)里拖一個圖片組件(Image)和一個文本組件(Text);
設置組件屬性:
圖片(Image)組件:
圖片路徑(Src),我們使用編譯器自帶的 Logo;
對象適應方式(ObjectFit) 為包含(Contain);
組件寬度(width)設置為 70%,高度(height)設置為 56%;
距離上邊距(MarginTop) 10%;
絕對定位,距離左側 15%;
文字(Text)組件:
文字內容(Content),我們先隨便填個 "測試";
文本居中;
組件寬度(width)設置為 100%,高度(height)設置為 24%;
絕對定位,距離頂部 60%(60%~70%均可);
做到這里,我們的ArcUI的設計就完成了,是不是覺得和下面三個圖標的目標效果還有點差距,別急,我們接下來就來實現GridItem數據的動態渲染。
2、實現數據動態渲染
下一步,我們來實現數據的動態渲染,在這個登錄頁面,我們需要對GridItem組件及其內部組件的屬性進行動態賦值。
① 創建數據源
我們先創建數據源,打開頁面對應的 ArcTS 文件(比如你現在編輯的可視化低代碼界面是Index.visual,那么對應的 ArcTS?文件就是 Index.ets)
默認的頁面 .ets 文件內容如下:
@Entry
@Component
struct Index {@State message: string = 'Hello World'build() {}
}
我們在這里創建 FunctionType 對象,用來裝配我們需要顯示的圖片路徑和文字內容。
然后再定義狀態變量 avenues,數組類型,用來包含我們裝配圖片路徑和文字內容的 FunctionType 對象。
更新后的代碼如下:
class FunctionType {name: string;icon: string;
}@Entry
@Component
struct Index {@State avenues: Array<FunctionType> = [{name: 'HuaWei', icon: "common/images/icon/huawei.png"},{name: 'CSDN', icon: "common/images/icon/csdn.png"},{name: 'OpenAtom', icon: "common/images/icon/openatom.png"}]build() {}
}
② 更新動態渲染組件屬性
回到我們低代碼頁面?Index.visual,修改網格子元素組件(GridItem)的Render里的ForEach屬性為this.avenues,其他默認;
然后我們再分別選中GridItem里的圖片組件和文本組件,對其勾選動態值。
圖片組件(Image)的圖片路徑(Src)選擇 item1.icon;
文本組件(Text)的內容(Content)選擇 item1.name;
然后我們到預覽器(Preview)的窗口里就可以看到已經完成的效果了。
至此,我們的低代碼開發部分已全部完成!?
3、低代碼頁面轉為ArcTs文件
這步是可選步驟,根據實際需要決定是否要轉,低代碼和 ArcTs 在開發頁面上各有優勢。低代碼開發迅速、改動簡單,ArcTS 則更方便自定義一些事件,擁有更好的擴展性。一般對于涉及交互業務的頁面,頁面的功能會相對比較復雜,推薦使用 ArcTS,如果是登錄頁這種簡單業務邏輯頁面,可以保留低代碼版本,不必轉化為 ArcTS 版本。
如果有需要將 .visual 頁面轉換為 .ets 文件,我們可以點擊右上角的轉換按鈕。
此操作能夠將低代碼界面轉換為 ArcTS 的代碼。
注意:轉換完之后原有的 .visual 文件會被刪除!這個過程不可逆!
目前編譯器點擊轉換按鈕后會有 ArcTS 的預覽代碼,需要點擊 Convert 來確認此次操作,本次界面轉換結果的預覽代碼如下:
Index.ets
class FunctionType {name: string;icon: string;
}@Entry
@Component
struct Index {@State avenues: Array<FunctionType> = [{name: 'HuaWei', icon: "common/images/icon/huawei.png"},{name: 'CSDN', icon: "common/images/icon/csdn.png"},{name: 'OpenAtom', icon: "common/images/icon/openatom.png"}]build() {Column() {Column() {Row() {Image($r('app.media.icon')).width("100vp").height("100vp").align(Alignment.Center).offset({ x: "0%", y: "0vp" }).backgroundImageSize(ImageSize.Auto)} .width("100%").height("100vp").position({ x: "0", y: "95vp" }).displayPriority(0).alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Center)Text("用戶登錄").width("100%").height("50vp").position({ x: "0vp", y: "200vp" }).borderRadius({ topRight: "0vp" }).textAlign(TextAlign.Center).textOverflow({ overflow: TextOverflow.Clip }).fontSize("26fp").fontWeight(FontWeight.Medium).fontFamily("sans-serif")Text("登錄帳號以使用更多服務").width("100%").height("30vp").position({ x: "0vp", y: "250vp" }).fontColor("#8c8c8c").textAlign(TextAlign.Center).fontSize("14fp")TextInput({ placeholder: "郵箱/手機號/用戶名" }).width("100%").height("50vp").position({ x: "0vp", y: "328vp" }).borderWidth({ bottom: "1vp" }).borderColor({ bottom: "#4a4a4a" }).backgroundColor("#ffffff").margin({ bottom: "0vp" }).padding({ top: "0vp" }).type(InputType.Normal)TextInput({ placeholder: "密碼" }).width("100%").height("50vp").position({ x: "0vp", y: "380vp" }).borderWidth({ bottom: "1vp" }).borderColor({ bottom: "#4a4a4a" }).backgroundColor("#ffffff").type(InputType.Password)Row() {Text("忘記密碼").width("50%").height("30vp").position({ x: "50%", y: "0px" }).textAlign(TextAlign.End).fontSize("14fp")Text("短信驗證碼登錄").width("50%").height("30vp").position({ x: "0%", y: "0vp" }).textAlign(TextAlign.Start).fontSize("14fp")} .width("94%").height("30vp").position({ x: "3%", y: "430vp" })Grid() {if (true) {ForEach(this.avenues,(item1: any, idx1: number) => {GridItem() {Row() {if (true) {Text(`${item1.name}`).width("100%").height("24%").position({ x: "0%", y: "60%" }).textAlign(TextAlign.Center).fontSize("14fp") }Image($r('app.media.icon')).width("70%").height("56%").position({ x: "15%", y: "0vp" }).margin({ top: "10%", bottom: "0vp", left: "0%", right: "0%" }).objectFit(ImageFit.Contain)} .width("100%").height("100%")} .width("33.3%").height("100%").align(Alignment.Start).offset({ x: "0vp", y: "0" })}) }} .width("100%").height("10%").align(Alignment.Center).position({ x: "0vp", y: "90%" }).backgroundImageSize(ImageSize.Auto).opacity(0.99).margin({ top: "0vp", bottom: "0vp", left: "0vp", right: "0vp" }).padding({ top: "0vp", bottom: "0vp" }).scrollBar(BarState.Off)Button("登錄").width("90%").height("40vp").position({ x: "5%", y: "530vp" }).fontSize("20fp")Text("注冊賬號").width("100%").height("30vp").position({ x: "0vp", y: "570vp" }).textAlign(TextAlign.Center).fontSize("14fp")Text("其他方式登錄").width("100%").height("4%").align(Alignment.Center).position({ x: "0vp", y: "85%" }).textAlign(TextAlign.Center).fontSize("14fp")} .width("100%").height("100%").position({ x: "0vp", y: "0vp" }).borderWidth({ bottom: "1vp" }).borderColor({ bottom: "#4a4a4a" }).justifyContent(FlexAlign.Center)} .width("100%").height("100%")}
}
四、測試應用
1、啟動仿真器
右上角選擇設備,點擊進入設備管理器,如果沒有對應的仿真設備,需要下載安裝,如果已經有,選擇 Huawei_Phone 作為調試的仿真設備,點擊啟動。
2、界面測試
點擊右上角啟動鍵,啟動項目。
有的時候會因為頁面刪除但是頁面配置沒清除完全導致運行失敗,這個需要到項目啟動類的配置文件里手動刪除多出來的頁面,啟動類配置文件的路徑是 DevEco-Studio\Test-Project\Harmony\entry\src\main\resources\base\profile\main_pages.json;
程序啟動成功,運行效果如圖: