#DAYU200体验官# 溢彩美妆App 原创 精华
本帖使用Dayu200为开发板,展示一个化妆品在线商店的App首页:溢彩美妆App。
注意:本文不涉及App上的用户互动,仅为页面设计效果的实现。
@toc
设计预览
下图是在设计软件中的效果预览:
可以看到设计感潮流感十足,简洁大方,页面上有大量的留白区域和明暗背景交错,并有正常模式和方便夜间查看的暗黑模式。
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开发大部分工作。
老师这Dayu200玩的也太6了
当体验官了,那是必须滴