HarmonyOS开发实战:如何实现一个运动排名榜页面

这篇具有很好参考价值的文章主要介绍了HarmonyOS开发实战:如何实现一个运动排名榜页面。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

HarmonyOS开发实战:如何实现一个运动排名榜页面

代码仓库: 运动排名榜页面

项目介绍

本项目使用声明式语法和组件化基础知识,搭建一个可刷新的排行榜页面。在排行榜页面中,使用循环渲染控制语法来实现列表数据渲染,使用@Builder创建排行列表布局内容,使用装饰器@State、@Prop、@Link来管理组件状态。最后我们点击系统返回按键,来学习自定义组件生命周期函数。完成效果如图所示:

HarmonyOS开发实战:如何实现一个运动排名榜页面,harmonyos,华为

新建项目工程

选择Create Project新建项目,点击Application选择第一个Empty Ability应用,点击“Next”进行下一步
HarmonyOS开发实战:如何实现一个运动排名榜页面,harmonyos,华为
配置页中,详细信息如下:

Project name是开发者可以自行设置的项目名称,这里根据自己选择修改为自己项目名称。
Bundle name是包名称,默认情况下应用ID也会使用该名称,应用发布时对应的ID需要保持一致。
Save location为工程保存路径,建议用户自行设置相应位置。
Compile SDK是编译的API版本,这里默认选择API9。
Model选择Stage模型,其他保持默认即可。
点击“Finish”进行下一步
HarmonyOS开发实战:如何实现一个运动排名榜页面,harmonyos,华为

项目创建成功
HarmonyOS开发实战:如何实现一个运动排名榜页面,harmonyos,华为

代码实现

编写应用入口页面

RankPage是应用入口页面

@Entry
@Component
struct RankPage {
  @State message: string = 'My Ranking'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}

修改EntryAbility.ts应用配置,入口页面更改为pages/RankPage
HarmonyOS开发实战:如何实现一个运动排名榜页面,harmonyos,华为
运行成功
HarmonyOS开发实战:如何实现一个运动排名榜页面,harmonyos,华为

编写公共常量

公共常量的好处包括:

  • 代码可读性: 使用公共常量可以提高代码的可读性和可维护性,因为它们可以清晰地表达出程序中使用的固定数值或字符串。
  • 便于修改和维护: 如果程序中的某个数值或字符串需要修改,只需修改公共常量的定义,而不需要在整个程序中逐个修改。
  • 避免魔法数值: 使用公共常量可以避免在代码中出现“魔法数值”,即难以理解和维护的硬编码数值。
  • 提高代码重用性: 公共常量可以在整个程序中被引用和使用,从而提高代码的重用性。
  • 统一管理: 将所有的固定数值或字符串集中管理在公共常量中,有利于统一管理和维护。
/**
 * The font size of application.
 */
export enum FontSize {
  SMALL = 14,
  MIDDLE = 16,
  LARGE = 20,
};

/**
 * The font weight of application.
 */
export enum FontWeight {
  BOLD = '400',
  BOLDER = '500',
};

/**
 * The weight is global default value for component size.
 */
export const WEIGHT = '100%';

/**
 * The duration of toast.
 */
export const TIME = 1000;

/**
 * The interval time of exit.
 */
export const APP_EXIT_INTERVAL: number = 4500;

/**
 * The tag is the page name,which is used to print.
 */
export const TAG: string = 'RankPage';

/**
 * The title of TitleComponent.
 */
export const TITLE: Resource = $r('app.string.title');

class style {
  RANK_PADDING: number = 15;
  CONTENT_WIDTH: string = '90%';
  BORDER_RADIUS: number = 20;
  STROKE_WIDTH: number = 1;
  HEADER_MARGIN_TOP: number = 20;
  HEADER_MARGIN_BOTTOM: number = 15;
  LIST_HEIGHT: string = '65%';
}

/**
 * The Style of RankPage.
 */
