我在for循环中以编程方式添加TextViews,并将它们添加到数组列表中。

我如何使用TextView。setId (int id) ?我要用什么样的整数ID才能不与其他ID冲突?


当前回答

int fID;
do {
    fID = Tools.generateViewId();
} while (findViewById(fID) != null);
view.setId(fID);

...

public class Tools {
    private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
    public static int generateViewId() {
        if (Build.VERSION.SDK_INT < 17) {
            for (;;) {
                final int result = sNextGeneratedId.get();
                int newValue = result + 1;
                if (newValue > 0x00FFFFFF)
                    newValue = 1; // Roll over to 1, not 0.
                if (sNextGeneratedId.compareAndSet(result, newValue)) {
                    return result;
                }
            }
        } else {
            return View.generateViewId();
        }
    }
}

其他回答

根据查看文档

标识符在这个视图的层次结构中不必是唯一的。标识符应该是一个正数。

你可以使用任何你喜欢的正整数,但在这种情况下,可以有一些具有等效id的视图。如果你想在层次结构中搜索某个视图,调用带有一些关键对象的setTag可能会很方便。

受到@dilettante answer的启发,下面是我在kotlin中作为扩展函数的解决方案:

/* sets a valid id that isn't in use */
fun View.findAndSetFirstValidId() {
    var i: Int
    do {
        i = Random.nextInt()
    } while (findViewById<View>(i) != null)
    id = i
}

我的选择:

// Method that could us an unique id

    int getUniqueId(){
        return (int)    
                SystemClock.currentThreadTimeMillis();    
    }

你也可以在res/values中定义ids.xml。你可以在android的示例代码中看到一个确切的例子。

samples/ApiDemos/src/com/example/android/apis/RadioGroup1.java
samples/ApiDemp/res/values/ids.xml
public String TAG() {
    return this.getClass().getSimpleName();
}

private AtomicInteger lastFldId = null;

public int generateViewId(){

    if(lastFldId == null) {
        int maxFld = 0;
        String fldName = "";
        Field[] flds = R.id.class.getDeclaredFields();
        R.id inst = new R.id();

        for (int i = 0; i < flds.length; i++) {
            Field fld = flds[i];

            try {
                int value = fld.getInt(inst);

                if (value > maxFld) {
                    maxFld = value;
                    fldName = fld.getName();
                }
            } catch (IllegalAccessException e) {
                Log.e(TAG(), "error getting value for \'"+ fld.getName() + "\' " + e.toString());
            }
        }
        Log.d(TAG(), "maxId="+maxFld +"  name="+fldName);
        lastFldId = new AtomicInteger(maxFld);
    }

    return lastFldId.addAndGet(1);
}