鸿蒙开发基础运用(ArkTS)-健康生活APP

news2024/11/28 20:36:32

健康生活应用,主要功能包括:

  1. 用户可以创建最多6个健康生活任务(早起,喝水,吃苹果,每日微笑,刷牙,早睡),并设置任务目标、是否开启提醒、提醒时间、每周任务频率。
  2. 用户可以在主页面对设置的健康生活任务进行打卡,其中早起、每日微笑、刷牙和早睡只需打卡一次即可完成任务,喝水、吃苹果需要根据任务目标量多次打卡完成。
  3. 主页可显示当天的健康生活任务完成进度,当天所有任务都打卡完成后,进度为100%,并且用户的连续打卡天数加一。

实操步骤

应用主页面

启动页

给应用添加一个启动页,启动页里需要用到定时器来实现启动页展示固定时间后跳转应用主页的功能。具体实现逻辑是:

  1. 通过修改entryability里的loadContent路径可以改变应用的入口文件,此处改为SplashPage。
  2. 在SplashPage通过首选项来实现“权限管理”弹窗。如果需要弹窗,用户点击同意后通过首选项对用户的操作做持久化保存。
// EntryAbility.ets
windowStage.loadContent('pages/SplashPage', (err, data) => {
  if (err.code) {...}
  Logger.info('windowStage', 'Succeeded in loading the content. Data: ' + JSON.stringify(data))
});

// SplashPage.ets
import common from '@ohos.app.ability.common';
import data_preferences from '@ohos.data.preferences';

@Entry
@Component
struct SplashIndex {
  context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
  
  onConfirm() {
    let preferences = data_preferences.getPreferences(that.context, H_STORE);
    preferences.then((res) => {
      res.put(IS_PRIVACY, true).then(() => {
        res.flush();
        Logger.info('SplashPage', 'isPrivacy is put success');
      }).catch((err: Error) => {
        Logger.info('SplashPage', 'isPrivacy put failed. Cause: ' + err);
      });
    })
    this.jumpAdPage();
  }

  exitApp() {
    this.context.terminateSelf();
  }

  jumpAdPage() {
    setTimeout(() => {
      router.replaceUrl({ url: 'pages/AdvertisingPage' });
    }, Const.LAUNCHER_DELAY_TIME);
  }

  aboutToAppear() {
    let preferences = data_preferences.getPreferences(this.context, H_STORE);
    preferences.then((res) => {
      res.get(IS_PRIVACY, false).then((isPrivate) => {
        if (isPrivate === true) {
          this.jumpAdPage();
        } else {
          this.dialogController.open();
        }
      });
    });
  }

  build() {
    ...
  }
}

应用入口

我们需要给APP添加底部菜单栏,用于切换不同的应用模块,由于各个模块之间属于完全独立的情况,并且不需要每次切换都进行界面的刷新,所以我们用到了Tabs,TabContent组件。 本应用一共有首页(HomeIndex),成就(AchievementIndex)和我的(MineIndex)三个模块,分别对应Tabs组件的三个子组件TabContent。

// MainPage.ets
Tabs({ barPosition: BarPosition.End, controller: this.tabController }) {
  TabContent() {    
    HomeIndex({ homeStore: $homeStore, editedTaskInfo: $editedTaskInfo, editedTaskID: $editedTaskID })
      .borderWidth({ bottom: 1 })
      .borderColor($r('app.color.primaryBgColor'))
  }
  .tabBar(this.TabBuilder(TabId.HOME)) 
  .align(Alignment.Start)

  TabContent() {    
    AchievementIndex()  
  }
  .tabBar(this.TabBuilder(TabId.ACHIEVEMENT))  

  TabContent() {    
    MineIndex()
  }
  .tabBar(this.TabBuilder(TabId.MINE))
}

首页

首页包含了任务信息的所有入口,包含任务列表的展示,任务的编辑和新增,上下滚动的过程中顶部导航栏的渐变,日期的切换以及随着日期切换界面任务列表跟着同步的功能。具体代码实现我们将在下边分模块进行说明。

  • 导航栏背景渐变