export const Style: style = {
  /**
   * The padding of ranking.
   */
  RANK_PADDING: 15,

  /**
   * The width of ranking content.
   */
  CONTENT_WIDTH: '90%',

  /**
   * The border radius.
   */
  BORDER_RADIUS: 20,

  /**
   * The stroke width of divider.
   */
  STROKE_WIDTH: 1,

  /**
   * The top margin of ranking header.
   */
  HEADER_MARGIN_TOP: 20,

  /**
   * The bottom margin of ranking header.
   */
  HEADER_MARGIN_BOTTOM: 15,

  /**
   * The height of list.
   */
  LIST_HEIGHT: '65%'
};

class listHeaderStyle {
  FONT_WEIGHT: number = 400;
  LAYOUT_WEIGHT_LEFT: string = '30%';
  LAYOUT_WEIGHT_CENTER: string = '50%';
  LAYOUT_WEIGHT_RIGHT: string = '20%';
}

/**
 * The Style of ListHeaderComponent.
 */
export const ListHeaderStyle: listHeaderStyle = {
  /**
   * The weight of font.
   */
  FONT_WEIGHT: 400,

  /**
   * The layout weight of left.
   */
  LAYOUT_WEIGHT_LEFT: '30%',

  /**
   * The layout weight of center.
   */
  LAYOUT_WEIGHT_CENTER: '50%',

  /**
   * The layout weight of right.
   */
  LAYOUT_WEIGHT_RIGHT: '20%',
};

class itemStyle {
  TEXT_LAYOUT_SIZE: number = 24;
  CIRCLE_TEXT_BORDER_RADIUS: number = 24;
  CIRCLE_TEXT_SIZE: number = 24;
  CIRCLE_TEXT_COLOR_STOP_1: number = 0.5;
  CIRCLE_TEXT_COLOR_STOP_2: number = 1.0;
  BAR_HEIGHT: number = 48;
  LAYOUT_WEIGHT_LEFT: string = '30%';
  LAYOUT_WEIGHT_CENTER: string = '50%';
  LAYOUT_WEIGHT_RIGHT: string = '20%';
  BORDER_WIDTH: number = 1;
  COLOR_GREEN: Resource = $r('app.color.item_color');
  COLOR_BLACK: Resource = $r('app.color.item_color_black');
}

/**
 * The Style of ListItemComponent.
 */
export const ItemStyle: itemStyle = {
  /**
   * The line height of text.
   */
  TEXT_LAYOUT_SIZE: 24,

  /**
   * The border radius of circle text.
   */
  CIRCLE_TEXT_BORDER_RADIUS: 24,

  /**
   * The size of circle text.
   */
  CIRCLE_TEXT_SIZE: 24,

  /**
   * Gradient color proportion.
   */
  CIRCLE_TEXT_COLOR_STOP_1: 0.5,

  /**
   * Gradient color proportion.
   */
  CIRCLE_TEXT_COLOR_STOP_2: 1.0,

  /**
   * The height of item.
   */
  BAR_HEIGHT: 48,

  /**
   * The layout weight of left.
   */
  LAYOUT_WEIGHT_LEFT: '30%',

  /**
   * The layout weight of center.
   */
  LAYOUT_WEIGHT_CENTER: '50%',

  /**
   * The layout weight of right.
   */
  LAYOUT_WEIGHT_RIGHT: '20%',

  /**
   * The width of border.
   */
  BORDER_WIDTH: 1,

  /**
   * The green color of item.
   */
  COLOR_GREEN: $r('app.color.item_color'),

  /**
   * The black color of item.
   */
  COLOR_BLACK: $r('app.color.item_color_black')
};

class titleBarStyle {
  IMAGE_BACK_SIZE: number = 21;
  IMAGE_BACK_MARGIN_RIGHT: number = 18;
  IMAGE_LOADING_SIZE: number = 22;
  BAR_HEIGHT: number = 47;
  BAR_MARGIN_HORIZONTAL: number = 26;
  BAR_MARGIN_TOP: number = 10;
  WEIGHT: string = '50%';
}

/**
 * The Style of TitleComponent.
 */
