如何指定或获取 nativescript 文本字段的资源 ID

How can I specify or get the resource id of a nativescript textfield

我们正在为我们的移动应用程序使用带 angular 的 nativescript。我想使用 Google Play 预发布报告功能,但我们的应用需要输入密码。 Google Play 允许指定密码,但您需要一个资源名称,以便测试脚本可以识别将密码放在哪里。

如何在视图中或通过代码隐藏或通过任何其他方式指定或接收 nativescript 文本字段的资源名称?

相关视图:

      <StackLayout class="form">
    <GridLayout columns="*,90" rows="50">
      <TextField #inviteTx
        col="0"
        height="50"
        autocorrect="false"
        returnKeyType="next"
        (returnPress)="enter(inviteTx.text)"
        class="input input-border"
        secure="false"
        keyboardType="url">
      </TextField>
      <Button col="1" height="50" class="btn btn-primary w-full fa" text="START &#xf105;" (tap)="enter(inviteTx.text)"></Button>
    </GridLayout>
  </StackLayout>

我做了一些研究,发现在原生 android、one could add an id to a TextField by adding an android:id attribute 中。

<TextView android:id="@+id/nameTextbox"/>

这在 nativescript 中似乎不起作用,之后我在 R.java 中找不到资源。

编辑: 原来我误解了 OP 的问题,即“如何为 NativeScript 的可视组件使用原生 Android 视图 ID”。相反,我回答了问题“如何在 NativeScript 中使用原生 Android 字符串”。

我最后在这里用一个单独的答案回答了原来的问题,这个答案仍然是关于在 NativeScript 中使用原生 Android 字符串,因为我认为这比使用原生 Android 更有用] ID。

如何在 NativeScript 中使用原生 Android 字符串

要访问 Android 本机资源,您可以使用 the Util package 中的方法 getApplication()getStringId(),如下所示:

// This module will give us access to the native Android context
// See https://docs.nativescript.org/core-concepts/utils
var utilsModule = require("tns-core-modules/utils/utils");

// This method receives a native Android string ID name (like "example_string"),
// and it returns a native Android integer ID
const getAndroidStringId = utilsModule.ad.resources.getStringId;

// Android Application object.
// This object's getString() method receives a native Android integer ID,
// and returns an actual Android native string
const androidApp = utilsModule.ad.getApplication()

/*
 *  @param id: a string with the name of the native ID
 *  @return  : the native Android string with that ID
 */
function getAndroidNativeString(idName) {
    var androidId = getAndroidStringId(idName);
    return androidApp.getString(androidId);
}

// This is how you use it
const nativeAndroidString = getAndroidNativeString('example_string_id')

我在第 28 行 this repo, which uses function code to show an Android native string at the top of the 42-click app from nativescript create. Look at file app/main-view-model.js, where the string obtained from native Android and added to the view model, and file app/main-page.xml 中设置了一个简单示例,其中将本机字符串应用于标签对象。

如何使用原生 Android ID 作为 NativeScript 可视组件的 ID

首先,虽然您可以使用 Android 本机 ID 作为 NS ID,但本机 Android 不会做任何有用的事情。特别是,如果您使用 Android 的 View.findViewById(),将找不到具有 Android 本机 ID 的 NS 视图。

NativeScript's source code, the file where NativeScript's view ID's are defined (view-base.ts) 中,找不到对原生 Android 的引用,这意味着 NativeScript 的视图 ID 和 Android 的视图 ID 实际上没有任何关系或交互。此外,我使用名为 Stetho 的本机 Android 工具查找 Android 视图 ID,发现 NativeScript 的视图根本没有 ID,即使 NativeScript 的 XML 文件确实定义了视图 ID。

为了回答您的问题,有一种方法可以使用视图模型为 NativeScript 提供原生 Android ID。

假设您要在 XML 中使用 Android "@+id/nameTextbox"。在 Java 中,这将转换为 R.id.nameTextBox,所以在你的 NativeScript XML 中你写:

<TextField id="{{R.id.nameTextbox}}"/>

大括号的使用意味着你需要从视图模型中获取R.id.nameTextbox,所以在视图模型创建函数中你添加:

viewModel.R = <your.application.id>.R

是您的 Android 应用程序的 applicationId,您可以在 app/App_Resources/Android/app.gradle.

上找到它

该行使您的 R class 对您的 XML 视图可见,因此您不仅可以将 R.id 中的值用作 ID,还可以将其用作 text你的 TextFields 和标签。如果这样做,您会看到 Android ID 是非常长的整数,而不是字符串。

要记住的另一件事是 Android 上的 R 是 class,它收集库或应用程序上的所有资源 ID,并且它是在构建时生成的。因此,如果您想为视图提供 ID R.id.totallyNewId,您的 Android 项目现在没有,您必须从 Android 开始创建它,这不是很方便方便(here is how)

总而言之,在 NativeScript 上使用 R.id 是可以做到的,但您没有理由想要这样做。

首先,您需要添加一个文件app/App_Resources/Android/src/main/res/values/ids.xml,内容为:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <item type="id" name="email_input" />
  <item type="id" name="pass_input" />
  <item type="id" name="submit_btn" />
</resources>

然后在您的视图中,确保向 TextField 和提交按钮添加一个 id。您认为的 id 不必与 ids.xml 中的相匹配,但在我的示例中它们是:

<Page loaded="loaded">
  <TextField id="email_input" />
  <TextField secure="true" id="pass_input" />
  <Button id="submit_btn" />
</Page>

最后,在您的视图控制器中,在 loaded 方法中:

function loaded(args) {
  const page = args.object;

  const emailInput = page.getViewById("email_input");
  const passInput = page.getViewById("pass_input");
  const submitBtn = page.getViewById("submit_btn");

  emailInput.android.setId(android.R.id.email_input);
  passInput.android.setId(android.R.id.pass_input);
  submitBtn.android.setId(android.R.id.submit_btn);
}