Scroll滚动的过程中,在它的onScrollAction()方法里我们通过计算它Y轴的偏移量来改变当前界面的@State修饰的naviAlpha变量值,进而改变顶部标题的背景色。

// HomeComponent.ets
// 视图滚动的过程中处理导航栏的透明度
@State naviAlpha: number = 0;
...
onScrollAction() {  
  this.yOffset = this.scroller.currentOffset().yOffset;  
  if (this.yOffset > Const.DEFAULT_56) {    
    this.naviAlpha = 1;  
  } else {    
    this.naviAlpha = this.yOffset / Const.DEFAULT_56;  
  }
}
  • 日历组件

日历组件主要用到的是一个横向滑动的Scroll组件。手动滑动页面时,通过在onScrollEndAction()方法里计算Scroll的偏移量来实现分页的效果,同时Scroll有提供scrollPage()方法可供我们点击左右按钮的时候来进行页面切换。需要在Scroll滑动到左边边缘的时候去请求更多的历史数据以便Scroll能一直滑动,通过Scroll的onScrollEdge方法可以判断它是否已滑到边缘位置。homeStore主要是请求数据库的数据并对数据进行处理进而渲染到界面上。同时还需要知道怎么根据当天的日期计算出本周内的所有日期数据。

// WeekCalendarComponent.ets
build() {    
  Row() {      
    Column() {        
      Row() {...}             
      Scroll(this.scroller) {          
        Row() {            
          ForEach(this.homeStore.dateArr, (item: WeekDateModel, index?: number) => {              
            Column() {                
              Text(item.weekTitle)                  
                .fontColor(
                  sameDate(item.date, this.homeStore.showDate) ? 
                    $r('app.color.blueColor') : $r('app.color.titleColor')
                )                                 
              Divider()
                .color(
                  sameDate(item.date, this.homeStore.showDate) ? 
                    $r('app.color.blueColor') : $r('app.color.white')
                )                
              Image(this.getProgressImg(item))                               
            } 
            .onClick(() => WeekCalendarMethods.calenderItemClickAction(item, index, this.homeStore))            
          })          
         }       
        }               
        .onScrollStop(() => this.onScrollEndAction())        
        .onScrollEdge((event) => this.onScrollEdgeAction(event))      
      }
    }
  }
}

// WeekCalendarComponent.ets
// scroll滚动停止时通过判断偏移量进行分页处理
onScrollEndAction() {
  // 区分是否是手动滑动,点击左右箭头按钮导致Scroll滑动时不作处理,不然会引起死循环
  if (this.isPageScroll === false) {
    let page = Math.round(this.scroller.currentOffset().xOffset / this.scrollWidth);
    page = (this.isLoadMore === true) ? page + 1 : page;
    if (this.scroller.currentOffset().xOffset % this.scrollWidth != 0 || this.isLoadMore === true) {
      let xOffset = page * this.scrollWidth;

      // 滑动到指定位置
      this.scroller.scrollTo({ xOffset, yOffset: 0 } as ScrollTo);
      this.isLoadMore = false;
    }
    // 处理当前界面展示的数据  
    this.currentPage = this.homeStore.dateArr.length / Const.WEEK_DAY_NUM - page - 1;
    let dayModel: WeekDateModel = this.homeStore.dateArr[Const.WEEK_DAY_NUM * page + this.homeStore.selectedDay];
    this.homeStore!.setSelectedShowDate(dayModel!.date!.getTime());
  }
  this.isPageScroll = false;
}

// WeekCalendarComponent.ets
onScrollEdgeAction(side: Edge) {
  if (side === Edge.Top && this.isPageScroll === false) {
    Logger.info('HomeIndex', 'onScrollEdge: currentPage ' + this.currentPage);
    if ((this.currentPage + 2) * Const.WEEK_DAY_NUM >= this.homeStore.dateArr.length) {
      Logger.info('HomeIndex', 'onScrollEdge: load more data');
      let date: Date = new Date(this.homeStore.showDate);
      date.setDate(date.getDate() - Const.WEEK_DAY_NUM);
      that.homeStore.getPreWeekData(date, () => {});
      this.isLoadMore = true;
    }
  }
}

