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

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


当前回答

我的选择:

// Method that could us an unique id

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

其他回答

这对我来说很管用:

static int id = 1;

// Returns a valid id that isn't in use
public int findId(){  
    View v = findViewById(id);  
    while (v != null){  
        v = findViewById(++id);  
    }  
    return id++;  
}

为了动态生成视图Id表单API 17使用

generateViewId ()

这将生成一个适合在setId(int)中使用的值。该值不会与aapt在构建时为r.d ID生成的ID值冲突。

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

Compat库现在还支持API级别之前的generateViewId()方法。

只要确保使用27.1.0以上版本的Compat库即可

例如,在您的构建中。Gradle文件,放入:

实现“com.android.support: appcompat-v7:27.1.1

然后你可以简单地使用来自ViewCompat类的generateViewId()而不是View类,如下所示:

//将分配唯一的ID myView。id = ViewCompat.generateViewId()

编码愉快!

只是对@phantomlimb的答案的补充,

而View.generateViewId()要求API级别>= 17, 该工具与所有API兼容。

根据现时的空气污染指数, 它决定天气是否使用系统API。

所以你可以使用ViewIdGenerator.generateViewId()和View.generateViewId() 同样的时间,不用担心得到相同的id

import java.util.concurrent.atomic.AtomicInteger;

import android.annotation.SuppressLint;
import android.os.Build;
import android.view.View;

/**
 * {@link View#generateViewId()}要求API Level >= 17,而本工具类可兼容所有API Level
 * <p>
 * 自动判断当前API Level,并优先调用{@link View#generateViewId()},即使本工具类与{@link View#generateViewId()}
 * 混用,也能保证生成的Id唯一
 * <p>
 * =============
 * <p>
 * while {@link View#generateViewId()} require API Level >= 17, this tool is compatibe with all API.
 * <p>
 * according to current API Level, it decide weather using system API or not.<br>
 * so you can use {@link ViewIdGenerator#generateViewId()} and {@link View#generateViewId()} in the
 * same time and don't worry about getting same id
 * 
 * @author fantouchx@gmail.com
 */
public class ViewIdGenerator {
    private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);

    @SuppressLint("NewApi")
    public static int generateViewId() {

        if (Build.VERSION.SDK_INT < 17) {
            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;
                }
            }
        } else {
            return View.generateViewId();
        }

    }
}