使用findViewById时动态初始化对象数组

时间:2011-04-01 06:14:35

标签: android

我对java和Android都很陌生。

如果你对我的问题有一个更好的标题,我会全力以赴。

我正在做一个带灯的应用程序,我已经在我自己创建的类中包装了ImageViews。我像这样初始化我的LED:

lightRig = new Led[] {
        new Led((ImageView) findViewById(R.id.imageView20), R.drawable.green_on_10, R.drawable.green_off_10),
           ...
           new Led((ImageView) findViewById(R.id.imageView1), R.drawable.green_on_10, R.drawable.green_off_10),
}

这样会伤害我的眼睛硬编码像这样的20个LED,我想更有活力。我的问题是我需要引用R.id.imageViewXX以便将它与我的Led相关联,并且 i 找不到比我上面所做的更多的方法。请建议一个新手。

更新:一行应该有20个LED,就像进度条一样。从绿色LED开始,然后以红色LED结束。

我同意拉尔斯的评论,我或许应采取不同的方法。感觉就像我应该的那样。我只是不知道如何。

我根据评论和其他来源采取了这种方法:

  while(i < numberOfImageViews - 1) {
      //Through reflection we can get the IDs, but its very expensive.
       int id = getResources().getIdentifier("imageView" + (i+1), "id", getPackageName());
       if (id > 0) {
           switch(i) {
            case 0  : drawableOn = R.drawable.green_on_10;
                      drawableOff = R.drawable.green_off_10;
                      break;
            case 5  : drawableOn = R.drawable.yellow_on_10;
                      drawableOff = R.drawable.yellow_off_10;
                      break;
            case 10 : drawableOn = R.drawable.orange_on_10;
                      drawableOff = R.drawable.orange_off_10;
                      break;
            case 15 : drawableOn = R.drawable.red_on_10;
                      drawableOff = R.drawable.red_off_10;
                      break;
           }
           lightRig[i] = new Led ( (ImageView) findViewById(id), drawableOn, drawableOff );
      }
      i++;
  }

5 个答案:

答案 0 :(得分:2)

我能想到一个替代方案:

int[] ids = {R.id.imageView1, R.id.imageView2, ...};
Led[] lightRig = new Led[20];

for (int i=1; i < 20; i++)
{
    lightRig[i] = new Led((ImageView) findViewById(ids[i]), R.drawable.green_on_10, R.drawable.green_off_10);
}

这是另一个,虽然你需要尝试:

<array name="imgs">
    <item>@+id/imageView1</item>
    <item>@+id/imageView2</item>
    ...
</array>

Led[] lightRig = new Led[20];
TypedArray imgAr = getResources().obtainTypedArray(R.array.imgs);

for (int i=1; i < 20; i++)
{
    int img = imgAr.getResourceId(1, 0);
    lightRig[i] = new Led((ImageView) findViewById(img), R.drawable.green_on_10, R.drawable.green_off_10);
}

答案 1 :(得分:0)

没有任何动态获取资源的方法。您需要使用R.id.imageViewXX逐个获取视图。

答案 2 :(得分:0)

@artifex,我不确定这是否有效。但你可以尝试一下。如果你一个接一个地放入所有的ImageViews而没有不同类型的组件,这可能会有用。

for ( int i = R.id.imageView1, int j=0 ; i <= R.id.imageView20 ; i ++ , j++ ) {  
    lightRig[j] = new Led((ImageView) findViewById(i), R.drawable.green_on_10,   R.drawable.green_off_10);  
}

在for循环中为任何ClassCastException设置一个try catch。

答案 3 :(得分:0)

资源无法动态生成,因为项目中使用的所有资源都必须由R.java计算

所以我认为我们不能动态导入它们。

答案 4 :(得分:0)

根据您的最新信息,我看到了两种方法。两者都只使用一个View

方法1

由于您有固定数量的LED,您可以准备20个不同的图形文件,每个图形文件代表进度条的一个步骤。因此,第一个图像将关闭所有LED,第二个图像将打开第一个图像,依此类推。然后将这20个文件放入res/drawable文件夹,并将图形应用于ImageView实例,如下所示:

// store the progress somewhere
int progress = 10;
...
// get the graphic for the current progress from resources
int resID = getResources().getIdentifier("led_" + progress, "drawable", this.getClass().getPackage().getName());
// apply the resource to an ImageView
imageView.setBackgroundResource(resID);

方法2

您可能需要考虑在运行时直接将leds绘制到您自己的Canvas类的View上:

class LedProgressView extends View {
    // specify your colors here; have it containing 20 elements
    // you can use also Color.argb(255, R, G, B) to specify your own color
    private final static int[] COLORS = new int[] { Color.GREEN, ..., Color.YELLOW, ..., Color.RED };

    private int progress = 0;

    public setProgress(int progress) {
        if ((progress < 0) || (progress > 19)) {
            throw new IllegalArgumentException("progress not valid");
        }
        this.progress = progress;
        // force repaint of your view
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // clear canvas
        canvas.drawARGB(0, 0, 0, 0);
        // draw leds
        Paint paint = new Paint();
        // rect contains position of a single led; static size here, surely you want to size it according to your view's size
        Rect rect = new Rect(0, 0, 0, 20);
        for (int i = 0; i < progress; i++) {
            rect.left = i * 20;
            rect.right = (i + 1) * 20;
            paint.setColor(COLORS[i]);
            canvas.drawRect(rect, paint);
        }
    }
}