// HomeViewModel.ets
public getPreWeekData(date: Date, callback: Function) {
  let weekCalendarInfo: WeekCalendarInfo = getPreviousWeek(date);    
  // 请求数据库数据
  DayInfoApi.queryList(weekCalendarInfo.strArr, (res: DayInfo[]) => {
    // 数据处理
    ...  
    this.dateArr = weekCalendarInfo.arr.concat(...this.dateArr);
  })
}

// WeekCalendarModel.ets
export function getPreviousWeek(showDate: Date): WeekCalendarInfo {
  let weekCalendarInfo: WeekCalendarInfo = new WeekCalendarInfo();
  let arr: Array<WeekDateModel> = [];
  let strArr: Array<string> = []; 

  // 由于date的getDay()方法返回的是0-6代表周日到周六,我们界面上展示的周一-周日为一周,所以这里要将getDay()数据偏移一天
  let currentDay = showDate.getDay() - 1;

  // 将日期设置为当前周第一天的数据(周一)
  showDate.setDate(showDate.getDate() - currentDay);
  for (let index = WEEK_DAY_NUM; index > 0; index--) {
    let tempDate = new Date(showDate);
    tempDate.setDate(showDate.getDate() - index);
    let dateStr = dateToStr(tempDate);
    strArr.push(dateStr);
    arr.push(new WeekDateModel(WEEK_TITLES[tempDate.getDay()], dateStr, tempDate));
  }
  weekCalendarInfo.arr = arr;
  weekCalendarInfo.strArr = strArr;
  return weekCalendarInfo;
}
  • 悬浮按钮

由于首页右下角有一个悬浮按钮,所以首页整体我们用了一个Stack组件,将右下角的悬浮按钮和顶部的title放在滚动组件层的上边。

// HomeComponent.ets
build() {  
  Stack() {    
    Scroll(this.scroller) {      
      Column() {     
        ...
        Column() {          
          ForEach(this.homeStore.getTaskListOfDay(), (item: TaskInfo) => {         
            TaskCard({
              taskInfoStr: JSON.stringify(item),
              clickAction: (isClick: boolean) => this.taskItemAction(item, isClick)
            }) 
          }, (item: TaskInfo) => JSON.stringify(item))
        }   
      }
    }
    .onScroll(() => { this.onScrollAction() })
    // 悬浮按钮
    AddBtn({ clickAction: () => { this.editTaskAction() } })  
    // 顶部title 
    Row() {       
      Text($r('app.string.EntryAbility_label'))
    }
    .position({ x: 0, y: 0 })    
    .backgroundColor(`rgba(${WHITE_COLOR_0X},${WHITE_COLOR_0X},${WHITE_COLOR_0X},${this.naviAlpha})`)    
    CustomDialogView()  
  }  
  .allSize() 
  .backgroundColor($r('app.color.primaryBgColor'))
}
  • 界面跳转及传参

首页任务列表长按时需要跳转到对应的任务编辑界面,同时点击悬浮按钮时需要跳转到任务列表页面。页面跳转需要在头部引入router。

// HomeComponent.ets
import router from '@ohos.router';

taskItemAction(item: TaskInfo, isClick: boolean): void {
  if (!this.homeStore.checkCurrentDay()) {
    return;
  }
  if (isClick) {
    // 点击任务打卡
    let callback: CustomDialogCallback ={ confirmCallback: (taskTemp: TaskInfo) => { this.onConfirm(taskTemp) }, cancelCallback: () => {} };
    this.broadCast.emit(BroadCastType.SHOW_TASK_DETAIL_DIALOG, [item, callback]);
  } else {
    // 长按编辑任务
    let editTaskStr: string = JSON.stringify(TaskMapById[item.taskID - 1]);
    let editTask: ITaskItem = JSON.parse(editTaskStr);
    editTask.targetValue = item?.targetValue;
    editTask.isAlarm = item.isAlarm;
    editTask.startTime = item.startTime;
    editTask.frequency = item.frequency;
    editTask.isOpen = item.isOpen;
    router.pushUrl({ url: 'pages/TaskEditPage', params: { params: JSON.stringify(editTask) } });
  }
}