export const TitleBarStyle: titleBarStyle = {
  /**
   * The image size of back button.
   */
  IMAGE_BACK_SIZE: 21,

  /**
   * The right margin of back button.
   */
  IMAGE_BACK_MARGIN_RIGHT: 18,

  /**
   * The size of loading image.
   */
  IMAGE_LOADING_SIZE: 22,

  /**
   * The height of TitleComponent.
   */
  BAR_HEIGHT: 47,

  /**
   * The horizontal margin of TitleComponent.
   */
  BAR_MARGIN_HORIZONTAL: 26,

  /**
   * The top margin of TitleComponent.
   */
  BAR_MARGIN_TOP: 10,

  /**
   * The weight of Row layout.
   */
  WEIGHT: '50%',
};

静态资源

静态资源从代码仓库去获取
HarmonyOS开发实战:如何实现一个运动排名榜页面,harmonyos,华为

实现标题组件

TitleComponent.ets代码实现

import AppContext from '@ohos.app.ability.common';
import { FontSize, TitleBarStyle, WEIGHT } from '../common/constants/Constants';

// 标题组件
@Component
export struct TitleComponent {
  @Link isRefreshData: boolean; // 是否刷新数据
  @State title: Resource = $r('app.string.title_default'); // 标题

  build() {
    Row() {
      Row() {
        // 返回箭头
        Image($r('app.media.ic_public_back'))
          .height(TitleBarStyle.IMAGE_BACK_SIZE) // 高度
          .width(TitleBarStyle.IMAGE_BACK_SIZE) // 宽度
          .margin({ right: TitleBarStyle.IMAGE_BACK_MARGIN_RIGHT }) // 外边距
          .onClick(() => { // 返回上一个界面
            let handler = getContext(this) as AppContext.UIAbilityContext;
            handler.terminateSelf();
          })
        Text(this.title) // 标题
          .fontSize(FontSize.LARGE)
      }
      .width(TitleBarStyle.WEIGHT)
      .height(WEIGHT)
      .justifyContent(FlexAlign.Start) // 水平起始位置对齐

      // 刷新图标
      Row() {
        Image($r('app.media.loading'))
          .height(TitleBarStyle.IMAGE_LOADING_SIZE)
          .width(TitleBarStyle.IMAGE_LOADING_SIZE)
          .onClick(() => { // 点击刷新列表数据
            this.isRefreshData = !this.isRefreshData;
          })
      }
      .width(TitleBarStyle.WEIGHT)
      .height(WEIGHT)
      .justifyContent(FlexAlign.End)
    }
    .width(WEIGHT)
    .padding({ left: TitleBarStyle.BAR_MARGIN_HORIZONTAL,
      right: TitleBarStyle.BAR_MARGIN_HORIZONTAL })
    .margin({ top: TitleBarStyle.BAR_MARGIN_TOP })
    .height(TitleBarStyle.BAR_HEIGHT)
    .justifyContent(FlexAlign.SpaceAround)
  }
}

应用入口页RankPage引入TitleComponent组件

import { APP_EXIT_INTERVAL, Style, TIME, TITLE, WEIGHT } from '../common/constants/Constants';
import { TitleComponent } from '../view/TitleComponent';

@Entry
@Component
struct RankPage {

  @State isSwitchDataSource: boolean = true; // 是否切换数据源

  build() {
    Column() {
      // 标题
      TitleComponent({ isRefreshData: $isSwitchDataSource, title: TITLE })
    }
  }
}

运行代码:
HarmonyOS开发实战:如何实现一个运动排名榜页面,harmonyos,华为

实现列表头部

ListHeaderComponent .ets代码实现

import { FontSize, ListHeaderStyle } from '../common/constants/Constants';

@Component
export struct ListHeaderComponent {
  paddingValue: Padding | Length = 0; // 内边距
  widthValue: Length = 0; // 宽度

