Programmatic Views how to set unique id's?

Barmaley picture Barmaley · Jul 22, 2011 · Viewed 28.3k times · Source

I am creating in my app bunch of programmatic Views. As it appeared to be they all by default have the same id=-1. In order to work with them I need to generate unique id's.

I have tried several approaches - random number generation and based on current time, but anyway there's no 100% guarantee that different Views will have different id's

Just wondering is there any more reliable way to generate unique ones? Probably there's special method/class?

Answer

X.Y. picture X.Y. · Mar 15, 2013

Just want to add to Kaj's answer, from API level 17, you can call

View.generateViewId()

then use the View.setId(int) method.

In case you need it for targets lower than level 17, here is its internal implementation in View.java you can use directly in your project:

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

ID number larger than 0x00FFFFFF is reserved for static views defined in the /res xml files. (Most likely 0x7f****** from the R.java in my projects.)

From the code, somehow Android doesn't want you to use 0 as a view's id, and it needs to be flipped before 0x01000000 to avoid the conflits with static resource IDs.