当前位置:   article > 正文

【鸿蒙】鸿蒙App应用-《记账软件》开发步骤_鸿蒙记账软件开发

鸿蒙记账软件开发

1. 介绍

《记账软件》是日常生活中每天都要使用的软件,通过软件来统计和规划每天的收入和支出情况,并根据日,周,月,年的数据进行生成图表,折线图,柱状图等等,并对消费情况进行分析给出合理的规划策略。

实现思路:

  1. 创建Java语言的项目,完成欢迎引导页滑动页面
  2. 创建登录页面,注册页面,找回密码页面
  3. 创建主界面,包含明细,图表,记账,发现,我的五大模块
  4. 明细模块:展示每天的收入支出情况,并可以根据月份统计本月,本日的收入支出的总和等功能
  5. 图表模块:根据收入支出情况生成日,周,月,年的折线图,饼状图,折线图等等,并对各种支出情况分类显示支出金额
  6. 记账模块:对消费的情况按不同分类进行记账,例如水果,公交,餐饮,工资等等
  7. 发现模块:这里接入web端的网站展示在移动端中
  8. 我的模块:对用户个人信息的设置和显示,头像,VIP设置,主题设置,提醒等等功能

2. 搭建HarmonyOS环境

我们首先需要完成HarmonyOS开发环境搭建,可参照如下步骤进行。

  • 安装DevEco Studio,详情请参考下载和安装软件
  • 设置DevEco Studio开发环境,DevEco Studio开发环境依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:
    1. 如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。
    2. 如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境

3. 搭建项目开发架构

鸿蒙系统项目中,一个项目只会存在一个Application类作为管理整个软件的应用程序。因此我们使用该类进行管理所打开的所有Ability页面,在开启一个新的页面,或者关闭一个页面的同时,我们更好的对页面的状态以及生命周期进行监听。代码如下:

  1. package com.example.bookkeepproject;
  2. import ohos.aafwk.ability.Ability;
  3. import ohos.aafwk.ability.AbilityPackage;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. /**
  7. * 主应用程序类,一个应用只有一个应用程序类
  8. */
  9. public class MyApplication extends AbilityPackage {
  10. private static List<Ability> abilities;
  11. @Override
  12. public void onInitialize() {
  13. super.onInitialize();
  14. abilities=new ArrayList<>();
  15. }
  16. /**
  17. * 将开启的界面添加至界面集合
  18. * @param ability
  19. */
  20. public void addAbility(Ability ability) {
  21. if (!abilities.contains(ability)) {
  22. abilities.add(ability);
  23. }
  24. }
  25. /**
  26. * 销毁所有的界面对象
  27. */
  28. public void removeAllAbility() {
  29. for (Ability activity : abilities) {
  30. activity.terminateAbility();
  31. }
  32. }
  33. }

在应用程序类中,定义一个ability集合,创建两个方法,用于监听新的ability界面的开启和关闭。

4.创建Ability类的基类

为了更好的统一管理所有的ability,我们建立BaseAbility(基类)继承至Ability类,那么我们所有的Ability都继承至我们自己的基类,在基类中可以定义封装常用的方法,方便调用,减少耦合度,避免代码冗余。代码如下:

  1. package com.example.bookkeepproject;
  2. import ohos.aafwk.ability.Ability;
  3. import ohos.aafwk.content.Intent;
  4. /**
  5. * 界面基类
  6. */
  7. public class BaseAbility extends Ability {
  8. MyApplication application;
  9. BaseAbility context;
  10. @Override
  11. protected void onStart(Intent intent) {
  12. super.onStart(intent);
  13. // 单例模式
  14. if (application == null) {
  15. application = (MyApplication) getAbilityPackage();
  16. }
  17. context = this;
  18. addAbility();
  19. }
  20. @Override
  21. protected void onStop() {
  22. super.onStop();
  23. }
  24. public void addAbility() {
  25. application.addAbility(context);
  26. }
  27. public void removeAllActivity() {
  28. application.removeAllAbility();
  29. }
  30. }