  build() {
    Row() {
      Text('排名')
        .fontSize(FontSize.SMALL) // 字体大小
        .width(ListHeaderStyle.LAYOUT_WEIGHT_LEFT) // 宽度
        .fontWeight(ListHeaderStyle.FONT_WEIGHT) // 字体宽度
        .fontColor($r('app.color.font_description')) // 字体颜色
      Text('姓名')
        .fontSize(FontSize.SMALL)
        .width(ListHeaderStyle.LAYOUT_WEIGHT_CENTER)
        .fontWeight(ListHeaderStyle.FONT_WEIGHT)
        .fontColor($r('app.color.font_description'))
      Text('步数')
        .fontSize(FontSize.SMALL)
        .width(ListHeaderStyle.LAYOUT_WEIGHT_RIGHT)
        .fontWeight(ListHeaderStyle.FONT_WEIGHT)
        .fontColor($r('app.color.font_description'))
    }
    .width(this.widthValue) // 宽度
    .padding(this.paddingValue) // 内边距
  }
}

应用入口页RankPage引入ListHeaderComponent 组件

import { APP_EXIT_INTERVAL, Style, TIME, TITLE, WEIGHT } from '../common/constants/Constants';
import { TitleComponent } from '../view/TitleComponent';
import { ListHeaderComponent } from '../view/ListHeaderComponent';

@Entry
@Component
struct RankPage {

  @State isSwitchDataSource: boolean = true; // 是否切换数据源

  build() {
    Column() {
      // 标题
      TitleComponent({ isRefreshData: $isSwitchDataSource, title: TITLE })
      // 列表头部
      ListHeaderComponent({
        paddingValue: {
          left: Style.RANK_PADDING,
          right: Style.RANK_PADDING
        },
        widthValue: Style.CONTENT_WIDTH
      })
        .margin({ // 外边距
          top: Style.HEADER_MARGIN_TOP,
          bottom: Style.HEADER_MARGIN_BOTTOM
        })
    }
  }
}

运行代码:
HarmonyOS开发实战:如何实现一个运动排名榜页面,harmonyos,华为

准备排名榜数据

RankData.ets 排序类

// 排名类
export class RankData {
  name: string; // 姓名
  stepNum: string; // 步数
  id: string;

  // 构造函数
  constructor(id: string, name: string, stepNum: string) {
    this.id = id;
    this.name = name;
    this.stepNum = stepNum;
  }
}

DataModel.ets初始化排名数据

import { RankData } from '../viewmodel/RankData';

export { rankData1, rankData2 }

// 初始化排名数据1
const rankData1: RankData[] = [
  new RankData('1', '喜羊羊', '12080'),
  new RankData('2', '美羊羊', '10320'),
  new RankData('3', '灰太狼', '9801'),
  new RankData('4', '红太狼', '8431'),
  new RankData('5', '懒羊羊', '7546'),
  new RankData('6', '暖羊羊', '7431'),
  new RankData('7', '沸羊羊', '7187'),
  new RankData('8', '蕉太狼', '7003'),
  new RankData('9', '小灰灰', '6794'),
  new RankData('10', '慢羊羊', '6721')
];

// 初始化排名数据2
const rankData2: RankData[] = [
  new RankData('11', '曹操', '8836'),
  new RankData('12', '马超', '8521'),
  new RankData('13', '关羽', '8431'),
  new RankData('14', '吕布', '7909'),
  new RankData('15', '张飞', '7547'),
  new RankData('16', '赵云', '7433'),
  new RankData('17', '刘备', '7186'),
  new RankData('18', '孙策', '7023'),
  new RankData('19', '黄忠', '6794'),
  new RankData('20', '许褚', '6721')
];

RankViewModel.ets获取排序数据

import { RankData } from './RankData';
import { rankData1, rankData2 } from '../model/DataModel';

// 获取排序数据
export class RankViewModel {
  loadRankDataSource1(): RankData[] {
    return rankData1;
  }

  loadRankDataSource2(): RankData[] {
    return rankData2;
  }
}

RankPage.ets引入排名数据源

  • let rankModel: RankViewModel = new RankViewModel();
  • 通过aboutToAppear函数初始化数据源
