I'm very new to both java and Android.
If you have a better title for my question i'm all ears.
I'm doing an app that has led lights, i have wrapped ImageViews in a class i've created my self. I initialize my leds like this:
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),
}
It hurts my eyes to hard code 20 leds like this and i'd like to开发者_开发技巧 do it more dynamic. My problem is that i need to refer to the R.id.imageViewXX in order to associate it with my Led, and i can't find another way than the one i've done above. Please advice a newbie.
Update: There should be 20 leds on a single line, acting like a progress bar. Starts with green leds and then ends with red leds.
I do agree with the comment from Lars that i perhaps should take a different approach. It feels like i should. I just don't know how.
I've taken this approach based on comments and other sources:
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++;
}
There is one alternative I can think of:
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);
}
Here's another, although you need to try it:
<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);
}
There isn't any dynamic way of getting the resources. You need to use the R.id.imageViewXX to get the view one by one.
@artifex, I not sure this works. But you can have a try. This might work, if you have put in all the ImageViews one after the other without a component of different type.
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);
}
put a try catch inside for loop for any ClassCastException.
Resources cant be generated dynamically since all the resources that are used in the project has to be accounted by R.java
So i don't think we can't import them dynamically.
With your updated information I see two approaches. Both are using one View
only.
Approach 1
Since you have a fixed amount of leds you could prepare 20 different graphic files, each representing one step of your progress bar. So the first image will have all leds off, the second has the first led on and so on. Then you put these 20 files into the res/drawable
folder and apply the graphic to an ImageView
instance as follows:
// 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);
Approach 2
You may want to consider drawing the leds at runtime directly onto the Canvas
of your own View
class:
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);
}
}
}
精彩评论