任务创建与编辑

功能概述

用户点击悬浮按钮进入任务列表页,点击任务列表可进入对应任务编辑的页面中,对任务进行详细的设置,之后点击完成按钮编辑任务后将返回首页。实现效果如图所示。

任务列表

  • 任务列表页

任务列表页由上部分的标题、返回按钮以及正中间的任务列表组成。使用Navigation以及List组件构成元素,使用ForEach遍历生成具体列表。这里是Navigation构成页面导航,实现效果如图所示:

// TaskListPage.ets
Navigation() {
  Column() {
    // 页面中间的列表
    TaskList()
  }
  .width(Const.THOUSANDTH_1000)
  .justifyContent(FlexAlign.Center)
}
.size({ width: Const.THOUSANDTH_1000, height: Const.THOUSANDTH_1000 })
.title(Const.ADD_TASK_TITLE)
.titleMode(NavigationTitleMode.Mini)

列表右侧有一个判断是否开启的文字标识,点击某个列表需要跳转到对应的任务编辑页里。具体的列表实现:

// TaskListComponent.ets
List({ space: Const.LIST_ITEM_SPACE }) {
  ForEach(this.taskList, (item: ITaskItem) => {
    ListItem() {
      Row() {
        Row() {
          Image(item?.icon)
          Text(item?.taskName)
            ...
        }
        .width(Const.THOUSANDTH_500)

        Blank()
          .layoutWeight(1)

        // 状态显示
        if (item?.isOpen) {
          Text($r('app.string.already_open'))
        }
        Image($r('app.media.ic_right_grey'))
          .width(Const.DEFAULT_8)
          .height(Const.DEFAULT_16)

      }
      ...
    }
    ...

    // 路由跳转到任务编辑页
    .onClick(() => {
      router.pushUrl({
        url: 'pages/TaskEditPage',
        params: {
          params: formatParams(item)
        }
      })
    })
    ...
  })
}

任务编辑

  • 任务编辑页

任务编辑页由上方的“编辑任务”标题以及返回按钮,主体内容的List配置项和下方的完成按钮组成。任务编辑页面,由Navigation和一个自定义组件TaskDetail构成。自定义组件由List以及其子组件ListItem构成,实现效果如图所示:

// TaskEditPage.ets
Navigation() {
  Column() {
    TaskDetail()
  }
  .width(Const.THOUSANDTH_1000)
  .height(Const.THOUSANDTH_1000)
}
.size({ width: Const.THOUSANDTH_1000, height: Const.THOUSANDTH_1000 })
.title(Const.EDIT_TASK_TITLE).titleMode(NavigationTitleMode.Mini)

// TaskDetailComponent.ets
List({ space: Const.LIST_ITEM_SPACE }) {
  ListItem() {
    TaskChooseItem()
  }
  .listItemStyle()

  ListItem() {
    TargetSetItem()
  }
  .listItemStyle()
  // 一些特殊情况的禁用,如每日微笑、每日刷牙的目标设置不可编辑
  .enabled( 
    this.settingParams?.isOpen
    && this.settingParams?.taskID !== taskType.smile
    && this.settingParams?.taskID !== taskType.brushTeeth
  )
  .onClick(() => {
    this.broadCast.emit(
      BroadCastType.SHOW_TARGET_SETTING_DIALOG);
  })

  ListItem() {
    OpenRemindItem()
  }
  .listItemStyle()
  // 其中做了禁用判断,需要任务打开才可以点击编辑
  .enabled(this.settingParams?.isOpen)

  ListItem() {
    RemindTimeItem()
  }
  .listItemStyle()
  // 提醒时间在开启提醒打开之后才可以编辑
  .enabled(this.settingParams?.isOpen && this.settingParams?.isAlarm)
  .onClick(() => {
    this.broadCast.emit(BroadCastType.SHOW_REMIND_TIME_DIALOG);
  })

  ListItem() {
    FrequencyItem()
  }
  .listItemStyle()
  .enabled(this.settingParams?.isOpen && this.settingParams?.isAlarm)
  .onClick(() => {
    this.broadCast.emit(BroadCastType.SHOW_FREQUENCY_DIALOG);
  })
}
.width(Const.THOUSANDTH_940)