import { RankViewModel } from '../viewmodel/RankViewModel';
import { RankData } from '../viewmodel/RankData';
import { APP_EXIT_INTERVAL, Style, TIME, TITLE, WEIGHT } from '../common/constants/Constants';
import { TitleComponent } from '../view/TitleComponent';
import { ListHeaderComponent } from '../view/ListHeaderComponent';

let rankModel: RankViewModel = new RankViewModel();

@Entry
@Component
struct RankPage {

  @State dataSource1: RankData[] = [];
  @State dataSource2: RankData[] = [];
  @State isSwitchDataSource: boolean = true; // 是否切换数据源

  // 初始化数据源
  aboutToAppear() {
    this.dataSource1 = rankModel.loadRankDataSource1();
    this.dataSource2 = rankModel.loadRankDataSource2();
  }

  build() {
    Column() {
      // 标题
      TitleComponent({ isRefreshData: $isSwitchDataSource, title: TITLE })
      // 列表头部
      ListHeaderComponent({
        paddingValue: {
          left: Style.RANK_PADDING,
          right: Style.RANK_PADDING
        },
        widthValue: Style.CONTENT_WIDTH
      })
        .margin({ // 外边距
          top: Style.HEADER_MARGIN_TOP,
          bottom: Style.HEADER_MARGIN_BOTTOM
        })
    }
  }
}

实现排名列表

ListItemComponent .ets代码实现

import { FontSize, FontWeight, ItemStyle, WEIGHT } from '../common/constants/Constants';

@Component
export struct ListItemComponent {
  index?: number;
  private name?: string;
  stepNum: string = '';
  @State isChange: boolean = false;

  build() {
    Row() {
      // 排名
      Column() {
          if (this.isRenderCircleText()) {
            this.CircleText(this.index);
          } else {
            Text(this.index?.toString())
              .lineHeight(ItemStyle.TEXT_LAYOUT_SIZE) // 行高
              .textAlign(TextAlign.Center) // 文本居中
              .width(ItemStyle.TEXT_LAYOUT_SIZE) // 宽度
              .fontWeight(FontWeight.BOLD) // 字体宽度
              .fontSize(FontSize.SMALL) // 字体大小
          }
      }
      .width(ItemStyle.LAYOUT_WEIGHT_LEFT) // 宽度
      .alignItems(HorizontalAlign.Start) // 垂直起始位置对齐

      // 姓名
      Text(this.name)
        .width(ItemStyle.LAYOUT_WEIGHT_CENTER)
        .fontWeight(FontWeight.BOLDER)
        .fontSize(FontSize.MIDDLE)
        // ture:绿色字体,false:黑色字体
        .fontColor(this.isChange ? ItemStyle.COLOR_GREEN : ItemStyle.COLOR_BLACK)
      // 步数
      Text(this.stepNum)
        .width(ItemStyle.LAYOUT_WEIGHT_RIGHT)
        .fontWeight(FontWeight.BOLD)
        .fontSize(FontSize.SMALL)
        .fontColor(this.isChange ? ItemStyle.COLOR_GREEN : ItemStyle.COLOR_BLACK)
    }
    .height(ItemStyle.BAR_HEIGHT)
    .width(WEIGHT)
    .onClick(() => { // 点击事件
      this.isChange = !this.isChange;
    })
  }

  // 圆圈背景
  @Builder CircleText(index: number) {
    Row() {
      Text(this.index?.toString())
        .fontWeight(FontWeight.BOLD)
        .fontSize(FontSize.SMALL)
        .fontColor(Color.White);
    }
    .justifyContent(FlexAlign.Center)
    .borderRadius(ItemStyle.CIRCLE_TEXT_BORDER_RADIUS)
    .size({ width: ItemStyle.CIRCLE_TEXT_SIZE,
      height: ItemStyle.CIRCLE_TEXT_SIZE })
    .backgroundColor($r('app.color.circle_text_background'))
  }