并改变MainAbility类继承至BaseAbility类,完成统一所有Ability的管理,统一监听其生命周期过程。

5.创建AbilitySlice基类

在鸿蒙的学习中,大家知道一个Ability可以管理包含多个AbilitySlice类,这里为了能更好的管理多个AbilitySlice类,我们也建立AbilitySlice的基类。

  1. package com.example.bookkeepproject.slice;
  2. import com.example.bookkeepproject.MainAbility;
  3. import com.example.bookkeepproject.utils.MyHelper;
  4. import ohos.aafwk.ability.AbilitySlice;
  5. import ohos.aafwk.content.Intent;
  6. import ohos.agp.window.dialog.ToastDialog;
  7. import ohos.data.rdb.RdbStore;
  8. import java.text.SimpleDateFormat;
  9. import java.util.Calendar;
  10. /**
  11. * 子界面的基类
  12. */
  13. public class BaseAbilitySlice extends AbilitySlice {
  14. MainAbility ability;
  15. BaseAbilitySlice context;
  16. RdbStore rs;
  17. // Preferences preferences;
  18. public Calendar calendar = null;
  19. public int year=Calendar.getInstance().get(Calendar.YEAR);
  20. public int month=Calendar.getInstance().get(Calendar.MONTH)+1;
  21. public int day=Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
  22. public String[] months = { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月",
  23. "9月", "10月", "11月", "12月" };
  24. public String[] types={"支出","收入","转账","余额"};
  25. @Override
  26. protected void onStart(Intent intent) {
  27. super.onStart(intent);
  28. // 单例模式
  29. if (ability == null) {
  30. ability = (MainAbility) getAbility();
  31. }
  32. context = this;
  33. // addAbilitySlice();
  34. if (calendar == null) {
  35. calendar = Calendar.getInstance();
  36. }
  37. if (rs==null)
  38. rs= MyHelper.getInstance(getContext(),"BookKeep");
  39. // if (preferences==null)
  40. // preferences= MyHelper.getInstance("BKInfo",getContext());
  41. //
  42. // // 向preferences实例注册观察者
  43. // PreferencesObserverImpl observer = new PreferencesObserverImpl();
  44. // preferences.registerObserver(observer);
  45. }
  46. // private class PreferencesObserverImpl implements Preferences.PreferencesObserver {
  47. //
  48. // @Override
  49. // public void onChange(Preferences preferences, String key) {
  50. // if ("intKey".equals(key)) {
  51. // showToastDialogShort("添加了key重复了");
  52. // }
  53. // }
  54. // }
  55. /**
  56. * 获得实时的年月日时分秒
  57. * @return
  58. */
  59. public static String getDate() {
  60. Calendar ca = Calendar.getInstance();
  61. SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
  62. String date = sdf.format(ca.getTimeInMillis());
  63. return date;
  64. }
  65. /**
  66. * 获得实时的年月日
  67. * @return
  68. */
  69. public static String getDate1() {
  70. Calendar ca = Calendar.getInstance();
  71. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  72. String date = sdf.format(ca.getTimeInMillis());
  73. return date;
  74. }
  75. public void addAbilitySlice() {
  76. ability.addAbilitySlice(context);
  77. }
  78. public void removeAllAbilitySlice() {
  79. ability.removeAllActivity();
  80. }
  81. @Override
  82. protected void onStop() {
  83. super.onStop();
  84. }
  85. public String getWeek() {
  86. String info = null;
  87. int month = calendar.get(Calendar.MONTH) + 1;
  88. int day = calendar.get(Calendar.DAY_OF_MONTH);
  89. int count = calendar.get(Calendar.DAY_OF_WEEK) - 1;
  90. if (count > 0) {
  91. info = month + "_" + (day - count + 1) + "_" + month + "_"
  92. + (day + 7 - count);
  93. }
  94. return info;
  95. }
  96. public String getmonth() {
  97. String info = null;
  98. int month = calendar.get(Calendar.MONTH) + 1;
  99. // 计算是当月的第几天
  100. int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
  101. System.out.printf("输入的日期是当月的第%d天\n ", dayOfMonth);
  102. // 计算当月的第一天
  103. calendar.add(Calendar.DATE, 1 - dayOfMonth);
  104. // 计算下月的第一天
  105. calendar.add(Calendar.MONTH, 1);
  106. // 计算当月的最后一天
  107. calendar.add(Calendar.DATE, -1);
  108. // 计算是当月一共几天
  109. dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
  110. System.out.printf("当月一共%d天\n ", dayOfMonth);
  111. info = month + "月" + 1 + "日--" + month + "月" + dayOfMonth + "日";
  112. return info;
  113. }
  114. public String getyear() {
  115. String info = null;
  116. int month = calendar.get(Calendar.MONTH) + 1;
  117. // 计算是当月的第几天
  118. int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
  119. System.out.printf("输入的日期是当月的第%d天\n ", dayOfMonth);
  120. // 计算当月的第一天
  121. calendar.add(Calendar.DATE, 1 - dayOfMonth);
  122. // 计算下月的第一天
  123. calendar.add(Calendar.MONTH, 1);
  124. // 计算当月的最后一天
  125. calendar.add(Calendar.DATE, -1);
  126. // 计算是当月一共几天
  127. dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
  128. System.out.printf("当月一共%d天\n ", dayOfMonth);
  129. info = "1月1日--" + month + "月" + dayOfMonth + "日";
  130. return info;
  131. }
  132. /**
  133. * 查看当前月份
  134. * @param month
  135. * @return
  136. */
  137. public int select_month(int month) {
  138. return (month == 13) ? 1 : (month);
  139. }
  140. /**
  141. * 查看当前天数
  142. * @param month
  143. * @param day
  144. * @return
  145. */
  146. public String select_day(int month, int day) {
  147. if (day >= 32) {
  148. int months = select_month(month + 1);
  149. return months + "-" + (day % 31);
  150. } else {
  151. return month + "-" + day;
  152. }
  153. }
  154. public void showToastDialogShort(String info){
  155. new ToastDialog(context).setText(info).setDuration(1000).show();
  156. }
  157. public void showToastDialogLong(String info){
  158. new ToastDialog(context).setText(info).setDuration(2000).show();
  159. }
  160. }

