本帖使用Dayu200為開發闆,展示一個化妝品線上商店的App首頁:溢彩美妝App。
注意:本文不涉及App上的使用者互動,僅為頁面設計效果的實作。
(目錄)
設計預覽
下圖是在設計軟體中的效果預覽:
可以看到設計感潮流感十足,簡潔大方,頁面上有大量的留白區域和明暗背景交錯,并有正常模式和友善夜間檢視的暗黑模式。
Dayu200暫時不能螢幕截圖,手機拍照精度太低;也為了預覽友善起見,
Dayu200的預覽配置
為了大幅提高UI的開發效率,降低Dayu200的使用門檻,在開發過程中,強烈建議使用DevEco Studio 3.0 Beta3(OpenHarmony)的MatePadPro作為預覽配置,并調整到橫屏模式,最終與Dayu200上的效果近似一緻。
資源導入
本案例為了簡單起見,文字與顔色直接寫在代碼中,僅圖檔資源需要導入(見附件meida.zip),将全部所需圖檔拖到資源檔案夾的media子目錄中:
啟動頁結構
使用預設的index.ets入口頁作為啟動頁,分析頁面的結構,可以分為上下兩個層:背景層、内容層。
内容層可分為導航、主題文字區、圖檔區。
頁面整體的骨架結構代碼可如下:
Stack {
Back() //背景層
Content() { //内容層
Nav() //導航
Theme() //主題文字區
Banner() //圖檔區
}
}
背景層
背景層效果看起來很不錯,仔細觀察設計,四個角都有镂空的圖形做襯托。其中左上角是一朵花,其餘三個角是呈輻射狀的星星,最底層是一個有着漸變流動光影效果的圖檔。要建立元件,依照慣例,在pages目錄下建立源碼檔案back.ets。
漸變流動光影
最底層是的圖檔特效非常獨特,直接插入圖檔元件。
Stack() {
Image($r("app.media.bg"))
}
.width('100%')
.height('100%')
在裝置的正常模式與暗黑模式下有不同的漸變流動光影效果,進而使得使用者對網站整體視覺上,似乎可以産生一股持續的如同文字主題想表達的,“溢彩生活”般的水波流動感。
圖形襯邊
頁面四角有圖形做襯托,首先是左上角的花枝:
Image($r("app.media.leaf"))
.width(274)
.height(345)
首先讓圖形略微向右旋轉傾斜:
Image($r("app.media.leaf"))
.width(274)
.height(345)
.objectFit(ImageFit.Contain)
.rotate({
z: 1,
angle: 5}
)
然後将至包含在一個Row容器中以便預設左對齊,在包含在一個Column中以便居于上方,這樣就讓圖形可以位于左上角。再适度讓左偏移:
Column() {
Row() {
Image($r("app.media.leaf"))
.width(274)
.height(345)
.objectFit(ImageFit.Contain)
.rotate({
z: 1,
angle: 5}
)
.offset({
x: -70}
)
}
.width('100%')
Blank()
}
.width('100%')
.height('100%')
此時發現圖檔本身的色彩過于飽滿,于是調整透明度為0.15:
Column() {
Row() {
Image($r("app.media.leaf"))
.width(274)
.height(345)
.objectFit(ImageFit.Contain)
.rotate({
z: 1,
angle: 5}
)
.offset({
x: -70}
)
}
.width('100%')
Blank()
}
.width('100%')
.height('100%')
.opacity(0.15)
如此一來,可以更好的融入背景色中。左下角的星形圖檔,參照做類似的處理:
Column() {
Blank()
Row() {
Image($r("app.media.star_l"))
.width(358)
.height(358)
.objectFit(ImageFit.Contain)
.offset({
x: -40}
)
}
.width('100%')
}
.width('100%')
.height('100%')
右上角的星形圖檔,也參照做類似的處理:
Column() {
Row() {
Blank()
Image($r("app.media.star_me"))
.width(358)
.height(358)
.objectFit(ImageFit.Contain)
.offset({
x: 20}
)
}
.width('100%')
Blank()
}
.width('100%')
.height('100%')
最後右下角的星形圖檔,同樣的處理:
Column() {
Blank()
Row() {
Blank()
Image($r("app.media.star_s"))
.width(246)
.height(246)
.objectFit(ImageFit.Contain)
.offset({
x: 20}
)
}
.width('100%')
}
.width('100%')
.height('100%')
完整代碼和效果
将四角的代碼組合起來,back.ets完整源代碼如下:
@Entry
@Component
export default struct Back {
build() {
Stack() {
Image($r("app.media.bg"))
Column() {
Row() {
Image($r("app.media.leaf"))
.width(274)
.height(345)
.objectFit(ImageFit.Contain)
.rotate({
z: 1,
angle: 5
})
.offset({
x: -70
})
}
.width('100%')
Blank()
}
.width('100%')
.height('100%')
.opacity(0.15)
Column() {
Blank()
Row() {
Image($r("app.media.star_l"))
.width(358)
.height(358)
.objectFit(ImageFit.Contain)
.offset({
x: -40
})
}
.width('100%')
}
.width('100%')
.height('100%')
Column() {
Row() {
Blank()
Image($r("app.media.star_me"))
.width(358)
.height(358)
.objectFit(ImageFit.Contain)
.offset({
x: 20
})
}
.width('100%')
Blank()
}
.width('100%')
.height('100%')
Column() {
Blank()
Row() {
Blank()
Image($r("app.media.star_s"))
.width(246)
.height(246)
.objectFit(ImageFit.Contain)
.offset({
x: 20
})
}
.width('100%')
}
.width('100%')
.height('100%')
}
.width('100%')
.height('100%')
}
}
預覽:
導航
内容層最上方是導航,而導航也分為三塊區域。要建立元件,依照慣例,在pages目錄下建立源碼檔案nav.ets。
大标題
大标題使用了細體,兩個詞的顔色是不一樣的,拆分成2個Text元件:
Row() {
Text('溢彩 ')
.fontSize(26)
.fontWeight(FontWeight.Lighter)
.fontColor('#932AE6')
Text('生活')
.fontSize(26)
.fontWeight(FontWeight.Lighter)
.fontColor('#FF6438')
}
導航菜單
菜單由4個Text組成,第一個顔色與其他有差別:
Row({space: 35}) {
Text('商店')
.fontSize(18)
.fontColor('#26273C')
.fontWeight(FontWeight.Lighter)
Text('爆品')
.fontSize(18)
.fontColor('#9094AC')
.fontWeight(FontWeight.Lighter)
Text('成分')
.fontSize(18)
.fontColor('#9094AC')
.fontWeight(FontWeight.Lighter)
Text('品牌')
.fontSize(18)
.fontColor('#9094AC')
.fontWeight(FontWeight.Lighter)
}
右側圖示組
右側有3個Image組成圖示組:
Row({space: 28}) {
Image($r("app.media.search"))
.width(46)
.height(46)
.objectFit(ImageFit.Contain)
Image($r("app.media.cart"))
.width(46)
.height(46)
.objectFit(ImageFit.Contain)
Image($r("app.media.avatar"))
.width(46)
.height(46)
.objectFit(ImageFit.Contain)
}
完整代碼和效果
把上述導航的子元件組合在一個Row,加上間隔以及上下左右的邊距,就可以形成一個完整的導航。
nav.ets完整代碼如下:
@Entry
@Component
export default struct Nav {
build() {
Row() {
Row() {
Text('溢彩 ')
.fontSize(23)
.fontWeight(FontWeight.Lighter)
.fontColor('#932AE6')
Text('生活')
.fontSize(23)
.fontWeight(FontWeight.Lighter)
.fontColor('#FF6438')
}
Blank()
Row({space: 35}) {
Text('商店')
.fontSize(14)
.fontColor('#26273C')
.fontWeight(FontWeight.Lighter)
Text('爆品')
.fontSize(14)
.fontColor('#9094AC')
.fontWeight(FontWeight.Lighter)
Text('成分')
.fontSize(14)
.fontColor('#9094AC')
.fontWeight(FontWeight.Lighter)
Text('品牌')
.fontSize(14)
.fontColor('#9094AC')
.fontWeight(FontWeight.Lighter)
}
Blank()
Row({space: 28}) {
Image($r("app.media.search"))
.width(40)
.height(40)
.objectFit(ImageFit.Contain)
Image($r("app.media.cart"))
.width(40)
.height(40)
.objectFit(ImageFit.Contain)
Image($r("app.media.avatar"))
.width(40)
.height(40)
.objectFit(ImageFit.Contain)
}
}
.width('100%')
.padding({
left: 145,
top: 20,
bottom: 0,
right: 50 }
)
}
}
主題文字區
這類文字比較多的區域,也可以根據字型大小來劃分出小塊。要建立元件,依照慣例,在pages目錄下建立源碼檔案theme.ets。
小标題
小标題可以使用Row來包含,以便預設左對齊。線段可以使用寬度很小的Row來填充背景色并加上圓角即可:
Row({space: 10}) {
Row()
.height(3)
.width(50)
.borderRadius(2)
.backgroundColor('#FF6438')
Text('純天然成分')
.fontSize(18)
.fontColor('#FF6438')
.fontWeight(FontWeight.Lighter)
}
大标題
大标題内3段文字按列(Column)布局,最後一段文字顔色有差異,以行(Row)來區分:
Text('讓生活')
.fontSize(50)
.fontColor('#26273C')
Text('處處')
.fontSize(50)
.fontColor('#26273C')
.fontWeight(FontWeight.Bold)
Row() {
Text('洋溢')
.fontSize(50)
.fontColor('#932AE6')
Text('彩色')
.fontSize(50)
.fontColor('#FF6438')
}
副标題
副标題的文字較多可能有換行,可在文字中使用換行符:
Text('守護你的美麗,我們别無所求,惟有提供\n最好的一切')
.fontSize(13)
.fontColor('#9094AC')
.fontWeight(FontWeight.Lighter)
按鈕組
2個按鈕在一行之内,第二個按鈕背景色是透明的:
Row({space: 40}) {
Button() {
Text('浏覽全部')
.fontSize(16)
.fontColor(Color.White)
.fontWeight(FontWeight.Lighter)
}
.width(150)
.height(55)
.type(ButtonType.Normal)
.borderRadius(8)
.backgroundColor('#FF6438')
Row() {
Blank()
Text('現在下單')
.fontSize(16)
.fontColor('#932AE6')
.fontWeight(FontWeight.Lighter)
Blank()
}
.width(150)
.height(55)
.borderWidth(1)
.borderColor('#932AE6')
.borderRadius(8)
}
.padding({top: 40})
完整代碼和預覽效果
将以上各個子元件和資料組合起來,theme.ets源檔案整個頁面的代碼:
@Entry
@Component
export default struct Theme {
build() {
Column() {
Row({space: 10}) {
Row()
.height(3)
.width(50)
.borderRadius(2)
.backgroundColor('#FF6438')
Text('純天然成分')
.fontSize(18)
.fontColor('#FF6438')
.fontWeight(FontWeight.Lighter)
}
Text('讓生活')
.fontSize(50)
.fontColor('#26273C')
Text('處處')
.fontSize(50)
.fontColor('#26273C')
.fontWeight(FontWeight.Bold)
Row() {
Text('洋溢')
.fontSize(50)
.fontColor('#932AE6')
Text('彩色')
.fontSize(50)
.fontColor('#FF6438')
}
Text('守護你的美麗,我們别無所求,惟有提供\n最好的一切')
.fontSize(13)
.fontColor('#9094AC')
.fontWeight(FontWeight.Lighter)
Row({space: 40}) {
Button() {
Text('浏覽全部')
.fontSize(14)
.fontColor(Color.White)
.fontWeight(FontWeight.Lighter)
}
.width(140)
.height(45)
.type(ButtonType.Normal)
.borderRadius(8)
.backgroundColor('#FF6438')
Row() {
Blank()
Text('現在下單')
.fontSize(14)
.fontColor('#932AE6')
.fontWeight(FontWeight.Lighter)
Blank()
}
.width(140)
.height(45)
.borderWidth(1)
.borderColor('#932AE6')
.borderRadius(8)
}
.padding({top: 40})
}
.alignItems(HorizontalAlign.Start)
.padding({
left:60,
top: 20
})
}
}
圖檔區
頁面中部右側是化妝品的圖檔集中展示。首先在pages目錄下建立banner.ets源檔案。
雙卡片組
卡片組由2個圖檔拼成一組,加上圓角:
Row() {
Image($r("app.media.bannner1"))
.width(267)
.height(274)
.objectFit(ImageFit.Contain)
.borderRadius(24)
.margin(right: 20)
Image($r("app.media.banner2"))
.width(267)
.height(274)
.objectFit(ImageFit.Contain)
.borderRadius(24)
}
.padding(20)
橫幅卡片
卡片組下方是一個相當于整個卡片組寬度的橫幅卡片:
Image($r("app.media.banner3"))
.width(555)
.height(274)
.objectFit(ImageFit.Contain)
.borderRadius(24)
完整元件源碼和預覽效果
将以上純元件和預覽用元件組合起來,banner.ets源檔案整個頁面的代碼:
@Entry
@Component
export default struct Banner {
build() {
Column() {
Row() {
Image($r("app.media.banner11"))
.width(210)
.height(222)
.objectFit(ImageFit.Contain)
.borderRadius(24)
.margin({right: 20})
Image($r("app.media.banner22"))
.width(210)
.height(222)
.objectFit(ImageFit.Contain)
.borderRadius(24)
}
.padding(20)
Image($r("app.media.bannerl3"))
.width(440)
.height(222)
.objectFit(ImageFit.Contain)
.borderRadius(24)
}
}
}
切換圖檔區的圖檔名稱,以及檢視在暗黑模式下的效果:
評價浮層
在圖檔區左下有一個使用者評價的浮層。在pages目錄下建立comment.ets源檔案。
評價卡片
評價卡片包含文字和評分圖檔,其中評分圖檔使用ForEach進行循環渲染5次:
Column() {
Text('小周')
.fontSize(16)
.fontColor('#26273C')
.fontWeight(FontWeight.Bold)
Text('最好用的套裝之一')
.fontSize(14)
.fontColor('#585C77')
.fontWeight(FontWeight.Lighter)
Row(space: 8) {
ForEach([1,2,3,4,5], () => {
Image($r("app.media.star_cmt"))
.width(15)
.height(15)
.objectFit(ImageFit.Contain)
})
}
.padding({top: 10})
}
.alignItems(HorizontalAlign.Start)
.width(263)
.height(111)
.shadow({
radius:15,
color: '#F8F9FC'}
)
.backgroundColor(Color.White)
.padding(20)
.margin(20)
.borderRadius(18)
因為卡片背景是白色,在正常模式下無法看到邊界,切換到暗黑模式下進行預覽:
評價頭像
評價圖檔周圍有邊框,Image本身并不支援這樣的邊框,可以包裝在Column容器中賦予均等的内邊距即可:
Column() {
Image($r("app.media.avatar_2"))
.width(56)
.height(56)
.borderRadius(8)
}
.backgroundColor('#C4C4C4')
.padding(5)
.borderRadius(8)
完整源碼和預覽效果
将以上卡片和頭像組合起來,再講頭像的位置做一定程度的向左上偏移,comment.ets源檔案整個頁面的代碼:
@Entry
@Component
export default struct Comment {
build() {
Stack() {
Column() {
Text('小周')
.fontSize(16)
.fontColor('#26273C')
.fontWeight(FontWeight.Bold)
Text('最好用的套裝之一')
.fontSize(14)
.fontColor('#585C77')
.fontWeight(FontWeight.Lighter)
Row({space: 8}) {
ForEach([1,2,3,4,5], () => {
Image($r("app.media.star_cmt"))
.width(15)
.height(15)
.objectFit(ImageFit.Contain)
})
}
.padding({top: 10})
}
.alignItems(HorizontalAlign.Start)
.width(263)
.height(111)
.shadow({
radius:15,
color: '#F8F9FC'
})
.backgroundColor(Color.White)
.padding({left: 70,top: 20})
.margin(20)
.borderRadius(18)
Row() {
Column() {
Image($r("app.media.avatar_2"))
.width(56)
.height(56)
.borderRadius(8)
}
.backgroundColor('#C4C4C4')
.padding(5)
.borderRadius(8)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.offset({
y: -30
})
}
.padding(20)
}
}
首頁的調整優化
将以上元件完整組合在一個Stack内,index.ets代碼如下:
Stack() {
Back()
Column() {
Nav()
Row() {
Theme()
Banner()
}
}
}
.width('100%')
.height('100%')
看起來導航、主題文字區、圖檔組都偏大,需要針對性調整。
各子元件的調整,不再贅述,請同學們自行調整。
首頁調整
把首頁進行相應尺寸調整,另外加上評價浮層及偏移,index.ets代碼如下:
import Back from './back.ets'
import Nav from './nav.ets'
import Theme from './theme.ets'
import Banner from './banner.ets'
import Comment from './comment.ets'
@Entry
@Component
struct Index {
build() {
Stack() {
Back()
Column() {
Nav()
Row() {
Theme()
Banner()
}
}
.height('100%')
Column() {
Blank()
Comment()
}
.height('100%')
.offset({
x: 100
})
}
.width('100%')
.height('100%')
}
}
預覽效果
調整優化後的首頁預覽:
暗黑模式下的效果如下:
您可以根據本帖開始的設計效果,自行更改适配的字型顔色。
總結
Dayu200不僅适合裝置開發,更适合App開發,配合最新的DevEco Studio 3.0,即使您手頭沒有裝置,也可以進行相對完善的UI開發大部分工作。
附件連結:
完整源碼(https://ost.51cto.com/resource/2148)
Dayu200案例(https://ost.51cto.com/resource/2140)