  // 是否显示圆圈
  isRenderCircleText(): boolean {
    return this.index === 1 || this.index === 2 || this.index === 3;
  }
}

应用入口页RankPage引入ListItemComponent组件

  • @Builder RankList装饰的方法用于定义组件的声明式UI描述,在一个自定义组件内快速生成多个布局内容。
import { RankViewModel } from '../viewmodel/RankViewModel';
import { RankData } from '../viewmodel/RankData';
import { APP_EXIT_INTERVAL, Style, TIME, TITLE, WEIGHT } from '../common/constants/Constants';
import { TitleComponent } from '../view/TitleComponent';
import { ListHeaderComponent } from '../view/ListHeaderComponent';
import { ListItemComponent } from '../view/ListItemComponent';

let rankModel: RankViewModel = new RankViewModel();

@Entry
@Component
struct RankPage {

  @State dataSource1: RankData[] = [];
  @State dataSource2: RankData[] = [];
  @State isSwitchDataSource: boolean = true; // 是否切换数据源

  // 初始化数据源
  aboutToAppear() {
    this.dataSource1 = rankModel.loadRankDataSource1();
    this.dataSource2 = rankModel.loadRankDataSource2();
  }

  build() {
    Column() {
      // 标题
      TitleComponent({ isRefreshData: $isSwitchDataSource, title: TITLE })
      // 列表头部
      ListHeaderComponent({
        paddingValue: {
          left: Style.RANK_PADDING,
          right: Style.RANK_PADDING
        },
        widthValue: Style.CONTENT_WIDTH
      })
        .margin({ // 外边距
          top: Style.HEADER_MARGIN_TOP,
          bottom: Style.HEADER_MARGIN_BOTTOM
        })
      // 排名列表
      this.RankList(Style.CONTENT_WIDTH)
    }
    .backgroundColor($r('app.color.background')) // 背景色
    .height(WEIGHT) // 高度
    .width(WEIGHT) // 宽度
  }

  @Builder RankList(widthValue: Length) {
    Column() {
      List() { // 列表
        ForEach(this.isSwitchDataSource ? this.dataSource1 : this.dataSource2,
          (item: RankData, index?: number) => {
            ListItem() {
              ListItemComponent({ index: (Number(index) + 1), name: item.name, stepNum: item.stepNum})
            }
          }, (item: RankData) => JSON.stringify(item))
      }
      .width(WEIGHT) // 宽度
      .height(Style.LIST_HEIGHT) // 高度
      .divider({ strokeWidth: Style.STROKE_WIDTH }) // 分割线
    }
    .padding({ // 内边距
      left: Style.RANK_PADDING,
      right: Style.RANK_PADDING
    })
    .borderRadius(Style.BORDER_RADIUS) // 边框半径
    .width(widthValue) // 宽度
    .alignItems(HorizontalAlign.Center) // 垂直居中对齐
    .backgroundColor(Color.White) // 背景色
  }
}

运行代码:
HarmonyOS开发实战:如何实现一个运动排名榜页面,harmonyos,华为
刷新列表:
HarmonyOS开发实战:如何实现一个运动排名榜页面,harmonyos,华为文章来源地址https://www.toymoban.com/news/detail-779420.html