// TaskDetailComponent.ets
addTask({
  // 相关参数
  ...
})
.then((res: number) => {
  // 成功的状态,成功后跳转首页
  GlobalContext.getContext().setObject('taskListChange', true);
  router.back({
    url: 'pages/MainPage',
    params: {
      editTask: this.backIndexParams()
    }
  })
  Logger.info('addTaskFinished', JSON.stringify(res));
})
.catch((error: Error) => {
  // 失败的状态,失败后弹出提示,并打印错误日志
  prompt.showToast({
    message: Const.SETTING_FINISH_FAILED_MESSAGE
  })
  Logger.error('addTaskFailed', JSON.stringify(error));
})

  • 任务编辑弹窗

在自定义弹窗CustomDialogView组件内注册打开弹窗的事件,当点击对应任务的编辑项时触发该事件,进而打开弹窗。

// TaskDialogView.ets
targetSettingDialog: CustomDialogController = new CustomDialogController({
  builder: TargetSettingDialog(),
  autoCancel: true,
  alignment: DialogAlignment.Bottom,
  offset: { dx: Const.ZERO, dy: Const.MINUS_20 }
});
...

// 注册事件
this.broadCast.on(BroadCastType.SHOW_TARGETSETTING_DIALOG, () => {
  this.targetSettingDialog.open();
})

// HomeComponent.ets
taskItemAction(item: TaskInfo, isClick: boolean): void {
  ...
  if (isClick) {
    let callback: CustomDialogCallback ={ confirmCallback: (taskTemp: TaskInfo) => { this.onConfirm(taskTemp) }, cancelCallback: () => {} };
    this.broadCast.emit(BroadCastType.SHOW_TASK_DETAIL_DIALOG, [item, callback]);
  } else {
    ...
  }
}

任务目标设置有三种类型,早睡早起的时间、喝水的量度、吃苹果的个数。故根据任务的ID进行区分,将同一弹窗复用,如图所示:

其余弹窗实现基本类似,这里不再赘述。

// TaskSettingDialog.ets
if ([taskType.getup, taskType.sleepEarly].indexOf(this.settingParams?.taskID) > Const.HAS_NO_INDEX) {
  TimePicker({
    selected: new Date(`${new Date().toDateString()} 8:00:00`),
  })
  ...
} else {
  TextPicker({ 
    range: this.settingParams?.taskID === taskType.drinkWater ? 
      this.drinkRange : 
      this.appleRange 
  })
  ...
}

// TaskSettingDialog.ets
// 校验规则
compareTime(startTime: string, endTime: string) {
  if (returnTimeStamp(this.currentTime) < returnTimeStamp(startTime) || 
    returnTimeStamp(this.currentTime) > returnTimeStamp(endTime)) {
    // 弹出提示
    prompt.showToast({
      message: commonConst.CHOOSE_TIME_OUT_RANGE
    })
    return false;
  }
  return true;
}

// 设置修改项
setTargetValue() {
  ...
  if (this.settingParams?.taskID === taskType.sleepEarly) {
    if (!this.compareTime(commonConst.SLEEP_EARLY_TIME, commonConst.SLEEP_LATE_TIME)) {
      return;
    }
    this.settingParams.targetValue = this.currentTime;
    return;
  }
  this.settingParams.targetValue = this.currentValue;
}

本文是鸿蒙开发中对OpenHarmony技术的简单运用,更多的鸿蒙开发技术可以前往我主页查询,下面分享鸿蒙开发4.0技术分布(略缩图):

高清完整版技术学习路线图如下寻找保存(附鸿蒙文档)

最后是效果如图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1365301.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024拜年祝福视频AE模板31套

