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

3

15

We are using nativescript with angular for our mobile app. I want to use the Google Play pre-launch report feature, but our app requires a password to be entered. Google Play allows specifying a password but you need a resource name so the testing script can identify where to put the password.

How can I specify or receive the resource name of a nativescript textfield, either in the view or by code behind or via any other means?

The view in question:

      <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>

I did some research and found out that in native android, one could add an id to a TextField by adding an android:id attribute.

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

This does not seem to work in nativescript, I cannot find the resource in R.java afterwards.

Meunier answered 4/4, 2018 at 9:2 Comment(1)
Please have a look at my answerPilpul
P
5

Edit: Turns out I misunderstood OP's question, which was "how to use native Android view ID's for NativeScript's visual components". Instead I answered the question "how to use native Android strings in NativeScript".

I ended up answering the original question on a separate answer here, and this answer will still be about using native Android strings in NativeScript, because I think that is more useful than using native Android ID's.

How to use native Android strings in NativeScript

For accessing Android native resources you can use methods getApplication() and getStringId() from the Util package, like so:

// 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')

I set up a simple example in 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, line 28, where the native string is applied to a label object.

Pilpul answered 15/4, 2018 at 0:0 Comment(8)
O.K. and how would you assign this string or numerical id to a e.g. TextField, so that google pre-launch can identify the text field via the given id? I did not see any setter or something like this in the API.Meunier
I added the string to the XML's view model, and then referenced that string from the XML, so your TextField won't use the Android ID itself, just the string. Have a look atmain-view-model.js and main-page.xml at github.com/leoacevedo/…Pilpul
I am not looking for that. I do not want to assign an android string id to a text fields value, but I want to assign the id to the field, so that i can identify that text field via that id programatically.Meunier
Then I misunderstood you. I will write a separate answer for addressing that, although I don't think that using those ID's it will be very useful for youPilpul
There it is. Hopefully I got it right this time! :)Pilpul
Can I specify which string.xml to use?Dandy
@Dandy just the regular strings.xmlPilpul
Can someone show an example for angular? The solutiona above dont works for me...Chevy
D
3

First of all, you need to add a file app/App_Resources/Android/src/main/res/values/ids.xml with the content:

<?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>

Then in your view, make sure to add an id to both TextFields and the submit button. The id from your view doesn't have to match the one in the ids.xml, but in my example they do:

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

Finally, in your view controller, in the loaded method:

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);
}
Deroo answered 11/8, 2019 at 0:15 Comment(2)
How are you getting android.R? is that an import?Kobarid
@FelipeCenteno android is a global variable in NS docs.nativescript.org/core-concepts/android-runtime/metadata/…Deroo
P
2

How to use native Android ID's as ID's for NativeScript's visual components

First, while you can use Android native IDs as NS ID's, native Android won't do anything useful with that. In particular, your NS view with an Android native ID will not be found if you use Android's View.findViewById().

In NativeScript's source code, the file where NativeScript's view ID's are defined (view-base.ts), no reference to native Android can be found, which means that NativeScript's view ID's and those of Android have effectively no relationship or interaction. Moreover, I looked for Android view ID's with a native Android tool called Stetho, and found NativeScript's views don't have ID's at all, even if NativeScript's XML files do define view ID's.

To answer your question, there is a way to give native Android ID's to NativeScript, by using view models.

Let's suppose that you want to use Android "@+id/nameTextbox" in XML. In Java, that would translate to R.id.nameTextBox, so in your NativeScript XML you write:

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

The use of curly brackets means you need to get R.id.nameTextbox from the view model, so in the view model creation function you add:

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

is the applicationId of your Android app, which you can find on app/App_Resources/Android/app.gradle.

That line makes your R class visible to your XML views, so you can use the values in R.id not only as ID's but also as text for your TextFields and labels. If you do that, you will see that the Android ID's are really long integers, not strings.

Another thing to keep in mind is that R on Android is the class that collects all the resource ID's on a library or an app, and that it is generated at build time. Therefore, if you would like give your view the ID R.id.totallyNewId, which your Android project doesn't have right now, you would have to create it from on Android, which is not very convenient (here is how)

So as a conclusion, using R.id on NativeScript can be done, but there is no reason why you would ever want to do it.

Pilpul answered 18/4, 2018 at 5:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.