What exactly is the Canvas View relationship? - android

I'm looking at this example of how to drag things around the screen and my only point of confusion is what exactly IS the Canvas c object being passed in?
Is this View occupying the entire screen? What if it's set as the child to a Layout? Are there multiple canvases (one for each display item) or is there one overall Canvas upon which all things are rendered?
I'm having a hard time picturing what's happening beneath the hood.

The Canvas is the entire drawable area of the screen. You're supposed to stay within the bounds that the view has set, but in reality there's nothing stopping you from drawing all over.

Related

Android: Is there a way to draw on top of an existing canvas using a secondary canvas?

Basically I'm trying to make a change to an already drawn canvas. There is a portion of it that will change based on user input. Redrawing the entire canvas takes too much time, so I was thinking of making a separate canvas using the same view and holder, and just drawing the item that changes on top of the canvas. The bitmap I'm drawing over it appears to completely wipe out the previous canvas once drawn. Any way around this?
To ask a simpler question, I need to be able to draw on top of an existing view(surfaceview in this case) without erasing it.
That doesn't make much sense since the Canvas instance is a single one that is propagated top-down through the view hierarchy. If you want to refresh just a piece of your custom view, you can use methods such as view.invalidate(Rect) or view.invalidate(left, top, right, bottom).

How to draw outside view bounds?

How can I draw (bitmap, line, etc) outside the bounds of a view? From the view's onDraw(), I've read this is not possible as everything drawn will get clipped to the view's bounds.
I did come up with one solution but I'm hoping there's a better one. What does work is to create a transparent view that is at the top of the z order and includes the area I want to draw in (the entire app client area). Then, whenever I want to draw outside some child view, I can simply translate to the coordinates to the transparent view and draw there.
I also read about SurfaceView hoping that would do what I want. But I think it's main purpose is to provide drawing in a separate thread and doesn't solve the problem I'm discussing.
To be clear, it isn't sufficient to simply draw in the parent of the target view because other views in the parent will be higher in the z order and hide the drawing.
Intuition tells me there's a "right way" to do this. Anyone know?
I'm drawing the conclusion that the right way is to do what I proposed - create a transparent view that is at the top of the z-order for the space you need to draw in.
I come to this conclusion after learning how the Navigation Drawer drawing works - exactly in this way. So, if Google uses this technique, I conclude that it's the best way available.

android- can you make an object drawn in a canvas clickable

I know that the canvas in android is a lower level drawing surface but currently Im drawing all my objects inside a canvas and I would like a better way to handle clicks for each object on the canvas. Ive tried matching an x and y through the view their drawn in and that only works some of the time.
Is there anyway to make the individual bitmaps Im drawing im my canvas clickable. The objects in my app are moving dynamically...think of a game object where on screen elements are moving. Ive tried creating a class that extended Button but everything got drawn in the upper right hand corner of the screen so Im not sure if you can have moving objects onscreen that extend button however at least when I clicked the image on top of the stack of ones drawn it gave the expected response. Right now I register onscreen clicks through the view that the canvas is drawn in and through the running loop that makes on screen action take place I have an array of all items and when a click is registered I loop through all the items and those that are onscreen are checked for their coordinates. if I get a match i fire an intent to perform an action.....like I said this is unreliable at best and Im momentarily at a loss on how to restructure everything to get reliable responses.

Android: SurfaceView and Z-Level Question

I have a FrameLayout containing first a SurfaceView, and second a RelativeLayout which in turn contians various Buttons and TextViews.
Upon the canvas of the SurfaceView I am drawing numerous Bitmaps, and, via Touch and Motion Events am allowing the user to drag them around.
These Bitmaps, when dragged around pass underneath the Buttons etc that are inside the RelativeLayout.
Now, it's my (possibly mistaken) understanding that the "Z-level" of the SurfaceView, or whatever it has that passes for it, is entirely unrelated to the actual Z-level of the rest of the Layout. Is this the case? If so, how may I get around it, so that dragged Bitmaps are drawn ontop of other Views? Or what other way can I implement a full-screen canvas and yet not have my buttons etc act like the controls of an overlay.
I guess what I actually need is an underlay, where touch events can still be picked up by the Buttons etc underneath. But I don't know how to achieve this, as, when redrawing my Canvas, I have to also redraw the background.
Can I swap the order of the RelativeLayout and the SurfaceView inside the FrameLayout, and then make the background of the Canvas transparent? If so how? Will touch events still "fall through" to the buttons underneath?
Thanks for bearing with me, I know I'm a bit of a waffler.
SurfaceView doesn't work that way.
SurfaceView has two parts, the "view" part and the "surface" part. The "view" part is a transparent hole that is laid out with the other view elements, and composited onto the view layer. The "surface" part is a completely separate layer that will be positioned and scaled to match the "view" part, and composited by the system compositor rather than the app.
You can control the Z-order of the "surface" layer when the SurfaceView is first created, but it's going to be above or below all View elements. It can't go above some Views and below others because they're completely independent layers. The "surface" layer does not catch input events, so having it on top (via SurfaceView#setZOrderOnTop()) doesn't affect input focus.
For API 14+, you can use a TextureView, which behaves in a more View-friendly way.
Edit: for full details, see the much longer explanation.
Can you clarify a little bit more? In your SurfaceView do you have a background assigned? If not, you could probably also use AbsoluteView if your intention is to simply drag pieces around. If there is no background, you should be able to place the entire view above the RelativeView that you have and only have the various Buttons and such drawn on the view on top, which would be draggable and remain above everything else.

View Animation (Resizing a Ball)

i am trying to do this:
1) user long touches the screen,
2) a circle/ball pops up (centered around the user's finger) and grows in size as long as the user is touching the screen
3) once the user lets go of the finger, the ball (now in its final size) will bounce around.
i think i have the bouncing around figure out from the DivideAndConquer example, but i am not sure how to animate the ball's growth. i looked at various view flipper examples such as this:
http://www.inter-fuser.com/2009/08/android-animations-3d-flip.html
but it seems like view flipper is best for swapping two static pictures. i wasn't able to find a good view animator example other than the flippers. also, i would prefer to use images as opposed to just a circle. can someone point me in the right direction?
thanks.
Here are two simple tutorials to help you get started with drawing basic animations including touch input: balls bouncing randomly around the screen and basic drag and drop.
In brief: You're right, ViewFlipper is really not suited for this. You want to draw on a Canvas by making your own custom View. This is the basic framework for 2D graphics. Canvases let you draw image files, solid colors and other things to the screen, while applying transformations ot them at the same time. Handling the user input (i.e. the finger on the screen) is done via the onTouchEvent(...) method, which lets you do something when the finger touches the screen, moves on the screen or lifts off. Have a play with those two tutorials, they should give you the basics.
If you're using a bitmap on a canvas to draw it
http://developer.android.com/reference/android/graphics/Canvas.html#drawBitmap(android.graphics.Bitmap, android.graphics.Matrix, android.graphics.Paint)
Use a scale matrix, the identity multiplied by the scalar of the size you want the image to be.

Categories

Resources