How to retain canvas state and use it in onDraw() method
- by marqss
I want to make a measure tape component for my app. It should look something like this with values from 0cm to 1000cm:
Initially I created long bitmap image with repeated tape background.
I drew that image to canvas in onDraw() method of my TapeView (extended ImageView). Then I drew a set of numbers with drawText() on top of the canvas.
public TapeView(Context context, AttributeSet attrs){
ImageView imageView = new ImageView(mContext);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
imageView.setLayoutParams(params);
mBitmap = createTapeBitmap();
imageView.setImageBitmap(mBitmap);
this.addView(imageView);
}
private Bitmap createTapeBitmap(){
Bitmap mBitmap = Bitmap.createBitmap(5000, 100, Config.ARGB_8888); //size of the tape
Bitmap tape = BitmapFactory.decodeResource(getResources(),R.drawable.tape);//the image size is 100x100px
Bitmap scaledTape = Bitmap.createScaledBitmap(tape, 100, 100, false);
Canvas c = new Canvas(mBitmap);
Paint paint = new Paint();
paint.setColor(Color.WHITE);
paint.setFakeBoldText(true);
paint.setAntiAlias(true);
paint.setTextSize(30);
for(int i=0; i<=500; i++){
//draw background image
c.drawBitmap(scaledTape,(i * 200), 0, null);
//draw number in the middle of that background
String text = String.valueOf(i);
int textWidth = (int) paint.measureText(text);
int position = (i * 100) + 100 - (textWidth / 2);
c.drawText(text, position, 20, paint);
}
return mBitmap;
}
Finally I added this view to HorizontalScrollView. At the beginning everything worked beautifully but I realised that the app uses a Lot of memory and sometimes crashed with OutOfMemory exception. It was obvious because a size of the bitmap image was ~4mb!
In order to increase the performance, instead of creating the bitmap I use Drawable (with the yellow tape strip) and set the tile mode to REPEAT: setTileModeX(TileMode.REPEAT); The view now is very light but I cannot figure out how to add numbers. There are too many of them to redraw them each time the onDraw method is called.
Is there any way that I can draw these numbers on canvas and then save that canvas so it can be reused in onDraw() method?