I'm trying to draw a Path in a SurfaceView through a Bitmap
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
mCanvas.drawPath(mPath);
canvas.setMatrix(mMatrix);
canvas.drawBitmap(mBitmap);
}
I have to use a Bitmap because I need to save drawings. The SurfaceView has a OnScaleListener through which I can zoom. There is a simple way to keep the path's stroke fixed while zooming? The zoom must affect only the scale of the path (points coordinates) but not the stroke... Any idea?
I'm trying to apply a visual effect to a viewgroup. My idea is to grab a bitmap of the viewgroup, shrink it down, expand it back up, and draw it over the viewgroup to give it a blocky, low quality effect.
I've got most of the way there using this code:
public class Blocker {
private static final float RESAMPLE_QUALITY = 0.66f; // less than 1, lower = worse quality
public static void block(Canvas canvas, Bitmap bitmap_old) {
block(canvas, bitmap_old, RESAMPLE_QUALITY);
}
public static void block(Canvas canvas, Bitmap bitmap_old, float quality) {
Bitmap bitmap_new = Bitmap.createScaledBitmap(bitmap_old, Math.round(bitmap_old.getWidth() * RESAMPLE_QUALITY), Math.round(bitmap_old.getHeight() * RESAMPLE_QUALITY), true);
Rect from = new Rect(0, 0, bitmap_new.getWidth(), bitmap_new.getHeight());
RectF to = new RectF(0, 0, bitmap_old.getWidth(), bitmap_old.getHeight());
canvas.drawBitmap(bitmap_new, from, to, null);
}
}
I simply pass in the canvas to draw on and a bitmap of what needs to be scaled down+up and it works well.
public class BlockedLinearLayout extends LinearLayout {
private static final String TAG = BlockedLinearLayout.class.getSimpleName();
public BlockedLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
applyCustomAttributes(context, attrs);
setup();
}
public BlockedLinearLayout(Context context) {
super(context);
setup();
}
private void setup() {
this.setDrawingCacheEnabled(true);
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
// block(canvas); If I call this here, it works but no updates
}
#Override
public void onDraw(Canvas canvas) {
// block(canvas); If I call this here, draws behind children, still no updates
}
private void block(Canvas canvas) {
Blocker.block(canvas, this.getDrawingCache());
}
}
The problem I'm having is in my viewgroup. If I run the block method in the viewgroup's draw, it draws over everything but doesn't ever update when child views change. I've traced function calls with Log, and the draw method seems to be running, but nothing changes.
I've also tried implementing this in onDraw. This draws the bitmap behind all the children views, and again they aren't updating.
Can anyone explain how I would go about fixing this?
Try this:
#Override
protected void dispatchDraw(Canvas canvas) {
// call block() here if you want to draw behind children
super.dispatchDraw(canvas);
// call block() here if you want to draw over children
}
And call destroyDrawingCache() and then, buildDrawingCache() each time you change a child.
Draw() method will work well for you.
I'm now trying to make a count time view in a circle shape, when time is passing, the view will reducing his angle. It's used to cover profile photo(a circle shape photo).
Starting with Android API 23, you can use onDrawForeground(Canvas) to draw on top of child views: https://developer.android.com/reference/android/view/View#onDrawForeground(android.graphics.Canvas)
Unlike onDraw() though, be sure to call through to the super class:
#Override
public void onDrawForeground(final Canvas canvas) {
super.onDrawForeground(canvas);
// Your code here
}
I have a code where I draw image:
class Panel extends View {
public Panel(Context context) {
super(context);
}
#Override
public void onDraw(Canvas canvas) {
Bitmap _scratch = BitmapFactory.decodeResource(getResources(), R.drawable.calvin_logo_small);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(_scratch, x-point, y-point, null);
}
}
How can I draw this image in my activity, but I don't want to change may layout. I have layout: setContentView(R.layout.main); This is possible to draw in this lauout with canvas? I have this activity and this layout have a lot of components. I only want image in place where I click with canvas. This is idea. I start application where start activity with my setContentView(R.layout.main);. After that I click on the screen and canvas draw picture in place where I clicked. This is possible to do?
Your code should work. Just override the onTouchEvent() for the view, store the co-ordinates of the touch event in field variables and invalidate() the view so that onDraw() would be called. Use the co-ordinates in onDraw() to render the image as you've already done.
To improve performance, you can cache the bitmap if it's not going to change.
I want to create an ImageView and then draw text on top of the ImageView. I also need to be able to modify the text periodically. Currently I've created a custom view that extends ImageView. Then I overwrite onDraw() and use it to draw the text. Only problem then is that when I use my custom ImageView it doesn't draw the image, just the text.
public class BoardView extends ImageView
{
public BoardView(Context context)
{
super(context);
}
protected void onDraw(Canvas canvas)
{
Paint paint = new Paint();
setImageResource(R.drawable.board);
paint.setColor(Color.BLUE);
canvas.drawText(x.getName(), x.getX(), x.getY(), paint);
}
}
You should call the super.onDraw in your onDraw method before your draw code.
How can I draw a button on top of the canvas in a custom view? (Preferably on the mid-right side) Is there something I have to call before doing the button.draw(canvas)?
public class MyClass extends View {
public Simulation(Context context) {
super(context);
pauseButton.setText("TestButton");
pauseButton.setClickable(true);
pauseButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.i(TAG, "Button Pressed!");
}
});
public onDraw(Canvas canvas) {
super.onDraw(canvas);
pauseButton.draw(canvas);
}
}
Thanks for your time
You cannot insert a button into canvas. Canvas is an interface for bitmap or a bitmap buffer for a view. You can only draw other bitmap or pixels in it, not insert an object or a widget.
There are some solutions:
as Nikolay suggested, use a FrameLayout and create two layers (views), first your custom view and the second LinerView or RelativeView, which will come on top, where you can have buttons etc
draw an image of a buttun on Canvas then use onTouchEvent in your custom view and test for the coordinates of the touch, then do something... an example for onTouchEvent here: Make certain area of bitmap transparent on touch
Why do you need to draw the button yourself? Use a FrameLayout and simply have the button overlayed on your custom view.
Try this
public onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
pauseButton.draw(canvas);
canvas.restore();
}