Java 动态名称

Java Dynamic Names

我知道,Java 没有预处理器,所以有些东西在 java 中或多或少是不可能的。

真的有 NO 方法在循环中用动态名称填充这些数组吗? 我想要类似的东西:

for(int i=0;i<5;i++){
earnTvs[i]=(TextView) findViewById(R.id.INSERT_GREAT_TRICK_HERE("earn"+i+"Tv"));
}

而不是

    earnTvs[0] = (TextView) findViewById(R.id.earn1Tv);
    earnTvs[1] = (TextView) findViewById(R.id.earn2Tv);
    earnTvs[2] = (TextView) findViewById(R.id.earn3Tv);
    earnTvs[3] = (TextView) findViewById(R.id.earn4Tv);
    earnTvs[4] = (TextView) findViewById(R.id.earn5Tv);
    timeTvs[0] = (TextView) findViewById(R.id.time1Tv);
    ...
    ownTvs[0] = (TextView) findViewById(R.id.own1Tv);
    ...
    costTvs[0] = (TextView) findViewById(R.id.build1Tv);
    ...
    buyBtns[0] = (ImageButton) findViewById(R.id.buy1Bt);
    ...
    progressBars[0] = (ProgressBar) findViewById(R.id.prog1pB);
    ...
    buildBtns[0] = (Button) findViewById(R.id.build1Bt);
    ...

或者有什么变态的技巧可以使用吗?

我会这样做:

final int[] earnTvsId = new int[] {R.id.earn1Tv, R.id.earn2Tv, R.id.earn3Tv, R.id.earn4Tv ...};
for(int i = 0; i < earnTvsId.length; ++i){
    earnTvs[i] = (TextView) findViewById(earnTvsId[i]);
}

如果要使用getIdentifier()方法:

for (int i = 0; i < NUMBER_OF_TEXTVIEWS; ++i) {
    final int resId = getResources().getIdentifier("earn" + i + "Tv", "id", getPackageName());
    earnTvs[i] = (TextView) findViewById(resId);
}

有反思。但是我不确定这里的反光效果好不好...

Class<?> idClass = R.id.getClass();
Field field = idClass.getField("earn" + i + "Tv");
TextView textView = (TextView) field.get(R.id);

您可以为此目的使用反射,但众所周知,反射在 Android(尤其是旧版本)上很慢,并且对于指定的用例来说非常难以维护;如果ID改变了怎么办?您必须在 2 个地方(XML 和代码)进行更改,而不是让您的 IDE 处理传播更改。

如果您对它的样板感到厌烦,或许您应该看看 Android Annotations。它使用编译时注释和注释处理器来帮助您减少样板代码。