做短视频必备的AE模板非常好看&#xff0c;跨年做个视频非常漂亮&#xff0c;喜欢的赶紧保存吧&#xff01; 链接&#xff1a;https://pan.quark.cn/s/fc1f3db12049

回首2023,厉兵秣马,启航2024

目录 回首风波的20232023&#xff0c;感恩相遇暂停发文发文狂潮感恩有你备战2024学习之余跆拳道比赛做手工diy 学习心路年初学习伊始心路其后学习后来心路 必须看配图说明 未知的2024Flag 回首风波的2023 2023&#xff0c;感恩相遇 还记得&#xff0c;22年末&#xff0c;23年…

Anaconda下载安装与使用

前言 Pandas之所以被称为工具包&#xff0c;原因是Pandas这个工具是由不同的代码模块组成的。每一个代码模块的功能不同&#xff0c;合在一起构成Pandas的丰富功能。其他工具包亦然。 名称描述NumpyNumpy是通用的数值计算工具包&#xff0c;包含大量数学计算函数和矩阵运算函数…

QT应用篇:QT自定义最小化托盘显示和操作

将应用程序最小化到托盘任务栏中,可以使用Qt框架中的QSystemTrayIcon类。该类允许应用程序在关闭窗口后最小化到系统托盘,保持在后台运行,同时可以显示应用程序图标、添加右键菜单功能以及发送消息通知等。通过学习这些技术,能够为自己的Qt应用程序增加更多的交互性和便利性…

3.1 CUDA Thread Organization

在第2章中&#xff0c;数据并行计算&#xff0c;我们学会了编写一个简单的CUDA C程序&#xff0c;该程序启动内核和线程网格&#xff0c;以对一维数组中的元素进行操作。内核指定每个线程执行的C语句。当我们发动如此大规模的执行活动时&#xff0c;我们需要控制这些活动&#…

【书生·浦语大模型实战营02】《轻松玩转书生·浦语大模型趣味Demo》学习笔记

《轻松玩转书生浦语大模型趣味Demo》 教程文档&#xff1a;《轻松玩转书生浦语大模型趣味 Demo文档》 致谢 感谢助教 MINGX 的帮助&#xff5e; 1、InternLM-Chat-7B 智能对话&#xff1a;生成 300 字的小故事 本节中我们将使用InternLM-Chat-7B 模型部署一个智能对话 Dem…

深入了解static关键字的作用和应用--java面向对象学习

Static修饰成员变量 Static是什么 叫静态&#xff0c;可以修饰成员变量&#xff0c;成员方法 成员变量按有无static修饰分俩种&#xff1a; 类变量&#xff1a;有static修饰&#xff0c;属于类&#xff0c;在计算机里只有一份&#xff0c;会被类的全部对…

Saprk SQL基础知识

一.Spark SQL基本介绍 1.什么是Spark SQL Spark SQL是Spark多种组件中其中一个,主要是用于处理大规模的[结构化数据] Spark SQL的特点: 1).融合性:既可以使用SQL语句,也可以编写代码,同时支持两者混合使用. 2).统一的数据访问:Spark SQL用统一的API对接不同的数据源 3).H…

vueRouter 配合 keep-alive 不生效的问题

文章目录 问题说明案例复现demo 结构问题复现和解决 其实这个不生效的问题根本也不算一个问题&#xff0c;犯的错和写错单词差不多&#xff0c;但是也是一时上头没发现&#xff0c;所以记录一下&#xff0c;如果遇到同样的问题&#xff0c;也希望可以帮助你早点看到这个哭笑不得…

WWDG---窗口看门狗

一.简介 窗口看门狗跟独立看门狗一样&#xff0c;也是一个递减计数器不断的往下递减计数&#xff0c;必须在一个窗口的上限值&#xff08;用户定义&#xff09;和下限值&#xff08;0X40&#xff0c;固定不能变&#xff09;之间喂狗不会复位&#xff0c;在上限值之前和下限值之…

etcd储存安装

