HarmonyOS鸿蒙Next中通过onBackPress实现app侧滑2次退出应用

HarmonyOS鸿蒙Next中通过onBackPress实现app侧滑2次退出应用 通过onBackPress实现app侧滑2次退出应用

5 回复

特别简单,直接上代码:

import { systemDateTime } from '@kit.BasicServicesKit';

@Entry
@Component
struct Index {
  @State mBackTime: number = 0;
  @State message: string = '再侧滑一次退出应用';


  onBackPress(): boolean | void {
    let time: number = systemDateTime.getTime(false);
    if ((time - this.mBackTime) > 2000) {
      this.mBackTime = time;
      this.getUIContext().getPromptAction().showToast({
        message: this.message,
        duration: 800
      })
      return true
    }else {
      return false
    }
  }

  build() {
    Column(){
      Text('首页')
        .fontSize(40)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

更多关于HarmonyOS鸿蒙Next中通过onBackPress实现app侧滑2次退出应用的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


private lastBackPressTime:number=0
onBackPress(): boolean | void {
  const now = new Date().getTime()
  if (now - this.lastBackPressTime < 1500) {
    return false
  } else {
    this.lastBackPressTime = now
    ToastUtils.showToast('再按一次退出应用')
    return true
  }
}

效果

图片

思路

private isSecondPressBack: boolean = false; // 在侧滑退出应用时,用于判断是否第二次滑动


// 侧滑返回拦截功能:用于首页侧滑返回时,需在1秒内侧滑两次才能退出应用
onBackPress() {
  if (this.isSecondPressBack) {
    return false;
  } else {
    this.isSecondPressBack = true;
    setTimeout(() => {
      this.isSecondPressBack = false;
    }, 1000);
    promptAction.showToast({
      message: '再滑一次退出',
      duration: 1800
    });
    return true;
  }
}

完整代码

import { BackTop } from '../components/BackTop'
import { SeckillGoods } from '../components/index/SeckillGoods'
import { SwiperNav } from '../components/index/SwiperNav'
import { NavBar } from '../components/NavBar'
import { TabBar } from '../components/TabBar'
import { WaterFlowGoods } from '../components/WaterFlowGoods'
import { promptAction, router } from '@kit.ArkUI'
import { Dialog } from '../components/Dialog'

@Entry
@Component
struct Index {

  // @StorageProp('bottomRectHeight') bottomRectHeight: number = 0;
  // @StorageProp('topRectHeight') topRectHeight: number = 0;

  private indexAdDialog = new Dialog(this.getUIContext(), 'indexAd', {
    ok: () => {},
    cancel:() => {
      this.indexAdDialog.close()
    },
  })

  aboutToAppear() {
    console.log('index aboutToAppear')
    this.indexAdDialog.open()
  }


  // onBackPress() {
  //   console.log('index onBackPress')
  //   // return false // 允许用户侧滑退出
  //   // return true // 禁止用户侧滑退出
  // }

  private isSecondPressBack: boolean = false; // 在侧滑退出应用时,用于判断是否第二次滑动


  // 侧滑返回拦截功能:用于首页侧滑返回时,需在1秒内侧滑两次才能退出应用
  onBackPress() {
    if (this.isSecondPressBack) {
      return false;
    } else {
      this.isSecondPressBack = true;
      setTimeout(() => {
        this.isSecondPressBack = false;
      }, 1000);
      promptAction.showToast({
        message: '再滑一次退出',
        duration: 1800
      });
      return true;
    }
  }

  @Builder NavBarMiddleBuilder() {
    Search({placeholder: '新人活动0.01'})
        .layoutWeight(1).backgroundColor(Color.White).margin({left:10,right:10})
        .height(30)
        .searchIcon({
          size: 25,
          color: Color.Red
        })
        .onClick(() => router.pushUrl({url: 'pages/SearchHot'}))
  }

  build() {
    Column() {
      // BackTop()
      // 导航栏
      NavBar({
        // LeftBuilder:UI数据
        left: 'menu',
        // middle: '首页',
        MiddleBuilder:  this.NavBarMiddleBuilder,
        right: '登录',
        // RightBuilder: ui数据
      })

      // 内容部分
      BackTop() {
        Column() {
          // 轮播图导航
          SwiperNav()
          // 秒杀
          SeckillGoods()
          // 瀑布流
          WaterFlowGoods()
        }.width('100%').layoutWeight(1).backgroundColor('#f3f5f7').padding({bottom:20})
      }

      // .layoutWeight(1).width('100%').backgroundColor('#f6f6f6').align(Alignment.Top) // 父的主轴方向剩余空间
      // 底部栏
      TabBar({ activeIndex: 0 })
    }
    // .padding({ top: px2vp(this.topRectHeight), bottom: px2vp(this.bottomRectHeight) })
  }
}

在HarmonyOS Next中,通过重写onBackPress方法并配合计时器可实现侧滑两次退出应用。具体是在onBackPress回调中,首次触发时显示提示(如“再按一次退出应用”),并启动一个定时器(如2秒)。若在定时器超时前再次触发onBackPress,则调用terminateSelf()退出应用;若超时后触发,则重置状态,重新提示。此逻辑需在Ability或Page的onBackPress中实现。

在HarmonyOS Next中,可以通过重写AbilityonBackPress()方法,并配合计时器来实现“侧滑(或按返回键)两次退出应用”的功能。这是一种常见的用户体验优化,防止用户误操作退出。

核心实现步骤:

  1. 定义状态变量:在Ability类中,定义两个private变量。

    private isExitPressedOnce: boolean = false; // 标记是否为第一次按下返回
    private exitTimer: number | null = null; // 用于清除定时器的引用
    
  2. 重写 onBackPress 方法:在您的Ability(例如EntryAbility)中重写该方法。

    onBackPress(): boolean {
      if (!this.isExitPressedOnce) {
        // 第一次按下返回键
        this.isExitPressedOnce = true;
        // 提示用户再按一次退出
        promptAction.showToast({
          message: '再按一次退出应用',
          duration: 2000 // 提示显示时长,即两次按下的有效间隔
        });
        // 设置一个定时器,超过时间后重置状态
        this.exitTimer = setTimeout(() => {
          this.isExitPressedOnce = false;
          this.exitTimer = null;
        }, 2000); // 这里设置2秒,与Toast时长保持一致
        // 返回 true 表示消费了本次返回事件,阻止默认的退出行为
        return true;
      } else {
        // 第二次按下返回键
        // 清除可能存在的定时器
        if (this.exitTimer) {
          clearTimeout(this.exitTimer);
          this.exitTimer = null;
        }
        // 执行应用退出逻辑
        this.context.terminateSelf();
        // 返回 true 或 false 均可,因为应用即将终止
        return true;
      }
    }
    

关键点说明:

  • 事件消费onBackPress()方法返回true表示当前Ability已经消费了返回事件,系统不会执行默认的退出操作。返回false则交给系统处理。
  • 状态管理:通过isExitPressedOnce布尔值来区分是第一次还是第二次触发。
  • 定时重置:利用setTimeout在第一次触发后开始计时(例如2秒),超时后自动将状态重置,要求用户重新进行“两次操作”的流程。
  • 资源清理:在第二次触发退出时,需要清理之前设置的定时器,避免内存泄漏。
  • 提示用户:使用@ohos.promptActionshowToast方法给用户明确的视觉反馈,这是该交互模式的重要组成部分。

注意事项:

  • 此逻辑通常放在应用的主Ability(如EntryAbility)中。如果应用有多个Ability栈或复杂的页面导航,需要根据具体业务逻辑调整,可能需要在PageonBackPress中也进行类似处理,并通过事件等方式与Ability通信。
  • terminateSelf()会终止当前Ability。对于单实例的EntryAbility,这通常意味着退出整个应用。
  • 定时器的时长(2000毫秒)和Toast提示的时长应保持一致,以提供一致的交互体验。

这种实现方式简洁有效,是HarmonyOS应用实现“两次返回退出”的标准方法。

回到顶部