Java Dynamic Names

2020-05-03 10:36发布

问题:

I know, that Java doesn't have a pre-processor, so some stuff is more or less impossible in java.

Is there really NO way to fill those arrays with dynamic names in a loop? I'd like to have something like:

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

instead of

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

Or is there any kinky trick, that can be used?

回答1:

I would do it like that:

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

If you want to use the getIdentifier() method:

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


回答2:

With reflection. But I'm not sure if reflections are good here...

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


回答3:

You could use reflection for this purpose, but that's known to be slow on Android (especially older versions) and for the specified use case pretty unmaintainable; what if the ID's change? You'd have to make your changes in 2 places (XML & code) rather than let your IDE handle propagating the change.

If it's boilerplate you're annoyed with, perhaps you should take a look at Android Annotations. It uses compile-time annotations & an annotation processor to help you reduce boilerplate code.