目录 etcd介绍: etcd工作原理 选举 复制日志 安全性 etcd工作场景 服务发现 etcd基本术语 etcd安装(centos) 设置&#xff1a;etcd后台运行 etcd 是云原生架构中重要的基础组件&#xff0c;由 CNCF 孵化托管。etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册…

【hcie-cloud】【18】华为云Stack灾备服务介绍【容灾解决方案介绍、灾备方案架构介绍、管理组件灾备方案介绍、高阶云服务容灾简介、缩略词】【下】

文章目录 灾备方案概述、备份解决方案介绍容灾解决方案介绍华为云容灾解决方案概览云容灾服务云硬盘高可用服务 (VHA)VHA组网结构VHA逻辑组网架构VHA管理组件介绍VHA服务实现原理云服务器高可用服务&#xff08;CSHA&#xff09;CSHA物理组网架构CSHA逻辑组网架构CSHA服务组件间…

嵌入式培训机构四个月实训课程笔记(完整版)-Linux系统编程第五天-Linux消息共享内存练习题(物联技术666)

更多配套资料CSDN地址:点赞+关注,功德无量。更多配套资料,欢迎私信。 物联技术666_嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记-CSDN博客物联技术666擅长嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记,等方面的知识,物联技术666关注机器学习,arm开发,物联网,嵌入式硬件,单片机…

2024--Django平台开发-Web框架和Django基础(二)---Mysql多版本共存(Mac系统)

MySQL多版本共存&#xff08;Mac系统&#xff09; 想要在Mac系统上同时安装【MySQL5.7 】【MySQL8.0】版本&#xff0c;需要进行如下的操作和配置。 想要同时安装两个版本可以采取如下方案&#xff1a; 方案1&#xff1a;【讲解】 MySQL57&#xff0c;用安装包进行安装。 MyS…

像专家一样使用TypeScript映射类型

掌握TypeScript的映射类型&#xff0c;了解TypeScript内置的实用类型是如何工作的。 您是否使用过Partial、Required、Readonly和Pick实用程序类型? 你知道他们内部是怎么运作的吗? 如果您想彻底掌握它们并创建自己的实用程序类型&#xff0c;那么不要错过本文所涵盖的内容。…

2、Excel:基础概念、表格结构与常见函数

数据来源&#xff1a;八月成交数据 数据初探 业务背景 数据来源行业&#xff1a;金融行业&#xff08;根据应收利息和逾期金额字段来判断&#xff09; 可以猜测&#xff1a; 业务主体&#xff1a;某互联网金融公司&#xff08;类似支付宝&#xff09;也业务模式&#xff1a;给…

leetcode动态规划问题总结 Python

目录 一、基础理论 二、例题 1. 青蛙跳台阶 2. 解密数字 3. 最长不含重复字符的子字符串 4. 连续子数组的最大和 5. 最长递增子序列 6. 最长回文字符串 7. 机器人路径条数 8. 礼物的最大价值 一、基础理论 动态规划其实是一种空间换时间的基于历史数据的递推算法&…

Java异常机制:从混乱到控制的错误管理艺术

&#x1f451;专栏内容&#xff1a;Java⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录 一、异常的体系结构1、异常的体系结构2、异常的分类 二、异常的处理1、异常的抛出2、异常的捕获2.1、异常声明throws2.2、try-c…

C#中List<T>底层原理剖析

C#中List底层原理剖析 1. 基础用法2. List的Capacity与Count&#xff1a;3.List的底层原理3.1. 构造3.2 Add()接口3.3 Remove()接口3.4 Inster()接口3.5 Clear()接口3.6 Contains()接口3.7 ToArray()接口3.8 Find()接口3.8 Sort()接口 4. 总结5. 参考 1. 基础用法 list.Max() …

2024龙年艺术字矢量Ai设计文件60套

2024新年将至&#xff0c;设计师们早已开始为龙年海报、推文的制作摩拳擦掌。该合集不仅内容丰富多样,作为矢量文件资源&#xff0c;也能够让设计者更为轻松地编辑与创作。 合集内另附200多张电脑壁纸。 文件总大小368MB 链接&#xff1a;https://pan.quark.cn/s/0caab4cf065…