Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 937
Paul Weber Avatar asked Apr 04 '18 09:04

Paul Weber


2 Answers

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.

like image 171
Leo supports Monica Cellio Avatar answered Nov 05 '22 15:11

Leo supports Monica Cellio


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);
}
like image 29
Nicu Surdu Avatar answered Nov 05 '22 14:11

Nicu Surdu