NativeScript 处理后退按钮事件

Posted

技术标签:

【中文标题】NativeScript 处理后退按钮事件【英文标题】:NativeScript handling back button event 【发布时间】:2017-03-28 23:11:47 【问题描述】:

我正在尝试处理 NativeScript 应用程序中的硬件后退按钮。我正在使用带有 Angular 的 NativeScript 2.3.0 版。

这是我在 main.ts 文件中的内容

// this import should be first in order to load some required settings (like globals and reflect-metadata)
import  platformNativeScriptDynamic, NativeScriptModule  from "nativescript-angular/platform";
import  NgModule,Component,enableProdMode  from "@angular/core";
import  AppComponent  from "./app.component";
import  NativeScriptRouterModule  from "nativescript-angular/router";
import  routes, navigatableComponents  from "./app.routing";
import  secondComponent  from "./second.component";
import androidApplication from "application";
@Component(
    selector: 'page-navigation-test',
    template: `<page-router-outlet></page-router-outlet>`
)
export class PageNavigationApp 

@NgModule(
    declarations: [AppComponent,PageNavigationApp,secondComponent
        // ...navigatableComponents
        ],
    bootstrap: [PageNavigationApp],
    providers:[AndroidApplication],
    imports: [NativeScriptModule,
        NativeScriptRouterModule,
    NativeScriptRouterModule.forRoot(routes)
    ],
)
class AppComponentModule 

    constructor(private androidapplication:AndroidApplication)
        this.androidapplication.on("activityBackPressed",()=>
            console.log("back pressed");

        )
    



enableProdMode();

platformNativeScriptDynamic().bootstrapModule(AppComponentModule);

我正在使用

导入应用程序

import AndroidApplication from "application";

然后在appComponentModule 的构造函数中,我正在为activityBackPressed 注册事件并且只是在做一个console.log。

这不起作用。

我在这里错过了什么?

【问题讨论】:

【参考方案1】:

我也在使用带有 Angular 的 NativeScript,这对我来说似乎工作得很好:

import  RouterExtensions  from "nativescript-angular";
import * as application from "tns-core-modules/application";
import  AndroidApplication, AndroidActivityBackPressedEventData  from "tns-core-modules/application";

export class HomeComponent implements OnInit 
  constructor(private router: Router) 
    
  ngOnInit() 
    if (application.android) 
      application.android.on(AndroidApplication.activityBackPressedEvent, (data: AndroidActivityBackPressedEventData) => 
        if (this.router.isActive("/articles", false)) 
          data.cancel = true; // prevents default back button behavior
          this.logout();
        
      );
    
  

请注意,挂钩到 backPressedEvent 是全局性的,因此您需要根据上面的示例检查您所在的页面并采取相应措施。

【讨论】:

感谢 eddy,但我如何以编程方式退出应用程序..我希望后退按钮在主视图中退出应用程序,正如您在以下答案中提到的那样,这不是最佳实践. ***.com/questions/41307447/… 我猜如果您的导航堆栈为“空”,则按下后退按钮应该退出应用程序。 暂时使用这些实用程序github.com/NathanaelA/nativescript-master-technology @EddyVerbruggen 我还需要添加.off 方法吗?如果有怎么办? @EddyVerbruggen:请帮助解决这个问题:***.com/questions/49732360/…【参考方案2】:

import  Component, OnInit  from "@angular/core";
import * as Toast from 'nativescript-toast';
import  Router  from "@angular/router";
import * as application from 'application';

@Component(
  moduleId: module.id,
  selector: 'app-main',
  templateUrl: './main.component.html',
  styleUrls: ['./main.component.css']
)
export class MainComponent 
  tries: number = 0;
  constructor(
    private router: Router
  ) 
    if (application.android) 
      application.android.on(application.AndroidApplication.activityBackPressedEvent, (args: any) => 
        if (this.router.url == '/main') 
          args.cancel = (this.tries++ > 0) ? false : true;
          if (args.cancel) Toast.makeText("Press again to exit", "long").show();
          setTimeout(() => 
            this.tries = 0;
          , 2000);
        
      );
    
  

【讨论】:

不错的解决方案,但代码有点讨厌,为什么不通过只编写一个字符变量等来提高效率,以便编译器可以更快地读取代码【参考方案3】:

通常您应该有一个 android 活动并在该活动上声明 backpress 函数。仅使用 AndroidApplication 是不够的。试试这个代码:

import topmost from "ui/frame";
import AndroidApplication from "application";

let activity = AndroidApplication.startActivity ||
            AndroidApplication.foregroundActivity ||
            topmost().android.currentActivity ||
            topmost().android.activity;

activity.onBackPressed = function() 
    // Your implementation

例如你也可以看看这个snippet

【讨论】:

【参考方案4】:

据我所知,NativeScript 对此有内置支持,但根本没有记录。 使用 onBackPressed 回调,您可以处理 View 组件(例如 Frame、Page、BottomNavigation)的后退按钮行为。

例子:

function pageLoaded(args) 
  var page = args.object;
  page.onBackPressed = function () 
    console.log("Returning true will block back button default behaviour.");
    return true;
  ;
  page.bindingContext = homeViewModel;


exports.pageLoaded = pageLoaded;

这里的棘手之处在于找出在您的应用中哪个视图处理后退按钮按下。在我的例子中,我使用了一个包含页面的 TabView,但 TabView 本身处理了事件而不是当前页面。

【讨论】:

以上是关于NativeScript 处理后退按钮事件的主要内容,如果未能解决你的问题,请参考以下文章

Nativescript后退按钮未重定向到正确的页面

为啥我的 Nativescript-vue 应用程序在呈现模态之前使用硬件后退按钮时崩溃?

android中的后退按钮打破nativescript-vue访问控制登录注销

本机脚本 |在android后退按钮导航后调用ngOnInit

浏览器后退按钮处理

处理 Windows Phone 应用中的“后退”按钮 (XAML)