在基类中,定义了提示对话框的工具方法,根据不同条件获得日,周,月的时间,以及实时获得当天时间的方法,这些方法可以供所有继承至该AbilitySlice基类的AbilitySlice类使用,这里不过多的叙述,学过java的同学应该都清楚,子类继承父类,子类可以直接调用父类的方法。

6.创建欢迎引导页

在任何一款成熟的软件都具备引导页,这里我们也不例外,我们完成四页的引导,在第四个引导页之后,进行跳入应用。代码如下:

  1. package com.example.bookkeepproject.slice;
  2. import com.example.bookkeepproject.ResourceTable;
  3. import com.example.bookkeepproject.adapter.LoadingPageAdapter;
  4. import ohos.aafwk.content.Intent;
  5. import ohos.agp.components.Component;
  6. import ohos.agp.components.PageSlider;
  7. /**
  8. * 引导页
  9. */
  10. public class LoadingAbilitySlice extends BaseAbilitySlice {
  11. private PageSlider page;
  12. private LoadingPageAdapter adapter;
  13. private int[] images = {ResourceTable.Media_load_1, ResourceTable.Media_load_2, ResourceTable.Media_load_3, ResourceTable.Media_load_4};
  14. @Override
  15. protected void onStart(Intent intent) {
  16. super.onStart(intent);
  17. this.setUIContent(ResourceTable.Layout_ability_loading);
  18. page = (PageSlider) this.findComponentById(ResourceTable.Id_page);
  19. adapter = new LoadingPageAdapter(images, this);
  20. page.setProvider(adapter);
  21. page.addPageChangedListener(listener);
  22. }
  23. private PageSlider.PageChangedListener listener = new PageSlider.PageChangedListener() {
  24. @Override
  25. public void onPageSliding(int i, float v, int i1) {
  26. }
  27. @Override
  28. public void onPageSlideStateChanged(int i) {
  29. }
  30. @Override
  31. public void onPageChosen(int i) {
  32. if (i == images.length - 1) {
  33. page.setClickedListener(clickedListener);
  34. }
  35. }
  36. };
  37. private Component.ClickedListener clickedListener=new Component.ClickedListener() {
  38. @Override
  39. public void onClick(Component component) {
  40. present(new LoginAbilitySlice(), new Intent());
  41. terminate();
  42. }
  43. };
  44. }