到了这里,关于HarmonyOS开发实战:如何实现一个运动排名榜页面的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 『牛角书』HarmonyOS鸿蒙实战 开发一个简单聊天助手APP

    我是通过b站上面老师的讲解,跟着老师编写了一个简单聊天助手app,简答实用,对于刚开始接触鸿蒙的我们来说很有帮助。 所用软件为DevEco Studio,点击Create HarmonyOS Project,这里选择了第一个空的项目,点击next会跳至下一个页面。 这里是项目的名称,因为是一个demo,就没有

    2024年02月12日
    浏览(31)
  • OpenHarmony实战开发-如何实现一个轻量级输入法应用。

    ​ 本示例使用inputMethodEngine实现一个轻量级输入法应用kikaInput,支持在运行OpenHarmony OS的智能终端上。 使用说明 1.使用hdc shell aa start ability -a InputMethod -b cn.openharmony.inputmethodchoosedialog命令拉起切换输入法弹窗,点击kikainput切换输入法到当前应用。 2.点击应用中的编辑框,拉起

    2024年04月24日
    浏览(38)
  • 【实战项目开发技术分享】如何解决机器人运动不平稳的问题

    机器人的运动平稳性对于其在各种应用中的成功执行任务至关重要。当机器人在执行任务过程中出现不稳定的运动,可能导致任务失败、损坏周围环境或甚至危及人员安全。因此,解决机器人运动不平稳问题是一个非常重要的挑战。本篇博文将向您介绍一些有效的方法来解决

    2024年02月16日
    浏览(27)
  • 【一步步开发AI运动小程序】十二、自定义一个运动分析器,实现计时计数02

    随着人工智能技术的不断发展,阿里体育等IT大厂,推出的“乐动力”、“天天跳绳”AI运动APP,让 云上运动会、线上运动会、健身打卡、AI体育指导 等概念空前火热。那么,能否将这些在APP成功应用的场景搬上小程序,分享这些概念的红利呢?本系列文章就带您一步一步从

    2024年02月13日
    浏览(32)
  • 【一步步开发AI运动小程序】十二、自定义一个运动分析器,实现计时计数01

    随着人工智能技术的不断发展,阿里体育等IT大厂,推出的“乐动力”、“天天跳绳”AI运动APP,让 云上运动会、线上运动会、健身打卡、AI体育指导 等概念空前火热。那么,能否将这些在APP成功应用的场景搬上小程序,分享这些概念的红利呢?本系列文章就带您一步一步从

    2024年02月09日
    浏览(32)
  • HarmonyOS - 实现多设备协同开发实战教程~

    现在随着个人设备越来越多,越来越需要多个设备之间相互感知和连接,设备和设备之间可以相互联动,形成互联互通的场景,而搭载HarmonyOS的设备恰好可以满足这一点 。下面通过开发一个HarmonyOS的多端分布式表白应用来实现设备之间的相互联动。 H5页面可以实现一些比较特

    2024年02月21日
    浏览(31)
  • HarmonyOS实战开发-通过screenshot模块实现屏幕截图 。

    本示例展示全屏截图和屏幕局部截图。 本示例通过screenshot模块实现屏幕截图 ,通过window模块实现隐私窗口切换,通过display模块查询当前隐私窗口。 使用说明: 点击右上角图标打开弹窗,选择截屏,展示全屏截图;选择局部截屏,选择截屏区域,点击右下角完成,展示局部

    2024年04月13日
    浏览(28)
  • 【运动规划算法项目实战】如何实现机器人多目标点导航

    在ROS机器人应用中,实现机器人多目标点导航是非常常见的需求。本文将介绍如何使用ROS和actionlib来实现机器人的多目标点导航,目标点信息将被记录在YAML文件中。 我们可以通过使用MoveBaseAction来实现机器人的导航功能。MoveBaseAction是一个ROS中的action类型,它提供了控制机器

    2024年02月02日
    浏览(28)
  • 【运动规划算法项目实战】如何实现三次样条插值(附ROS C++代码)

    三次样条插值是一种广泛应用于数据拟合和插值的方法。它通过使用三次多项式在给定的一组数据点之间进行插值,以实现平滑的拟合效果。三次样条插值的优点是可以平滑地拟合给定的数据点,而不会产生震荡或振荡现象。 三次样条插值是机器人路径规划中常用的一

    2024年02月14日
    浏览(32)
  • 【运动规划算法项目实战】如何实现机器人多目标点导航(附ROS C++代码)

    在ROS机器人应用中,实现机器人多目标点导航是非常常见的需求。本文将介绍如何使用ROS和actionlib来实现机器人的多目标点导航,目标点信息将被记录在YAML文件中。 我们可以通过使用MoveBaseAction来实现机器人的导航功能。MoveBaseAction是一个ROS中的action类型,它提供了控制机器

    2024年02月10日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包