獲取成就
本節將介紹成就頁面。
功能概述
成就頁面展示用戶可以獲取的所有勛章,當用戶滿足一定的條件時,將點亮本頁面對應的勛章,沒有得到的成就勛章處于熄滅狀態。共有六種勛章,當用戶連續完成任務打卡3天、7天、30天、50天、73天、99天時,可以獲得對應的“連續xx天達成”勛章。
頁面布局與 ArkTS 代碼對應關系
效果如圖所示:
標題部分TitleBar是一個橫向容器Row里包含一個子組件Text。
開發前請熟悉鴻蒙開發指導文檔:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
點擊或者復制轉到。
// TitleBarComponent.ets
@Component
export struct TitleBar {build() {Row() {Text($r('app.string.achievement')).fontSize($r('app.float.default_24')).fontColor($r('app.color.white')).align(Alignment.Start).padding({left: Const.ACHIEVE_TITLE_BAR_LEFT,top: Const.ACHIEVE_TITLE_BAR_TOP})}.width(Const.FULL_WIDTH)}
}
每個勛章卡片BadgeCard是由一個豎向容器Column、一個圖片子組件Image和一個文字子組件Text組成。
// BadgeCardComponent.ets
@Component
export struct BadgeCard {@Prop content: string = '';imgSrc: Resource = $r('app.string.empty');build() {Column({space: Const.DEFAULT_18}) {Image(this.imgSrc).width(Const.FULL_WIDTH).height(Const.ACHIEVE_CARD_IMG_HEIGHT).objectFit(ImageFit.Contain)Text($r('app.string.task_achievement_level', Number(this.content))).lineHeight($r('app.float.default_16')).fontSize($r('app.float.default_12')).fontColor($r('app.color.white'))}.width(ratio2percent(Const.ACHIEVE_SPLIT_RATIO)).padding({top: Const.ACHIEVE_CARD_TOP, bottom: Const.ACHIEVE_CARD_BOTTOM})}
}
整體的勛章面板使用Flex一個組件即可以實現均分和換行的功能。
// BadgePanelComponent.ets
@Component
export struct BadgePanel {@StorageProp(ACHIEVEMENT_LEVEL_KEY) successiveDays: number = 0;aboutToAppear() {Logger.debug('BadgePanel','aboutToAppear');getAchievementLevel();}build() {Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap }) {ForEach(getBadgeCardItems(this.successiveDays), (item: CardInfo) => {BadgeCard({ content: item.titleContent, imgSrc: item.achievement})})}.width(Const.FULL_WIDTH)}
}`HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿`
獲取數據
進入界面第一次獲取數據在aboutToAppear()聲明周期中從數據庫GlobalInfo表中獲取存儲的勛章數據, 通過@StorageProp裝飾器刷新界面,其他的地方只要通過AppStorage更新勛章數據即可。
// BadgePanelComponent.ets
aboutToAppear() {Logger.debug('BadgePanel','aboutToAppear');getAchievementLevel();
}// AchieveModel.ets
export function getAchievementLevel() {GlobalInfoApi.query((res: GlobalInfo) => {let globalInfo: GlobalInfo = res;let achievementStr = globalInfo.achievements??'';let achievements = achievementStr.split(',');if (achievements.length > 0) {AppStorage.Set<Number>(ACHIEVEMENT_LEVEL_KEY, Number(achievements[achievements.length - 1]));}})
}// BadgePanelComponent.ets
@StorageProp(ACHIEVEMENT_LEVEL_KEY) successiveDays: number = 0;ForEach(getBadgeCardItems(this.successiveDays), (item: CardInfo) => {BadgeCard({ content: item.titleContent, imgSrc: item.achievement})
})// AchievementViewModel.ets
export function getBadgeCardItems(successiveDays: number): Array<CardInfo> {let badgeMileStones = ACHIEVEMENT_LEVEL_LIST;let cardItems: Array<CardInfo> = [];for (let i = 0; i < badgeMileStones.length; i++) {let onOrOff = successiveDays >= badgeMileStones[i] ? 'on' : 'off';let titleContent = String(badgeMileStones[i]);let cardInfo: CardInfo = new CardInfo();cardInfo.titleContent = titleContent;cardInfo.achievement = getAchievement(`${ onOrOff }_${ badgeMileStones[i] }`);cardItems.push(cardInfo);}return cardItems;
}