Maciej Dobosz
Maciej Dobosz

Reputation: 158

Android: Find an ID of dynamically created view

I've got a following problem:

In Android Studio I generate en EditText dynamically when an ExerciseButton is clicked:

public void exerciseButtonClick(View view) {
  EditText exercise = new EditText(this);
  exercise.setId(exerciseId);
  exerciseId++;
}

Later in the code I would like to refer to all my EditText's via ID. I'm trying something like this but this is not working:

for (int i = 1; i < exerciseId; i++) {
                EditText currentEditText = (EditText) findViewById(i);
                // further instructions on that EditText
}

The error is of course here: findViewById(i), showing Expected resource type to be on of id. How can I solve this problem?

Upvotes: 4

Views: 5261

Answers (3)

Robert Estivill
Robert Estivill

Reputation: 12497

You need to make sure the ID doesn't clash with the Android generated id's. Also, you need to make sure you add the views to the activity view hierarchy, otherwise they will never be found.

In your scenario, i would probably try one of the following things

1) If you still want to use integer id's, then use this method to generate a valid non-clashing id

https://developer.android.com/reference/android/view/View.html#generateViewId

2) Set tag to the view, and retrieve by tag. Tag can be any object.

public void exerciseButtonClick(View view) {
  EditText exercise = new EditText(this);
  exercise.setTag("exercise-" + excersiceId);
  excersiceId++;
}


EditText exercise = (EditText)findViewByTag("exercise-" + someId );

3) Keep a local variable, holding the reference to the created EditText (or to the created array of EditTexts)

private EditText exercise;

public void exerciseButtonClick(View view) {
  exercise = new EditText(this);
  excersiceId++;
}

Upvotes: 5

Anmol317
Anmol317

Reputation: 1376

you can add the textView which u are adding in a ArrayList side by side and add a position tag with it as well, according to the size of the arraylist like this.

arrayList.add(textView);
textView.setTag(arraylist.size());

Then onClickListener you can get the tag doing

onClick(View view){
if (view == arraylist.get(Integer.parseInt(view.getTag()))){
 // do onClick coding here
}
}

and use that tag to implement different clickListenrs.

Upvotes: 2

Niki van Stein
Niki van Stein

Reputation: 10744

This is because you need to generate appropriate ids that do not clash with existing ids, and then store these ids in an array for example such that you know which are used for your generated views.

In API 17 and above you can just use the function View.generateViewId() to generate this id.

And otherwise you can use this code (from this answer):

private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);

/**
 * Generate a value suitable for use in {@link #setId(int)}.
 * This value will not collide with ID values generated at build time by aapt for R.id.
 *
 * @return a generated ID value
 */
public static int generateViewId() {
    for (;;) {
        final int result = sNextGeneratedId.get();
        // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
        int newValue = result + 1;
        if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
        if (sNextGeneratedId.compareAndSet(result, newValue)) {
            return result;
        }
    }
}

Upvotes: 2

Related Questions