HarmonyOS 鸿蒙Next中实现页面停留时间自动统计功能

HarmonyOS 鸿蒙Next中实现页面停留时间自动统计功能 问题现象 需要统计用户在学习页面的停留时间,用于计算每日学习时长目标完成度。

3 回复

原理解析

利用组件的生命周期函数:

  • aboutToAppear:组件即将显示时调用,适合启动计时器
  • aboutToDisappear:组件即将销毁时调用,适合停止计时器并保存数据

解决方案

import { updateTodayProgress } from '../components/LearningGoalCard';

@Entry
@Component
struct StudyDetailPage {
  @State viewDuration: number = 0;
  
  // 计时相关私有变量
  private pageEnterTime: number = 0;
  private timeTracker: number = -1;
  
  aboutToAppear(): void {
    // 记录进入时间
    this.pageEnterTime = Date.now();
    // 启动定时器
    this.startTimeTracking();
  }
  
  aboutToDisappear(): void {
    // 停止计时并保存剩余时间
    this.stopTimeTracking();
  }
  
  startTimeTracking(): void {
    // 每15秒累计一次学习时间
    this.timeTracker = setInterval(() => {
      this.viewDuration += 15;
      // 更新今日学习进度(秒数)
      updateTodayProgress('seconds', 15);
    }, 15000);
  }
  
  stopTimeTracking(): void {
    if (this.timeTracker !== -1) {
      clearInterval(this.timeTracker);
      this.timeTracker = -1;
    }
    // 计算剩余不足15秒的时间(超过5秒才计入)
    const elapsed = Math.floor((Date.now() - this.pageEnterTime) / 1000) % 15;
    if (elapsed >= 5) {
      updateTodayProgress('seconds', elapsed);
    }
  }
  
  // 格式化显示时长
  formatDuration(seconds: number): string {
    if (seconds < 60) return `${seconds}秒`;
    const minutes = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return secs > 0 ? `${minutes}分${secs}秒` : `${minutes}分钟`;
  }
  
  build() {
    Column() {
      // 显示学习时长
      Row({ space: 4 }) {
        Text('⏱️').fontSize(14)
        Text(`已学习 ${this.formatDuration(this.viewDuration)}`)
          .fontSize(13)
          .fontColor('#666666')
      }
      // ... 其他内容
    }
  }
}

进度更新函数实现

// LearningGoalCard.ets
export function updateTodayProgress(
  type: 'case' | 'quiz' | 'seconds', 
  value: number = 1
): void {
  const today = new Date().toDateString();
  const savedDate = storageUtil.getStringSync('progressDate', '');
  
  // 初始化或获取今日进度
  let progress: TodayProgress = { 
    casesViewed: 0, 
    quizzesCompleted: 0, 
    minutesLearned: 0 
  };
  
  if (savedDate === today) {
    const saved = storageUtil.getStringSync('todayProgress', '');
    if (saved) {
      try { progress = JSON.parse(saved); } catch (e) {}
    }
  } else {
    // 新的一天,重置进度
    storageUtil.setString('progressDate', today);
  }
  
  // 根据类型更新
  switch (type) {
    case 'case':
      progress.casesViewed += value;
      break;
    case 'quiz':
      progress.quizzesCompleted += value;
      break;
    case 'seconds':
      // 累计秒数,转换为分钟
      const currentSeconds = storageUtil.getNumberSync('todayLearnSeconds', 0);
      const newSeconds = currentSeconds + value;
      storageUtil.setNumber('todayLearnSeconds', newSeconds);
      progress.minutesLearned = Math.floor(newSeconds / 60);
      break;
  }
  
  storageUtil.setString('todayProgress', JSON.stringify(progress));
}

更多关于HarmonyOS 鸿蒙Next中实现页面停留时间自动统计功能的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,可通过页面生命周期回调自动统计停留时间。在onPageShow记录进入时间戳,在onPageHide计算停留时长并上报。使用@State存储时间数据,结合LocalStorageAppStorage进行跨页面数据管理。注意避免统计页面切换时的误差,确保时间记录的准确性。

在HarmonyOS Next中实现页面停留时间自动统计,可以通过监听页面的生命周期并计算时间差来完成。以下是核心实现思路:

  1. 记录时间戳:在页面的aboutToAppear生命周期中记录进入时间(如使用Date.now()performance.now()),在aboutToDisappear中记录离开时间。

  2. 计算停留时长:在离开时计算时间差(离开时间 - 进入时间),得到本次停留的毫秒数。

  3. 数据持久化与上报:将时长累加到本地存储(如使用PreferencesRdb),并可选择在合适时机上报至服务器。

  4. 注意事项

    • 考虑应用切换到后台的情况(如接电话),需在onPageHide中记录暂停,在onPageShow中恢复计时。
    • 多页面跳转时需确保每个页面独立计时,避免重复或遗漏。

示例代码片段(ArkTS):

@Entry
@Component
struct StudyPage {
  private startTime: number = 0;
  private totalTime: number = 0; // 本地累计时间

  aboutToAppear() {
    this.startTime = Date.now();
  }

  aboutToDisappear() {
    const endTime = Date.now();
    const duration = endTime - this.startTime;
    this.totalTime += duration;
    // 保存到Preferences
    Preferences.put('studyDuration', this.totalTime);
  }
}

此方法可准确统计单次页面访问时长,结合后台状态监听可完善连续学习时长的统计需求。

回到顶部