对应的布局文件代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <DirectionalLayout
  3. xmlns:ohos="http://schemas.huawei.com/res/ohos"
  4. ohos:height="match_parent"
  5. ohos:width="match_parent"
  6. ohos:orientation="vertical">
  7. <PageSlider
  8. ohos:id="$+id:page"
  9. ohos:height="match_parent"
  10. ohos:width="match_parent"/>
  11. </DirectionalLayout>

7.创建滑动加载适配器

 创建一个adapter包,在包中新建一个LoadingPageAdapter类继承至PageSliderProvider类,并实现未实现的方法,加载图片和动态的创建子布局

  1. package com.example.bookkeepproject.adapter;
  2. import ohos.aafwk.ability.AbilitySlice;
  3. import ohos.agp.components.Component;
  4. import ohos.agp.components.ComponentContainer;
  5. import ohos.agp.components.Image;
  6. import ohos.agp.components.PageSliderProvider;
  7. public class LoadingPageAdapter extends PageSliderProvider {
  8. private int[] images;
  9. private AbilitySlice context;
  10. public LoadingPageAdapter(int[] images, AbilitySlice context) {
  11. this.images = images;
  12. this.context = context;
  13. }
  14. @Override
  15. public int getCount() {
  16. return images.length;
  17. }
  18. @Override
  19. public Object createPageInContainer(ComponentContainer componentContainer, int i) {
  20. Image image=new Image(context);
  21. image.setScaleMode(Image.ScaleMode.STRETCH);
  22. ComponentContainer.LayoutConfig config=new ComponentContainer
  23. .LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,
  24. ComponentContainer.LayoutConfig.MATCH_PARENT);
  25. image.setLayoutConfig(config);
  26. image.setPixelMap(images[i]);
  27. componentContainer.addComponent(image);
  28. return image;
  29. }
  30. @Override
  31. public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) {
  32. //滑出屏幕的组件进行移除
  33. componentContainer.removeComponent((Component) o);
  34. }
  35. @Override
  36. public boolean isPageMatchToObject(Component component, Object o) {
  37. //判断滑页上的每一页的组件和内容是否保持一致
  38. return true;
  39. }
  40. }

8.引导页效果展示

 8.总结

一个项目的开发,开发过程中搭建框架是非常重要的,框架搭建的越好,后期的功能开发越来越轻松。

【鸿蒙】鸿蒙App应用-《记账软件》登录,注册,找回密码功能

【鸿蒙】鸿蒙App应用-《记账软件》明细模块

【鸿蒙】鸿蒙App应用-《记账软件》图表模块

【鸿蒙】鸿蒙App应用-《记账软件》记账模块

【鸿蒙】鸿蒙App应用-《记账软件》发现模块

【鸿蒙】鸿蒙App应用-《记账软件》我的模块

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/282174
推荐阅读
相关标签
  

闽ICP备14008679号