完成首页和我的页面的内容和样式结构

This commit is contained in:
2026-05-08 16:46:15 +08:00
parent f869743ff4
commit c9c1092702
7 changed files with 697 additions and 38 deletions

View File

@@ -1,15 +1,299 @@
@Component
export struct HomeContent {
@State todayCount: number = 23;
@State accuracy: number = 78;
@State studyMinutes: number = 35;
build() {
Column() {
Text('首页')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor('#333333')
Scroll() {
Column() {
// 顶部问候
Row() {
Column() {
Text('Hi今天也要加油呀')
.fontSize(22)
.fontWeight(FontWeight.Bold)
.fontColor($r('app.color.text_primary'))
Text('每日一练,进步看得见')
.fontSize(13)
.fontColor($r('app.color.text_hint'))
.margin({ top: 4 })
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
Row({ space: 16 }) {
Text('○')
.fontSize(22)
.fontColor($r('app.color.text_primary'))
Text('○')
.fontSize(22)
.fontColor($r('app.color.text_primary'))
}
}
.width('100%')
.padding({ top: 16, bottom: 12 })
// 今日统计卡片
Column() {
Text('今日已练习')
.fontSize(13)
.fontColor('rgba(255,255,255,0.8)')
Row() {
Text(this.todayCount.toString())
.fontSize(48)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
Text(' 题')
.fontSize(16)
.fontColor('rgba(255,255,255,0.8)')
.margin({ bottom: 8 })
}
.alignItems(VerticalAlign.Bottom)
Row() {
Column() {
Text('正确率')
.fontSize(12)
.fontColor('rgba(255,255,255,0.7)')
Text(this.accuracy + '%')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.margin({ top: 2 })
}
Column() {
Text('学习时长')
.fontSize(12)
.fontColor('rgba(255,255,255,0.7)')
Text(this.studyMinutes + ' min')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.margin({ top: 2 })
}
.margin({ left: 48 })
}
.width('100%')
.margin({ top: 8 })
}
.width('100%')
.padding(20)
.borderRadius(16)
.linearGradient({
angle: 135,
colors: [['#4E6EF2', 0], ['#7B9CFF', 1]]
})
.alignItems(HorizontalAlign.Start)
// 快捷入口(白色背景+阴影)
Row() {
this.QuickAction('题库分类', '#4E6EF2')
this.QuickAction('随机练习', '#FF7043')
this.QuickAction('错题本', '#26C6DA')
this.QuickAction('收藏夹', '#AB47BC')
}
.width('100%')
.justifyContent(FlexAlign.SpaceEvenly)
.padding({ top: 20, bottom: 20 })
.backgroundColor($r('app.color.card_background'))
.borderRadius(12)
.shadow({ radius: 8, color: $r('app.color.shadow_color'), offsetX: 0, offsetY: 2 })
.margin({ top: 16 })
// 推荐练习
this.SectionHeader('推荐练习', '查看全部')
Column({ space: 12 }) {
this.TopicItem('数据结构与算法', 1200, 3580, '#4E6EF2')
this.TopicItem('操作系统', 890, 2150, '#26C6DA')
this.TopicItem('计算机网络', 560, 1890, '#FF7043')
this.TopicItem('数据库系统', 430, 1520, '#AB47BC')
}
.width('100%')
// 每日一练
this.SectionHeader('每日一练', '')
Row() {
Column() {
Text('5月')
.fontSize(11)
.fontColor($r('app.color.text_hint'))
Text('20')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor($r('app.color.text_primary'))
}
.width(56)
.height(64)
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.borderRadius(12)
.backgroundColor($r('app.color.input_background'))
Column() {
Text('每日一练 05.20')
.fontSize(15)
.fontWeight(FontWeight.Medium)
.fontColor($r('app.color.text_primary'))
Text('每天5题积少成多')
.fontSize(12)
.fontColor($r('app.color.text_hint'))
.margin({ top: 4 })
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
.margin({ left: 12 })
Button('去练习')
.fontSize(13)
.fontColor(Color.White)
.backgroundColor($r('app.color.primary_color'))
.borderRadius(16)
.height(32)
}
.width('100%')
.padding(16)
.backgroundColor($r('app.color.card_background'))
.borderRadius(12)
// 近期练习
this.SectionHeader('近期练习', '查看全部')
Column() {
Row() {
Column() {
Text('数组与链表')
.fontSize(15)
.fontWeight(FontWeight.Medium)
.fontColor($r('app.color.text_primary'))
Text('2024-05-20 09:30')
.fontSize(12)
.fontColor($r('app.color.text_hint'))
.margin({ top: 4 })
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
Row() {
Text('18/20')
.fontSize(13)
.fontColor($r('app.color.text_secondary'))
Text(' 正确率 ')
.fontSize(12)
.fontColor($r('app.color.text_hint'))
Text('90%')
.fontSize(14)
.fontWeight(FontWeight.Medium)
.fontColor($r('app.color.primary_color'))
}
}
.width('100%')
}
.width('100%')
.padding(16)
.backgroundColor($r('app.color.card_background'))
.borderRadius(12)
.margin({ bottom: 16 })
}
.width('100%')
.padding({ left: 16, right: 16 })
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.backgroundColor($r('app.color.page_background'))
.scrollBar(BarState.Off)
}
@Builder
QuickAction(title: string, color: string) {
Column() {
Row() {
Text('○')
.fontSize(20)
.fontColor(Color.White)
}
.width(48)
.height(48)
.justifyContent(FlexAlign.Center)
.borderRadius(12)
.backgroundColor(color)
Text(title)
.fontSize(12)
.fontColor($r('app.color.text_secondary'))
.margin({ top: 8 })
}
.alignItems(HorizontalAlign.Center)
}
@Builder
SectionHeader(title: string, action: string) {
Row() {
Text(title)
.fontSize(17)
.fontWeight(FontWeight.Bold)
.fontColor($r('app.color.text_primary'))
Blank()
if (action.length > 0) {
Text(action + ' >')
.fontSize(13)
.fontColor($r('app.color.text_hint'))
}
}
.width('100%')
.padding({ top: 20, bottom: 12 })
}
@Builder
TopicItem(name: string, done: number, total: number, color: string) {
Row() {
Row() {
Text('○')
.fontSize(18)
.fontColor(Color.White)
}
.width(44)
.height(44)
.justifyContent(FlexAlign.Center)
.borderRadius(22)
.backgroundColor(color)
Column() {
Text(name)
.fontSize(15)
.fontWeight(FontWeight.Medium)
.fontColor($r('app.color.text_primary'))
Text(done + '/' + total + ' 题')
.fontSize(12)
.fontColor($r('app.color.text_hint'))
.margin({ top: 4 })
// 进度条
Stack({ alignContent: Alignment.Start }) {
Row()
.width('100%')
.height(4)
.borderRadius(2)
.backgroundColor($r('app.color.progress_background'))
Row()
.width((done / total * 100) + '%')
.height(4)
.borderRadius(2)
.backgroundColor(color)
}
.width('100%')
.margin({ top: 6 })
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
.margin({ left: 12 })
Text('>')
.fontSize(16)
.fontColor($r('app.color.tab_inactive'))
}
.width('100%')
.padding(14)
.backgroundColor($r('app.color.card_background'))
.borderRadius(12)
}
}

View File

@@ -1,15 +1,302 @@
import { ConfigurationConstant } from '@kit.AbilityKit';
import { common } from '@kit.AbilityKit';
@Component
export struct MineContent {
@State isDarkMode: boolean = false;
aboutToAppear(): void {
const context = getContext(this) as common.UIAbilityContext;
const colorMode = context.config.colorMode;
this.isDarkMode = colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
}
private toggleDarkMode(): void {
const context = getContext(this) as common.UIAbilityContext;
this.isDarkMode = !this.isDarkMode;
const mode = this.isDarkMode
? ConfigurationConstant.ColorMode.COLOR_MODE_DARK
: ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT;
context.getApplicationContext().setColorMode(mode);
}
build() {
Column() {
Text('我的')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor('#333333')
Scroll() {
Column() {
// 区域1用户信息卡片深蓝背景圆角
Column() {
// 设置/客服按钮
Row() {
Blank()
Row({ space: 20 }) {
Text('○')
.fontSize(20)
.fontColor('rgba(255,255,255,0.8)')
Text('○')
.fontSize(20)
.fontColor('rgba(255,255,255,0.8)')
}
}
.width('100%')
.padding({ left: 20, right: 20, top: 12 })
// 头像 + 用户名
Row() {
Row() {
Text('A')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
}
.width(64)
.height(64)
.justifyContent(FlexAlign.Center)
.borderRadius(32)
.backgroundColor('#7B9CFF')
Column() {
Row() {
Text('刷题小能手')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
Text('Lv.4')
.fontSize(11)
.fontColor(Color.White)
.backgroundColor('#FFB74D')
.borderRadius(8)
.padding({ left: 6, right: 6, top: 2, bottom: 2 })
.margin({ left: 8 })
}
.alignItems(VerticalAlign.Center)
Text('少壮不努力,刷题要学霸!')
.fontSize(13)
.fontColor('rgba(255,255,255,0.7)')
.margin({ top: 6 })
}
.alignItems(HorizontalAlign.Start)
.margin({ left: 16 })
}
.width('100%')
.padding({ left: 20, right: 20, top: 16, bottom: 20 })
}
.width('100%')
.borderRadius({ bottomLeft: 16, bottomRight: 16 })
.linearGradient({
angle: 180,
colors: [['#3D5AAF', 0], ['#4E6EF2', 1]]
})
// 区域2统计数据卡片白底独立卡片
Row() {
this.StatItem('128', '连续打卡(天)', '#4E6EF2')
this.StatItem('3568', '做题总数(道)', '#333333')
this.StatItem('78%', '正确率', '#4E6EF2')
}
.width('100%')
.justifyContent(FlexAlign.SpaceEvenly)
.padding({ top: 20, bottom: 20 })
.backgroundColor($r('app.color.card_background'))
.borderRadius(12)
.margin({ left: 16, right: 16, top: 12 })
// 内容区域
Column() {
// VIP 卡片
Row() {
Row() {
Text('V')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#FFB74D')
}
.width(36)
.height(36)
.justifyContent(FlexAlign.Center)
.borderRadius(18)
.backgroundColor('#FFF3E0')
Column() {
Text('VIP 会员')
.fontSize(15)
.fontWeight(FontWeight.Medium)
.fontColor($r('app.color.text_primary'))
Text('享受更多专属权益')
.fontSize(12)
.fontColor($r('app.color.text_hint'))
.margin({ top: 2 })
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
.margin({ left: 12 })
Button('去开通')
.fontSize(13)
.fontColor(Color.White)
.backgroundColor('#FFB74D')
.borderRadius(16)
.height(32)
}
.width('100%')
.padding(16)
.backgroundColor($r('app.color.card_background'))
.borderRadius(12)
// 我的工具
Column() {
Text('我的工具')
.fontSize(17)
.fontWeight(FontWeight.Bold)
.fontColor($r('app.color.text_primary'))
.margin({ bottom: 16 })
// 第一行
Row() {
this.ToolItem('错题本')
this.ToolItem('收藏夹')
this.ToolItem('笔记')
this.ToolItem('练习记录')
}
.width('100%')
.justifyContent(FlexAlign.SpaceEvenly)
// 第二行
Row() {
this.ToolItem('学习计划')
this.ToolItem('数约分享')
this.ToolItem('题目反馈')
this.DarkModeItem()
}
.width('100%')
.justifyContent(FlexAlign.SpaceEvenly)
.margin({ top: 20 })
}
.width('100%')
.padding(16)
.backgroundColor($r('app.color.card_background'))
.borderRadius(12)
.margin({ top: 12 })
// 更多服务
Column() {
Text('更多服务')
.fontSize(17)
.fontWeight(FontWeight.Bold)
.fontColor($r('app.color.text_primary'))
.margin({ bottom: 8 })
this.ServiceItem('消息通知')
this.ServiceItem('帮助与反馈')
this.ServiceItem('关于我们')
this.ServiceItem('设置')
}
.width('100%')
.padding(16)
.backgroundColor($r('app.color.card_background'))
.borderRadius(12)
.margin({ top: 12 })
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.padding({ left: 16, right: 16, top: 16, bottom: 16 })
}
.width('100%')
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.backgroundColor($r('app.color.page_background'))
.scrollBar(BarState.Off)
}
@Builder
StatItem(value: string, label: string, valueColor: string) {
Column() {
Text(value)
.fontSize(22)
.fontWeight(FontWeight.Bold)
.fontColor(valueColor)
Text(label)
.fontSize(11)
.fontColor($r('app.color.text_hint'))
.margin({ top: 4 })
}
.alignItems(HorizontalAlign.Center)
}
@Builder
ToolItem(title: string) {
Column() {
Row() {
Text('○')
.fontSize(18)
.fontColor($r('app.color.primary_color'))
}
.width(44)
.height(44)
.justifyContent(FlexAlign.Center)
.borderRadius(12)
.backgroundColor($r('app.color.input_background'))
Text(title)
.fontSize(12)
.fontColor($r('app.color.text_secondary'))
.margin({ top: 8 })
}
.alignItems(HorizontalAlign.Center)
.width('25%')
}
@Builder
DarkModeItem() {
Column() {
Row() {
Text(this.isDarkMode ? '●' : '○')
.fontSize(18)
.fontColor($r('app.color.primary_color'))
}
.width(44)
.height(44)
.justifyContent(FlexAlign.Center)
.borderRadius(12)
.backgroundColor($r('app.color.input_background'))
.onClick(() => {
this.toggleDarkMode();
})
Text('夜间模式')
.fontSize(12)
.fontColor($r('app.color.text_secondary'))
.margin({ top: 8 })
}
.alignItems(HorizontalAlign.Center)
.width('25%')
}
@Builder
ServiceItem(title: string) {
Row() {
Row() {
Text('○')
.fontSize(14)
.fontColor($r('app.color.text_secondary'))
}
.width(28)
.height(28)
.justifyContent(FlexAlign.Center)
Text(title)
.fontSize(15)
.fontColor($r('app.color.text_primary'))
.margin({ left: 8 })
.layoutWeight(1)
Text('>')
.fontSize(14)
.fontColor($r('app.color.tab_inactive'))
}
.width('100%')
.height(48)
.alignItems(VerticalAlign.Center)
}
}

View File

@@ -36,7 +36,7 @@ struct HomePage {
})
.width('100%')
.height('100%')
.backgroundColor('#F5F6F7')
.backgroundColor($r('app.color.page_background'))
}
@Builder
@@ -46,7 +46,7 @@ struct HomePage {
.fontSize(22)
Text(title)
.fontSize(12)
.fontColor(this.currentIndex === index ? '#4E6EF2' : '#999999')
.fontColor(this.currentIndex === index ? $r('app.color.primary_color') : $r('app.color.tab_inactive'))
.fontWeight(this.currentIndex === index ? FontWeight.Medium : FontWeight.Normal)
.margin({ top: 2 })
}

View File

@@ -18,11 +18,11 @@ struct LoginPage {
Text('刷什么')
.fontSize(36)
.fontWeight(FontWeight.Bold)
.fontColor('#4E6EF2')
.fontColor($r('app.color.primary_color'))
Text('每日一练,轻松备考')
.fontSize(14)
.fontColor('#999999')
.fontColor($r('app.color.text_hint'))
.margin({ top: 8 })
}
.margin({ bottom: 48 })
@@ -33,13 +33,13 @@ struct LoginPage {
Column() {
Text('账号')
.fontSize(14)
.fontColor('#333333')
.fontColor($r('app.color.text_primary'))
.margin({ bottom: 8 })
TextInput({ placeholder: '请输入手机号/邮箱', text: this.username })
.height(48)
.fontSize(16)
.backgroundColor('#F5F6F7')
.backgroundColor($r('app.color.input_background'))
.borderRadius(8)
.padding({ left: 16, right: 16 })
.onChange((value: string) => {
@@ -53,13 +53,13 @@ struct LoginPage {
Column() {
Text('密码')
.fontSize(14)
.fontColor('#333333')
.fontColor($r('app.color.text_primary'))
.margin({ bottom: 8 })
TextInput({ placeholder: '请输入密码', text: this.password })
.height(48)
.fontSize(16)
.backgroundColor('#F5F6F7')
.backgroundColor($r('app.color.input_background'))
.borderRadius(8)
.padding({ left: 16, right: 16 })
.type(InputType.Password)
@@ -76,7 +76,7 @@ struct LoginPage {
Blank()
Text('忘记密码?')
.fontSize(13)
.fontColor('#4E6EF2')
.fontColor($r('app.color.primary_color'))
.onClick(() => {
// TODO: 跳转忘记密码页面
})
@@ -90,7 +90,7 @@ struct LoginPage {
.height(48)
.fontSize(16)
.fontColor(Color.White)
.backgroundColor('#4E6EF2')
.backgroundColor($r('app.color.primary_color'))
.borderRadius(24)
.margin({ top: 32 })
.enabled(!this.isLoading && this.username.length > 0 && this.password.length > 0)
@@ -103,10 +103,10 @@ struct LoginPage {
Row() {
Text('还没有账号?')
.fontSize(14)
.fontColor('#999999')
.fontColor($r('app.color.text_hint'))
Text('立即注册')
.fontSize(14)
.fontColor('#4E6EF2')
.fontColor($r('app.color.primary_color'))
.fontWeight(FontWeight.Medium)
.onClick(() => {
router.pushUrl({ url: 'pages/RegisterPage' });
@@ -122,7 +122,7 @@ struct LoginPage {
}
.width('100%')
.height('100%')
.backgroundColor(Color.White)
.backgroundColor($r('app.color.card_background'))
}
private handleLogin(): void {

View File

@@ -14,7 +14,7 @@ struct RegisterPage {
Row() {
Text('←')
.fontSize(24)
.fontColor('#333333')
.fontColor($r('app.color.text_primary'))
.onClick(() => {
router.back();
})
@@ -22,7 +22,7 @@ struct RegisterPage {
Text('注册账号')
.fontSize(18)
.fontWeight(FontWeight.Medium)
.fontColor('#333333')
.fontColor($r('app.color.text_primary'))
.layoutWeight(1)
.textAlign(TextAlign.Center)
@@ -42,13 +42,13 @@ struct RegisterPage {
Column() {
Text('账号')
.fontSize(14)
.fontColor('#333333')
.fontColor($r('app.color.text_primary'))
.margin({ bottom: 8 })
TextInput({ placeholder: '请输入手机号/邮箱', text: this.username })
.height(48)
.fontSize(16)
.backgroundColor('#F5F6F7')
.backgroundColor($r('app.color.input_background'))
.borderRadius(8)
.padding({ left: 16, right: 16 })
.onChange((value: string) => {
@@ -62,13 +62,13 @@ struct RegisterPage {
Column() {
Text('密码')
.fontSize(14)
.fontColor('#333333')
.fontColor($r('app.color.text_primary'))
.margin({ bottom: 8 })
TextInput({ placeholder: '请输入密码至少6位', text: this.password })
.height(48)
.fontSize(16)
.backgroundColor('#F5F6F7')
.backgroundColor($r('app.color.input_background'))
.borderRadius(8)
.padding({ left: 16, right: 16 })
.type(InputType.Password)
@@ -84,13 +84,13 @@ struct RegisterPage {
Column() {
Text('确认密码')
.fontSize(14)
.fontColor('#333333')
.fontColor($r('app.color.text_primary'))
.margin({ bottom: 8 })
TextInput({ placeholder: '请再次输入密码', text: this.confirmPassword })
.height(48)
.fontSize(16)
.backgroundColor('#F5F6F7')
.backgroundColor($r('app.color.input_background'))
.borderRadius(8)
.padding({ left: 16, right: 16 })
.type(InputType.Password)
@@ -116,7 +116,7 @@ struct RegisterPage {
.height(48)
.fontSize(16)
.fontColor(Color.White)
.backgroundColor('#4E6EF2')
.backgroundColor($r('app.color.primary_color'))
.borderRadius(24)
.margin({ top: 36 })
.enabled(!this.isLoading && this.isFormValid())
@@ -129,10 +129,10 @@ struct RegisterPage {
Row() {
Text('已有账号?')
.fontSize(14)
.fontColor('#999999')
.fontColor($r('app.color.text_hint'))
Text('返回登录')
.fontSize(14)
.fontColor('#4E6EF2')
.fontColor($r('app.color.primary_color'))
.fontWeight(FontWeight.Medium)
.onClick(() => {
router.back();
@@ -148,7 +148,7 @@ struct RegisterPage {
}
.width('100%')
.height('100%')
.backgroundColor(Color.White)
.backgroundColor($r('app.color.card_background'))
}
private isFormValid(): boolean {

View File

@@ -3,6 +3,50 @@
{
"name": "start_window_background",
"value": "#FFFFFF"
},
{
"name": "page_background",
"value": "#F5F6F7"
},
{
"name": "card_background",
"value": "#FFFFFF"
},
{
"name": "text_primary",
"value": "#333333"
},
{
"name": "text_secondary",
"value": "#666666"
},
{
"name": "text_hint",
"value": "#999999"
},
{
"name": "primary_color",
"value": "#4E6EF2"
},
{
"name": "input_background",
"value": "#F5F6F7"
},
{
"name": "divider_color",
"value": "#F0F0F0"
},
{
"name": "tab_inactive",
"value": "#999999"
},
{
"name": "shadow_color",
"value": "#0F000000"
},
{
"name": "progress_background",
"value": "#F0F0F0"
}
]
}

View File

@@ -2,7 +2,51 @@
"color": [
{
"name": "start_window_background",
"value": "#000000"
"value": "#1A1A1A"
},
{
"name": "page_background",
"value": "#1A1A1A"
},
{
"name": "card_background",
"value": "#2C2C2C"
},
{
"name": "text_primary",
"value": "#E0E0E0"
},
{
"name": "text_secondary",
"value": "#AAAAAA"
},
{
"name": "text_hint",
"value": "#777777"
},
{
"name": "primary_color",
"value": "#6B8AFF"
},
{
"name": "input_background",
"value": "#3A3A3A"
},
{
"name": "divider_color",
"value": "#3A3A3A"
},
{
"name": "tab_inactive",
"value": "#777777"
},
{
"name": "shadow_color",
"value": "#00000000"
},
{
"name": "progress_background",
"value": "#3A3A3A"
}
]
}