Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I am trying to animate/morph a rectangular view/layout, as all views are rectangular. The user case for this would be: The user long-clicks a view that contains an ImageView or just the main view with a background, a new view would be generated being the size of the screen, then this view would shrink into a circle of a certain size. Possible solution I have found is extending the view class, therefore creating my own view and implementing a custom method, but I am confused on how to animate the view to shrink. Also the view would have to follow the users touch location continuously as it animates/morphs, adding more to the confusion.
A quick, not-so-thorough explanation to at least get you thinking in the right direction:
I think the big thing to keep in mind here is that whatever solution you find, the animation is going to be painfully slow unless you perform the transformations entirely within the view's onDraw(Canvas canvas) method. In other words, avoid anything that requires the view to measure and lay out for every frame of the animation. With this approach, you simply perform a frame transition and call invalidate() on the view to update. Keep in mind that you will lose most of your ability to interact with anything within the view in its circular rendering.
Since there are no shape-transforming animations built into Android, you will probably need to use something like Property Animation to roll it yourself. If you're supporting devices prior to Honeycomb (3.0), you will probably need to bring in the NineOldAndroids library and use its property animation capabilities instead. Essentially, you'll need to animate the values of the corner radius. Best case scenario, you're transforming a square into a circle. Otherwise, you need to do some cropping or dimension transformations as well.
To animate the view, you will first need to obtain a bitmap representing the latest render of that view. You can do that using the following code:
// Creates a bitmap in the size of the view
Bitmap bitmap = Bitmap.createBitmap(myView.getWidth(), myView.getHeight(), Bitmap.Config.RGB_565);
// Creates a new canvas that draws to the bitmap
Canvas canvas = new Canvas(bitmap);
// Draws the contents of the view to the bitmap via the canvas
view.draw(notifyCanvas);
You should only perform this once per animation, and it should occur just prior to performing the animation.
Next, you most likely need to create an empty extended View simply to hold the animated representation of the view you want to modify.
Implementing the transformation logic in onDraw(Canvas canvas) (which is done by extending the view as mentioned above), you have access to the Canvas object. Essentially, the Canvas object is the final layer that contains all the "draw" calls that render the view on the screen. Overloading the onDraw method on your new custom view, you can then use canvas.drawRoundedRect(...) to draw a rectangle with rounded corners and paint in the bitmap of the view we created in the code above. Within your custom view, you can keep a variable that stores the radius used by drawRoundedRect. As you animate, you set that radius to be larger and larger until you get a circle (granted, you'll only get a circle if the original shape is a square). This does get pretty complicated, and I've definitely skipped a few steps, but you can see a good example of a rounded view by checking out the RoundedImageView on GitHub. There are lots of good ideas in that library that you could borrow.
Apologies for not pulling together a more complete explanation. It's quite a complex task!
Related
I want to learn, how to create custom view. I have gone through multiple tutorial and didn't get what i want(I mean concept).
What i have learned
I am sharing my concept,if i am wrong please correct me.
If you want to make a minor change to the standard view then inherit itself(e.g extends seekbar) and customize it.
But if you want to make difficult or multifunction view, We should inherit View Class
When we inherit a View.
Two methods are neccessary
onDraw(Canvas canvas) // it call each time it and also can be call using invalidate.
onMeasure // it measure the actual width and size and set our viewit accordingly
Whatever you want to draw on View can be done using canvas;(Am i right).
To define additional attributes create an attrs.xml file in your res/values folder. and add <declare-styleable name="YourCustomView"> and add attributes to it.
get these attribute in the constructor of the View using TypedArray call recyle method.
My Confusions
can we draw something without using Canvas
can we draw ImageView without converting it to bitmap.
I simply want to create a custom imageView which can be rotated like
a dialView but it should rotate half(semi-circle) and also want to
draw its progress outside it. using canvas.drawArc()
What i want to achieve
I want to create my own custom knob, I have searched our google but didn't find what i want see my questions here
First Question
Second Question
Thanks in Advance....
1)You can use openGL. Otherwise you need a canvas. The canvas defines where you're drawing to, without it (or the openGL equivalent) we don't know where to draw. You might not want to draw directly to the screen, its common to draw to bitmaps in many cases.
2)Your question doesn't make a lot of sense. Why would you want to draw an ImageView, other than by letting it draw itself?
3)Easiest way to do that is to use a normal image view and call setRotation to rotate it as needed.
I need update a small portion of a custom view in order to display a small animation. The rest portion of the view has only static image. The most straightforward would be to obtain the canvas of the view and update only that particular portion directly. But I can't really find anyway to get the view's canvas object outside of the view::onDraw method.
The only alternative I know is this: call view::invalidate() with a specified rectangle to minimize the drawing flicker. I have the code to update the entire view within onDraw. So the best thing to do is to detect the clipping rect and only run the code to update the specified area, in order to minimize CPU usage as well?
I guess I will try to answer this question myself to the best my knowledge so far.
There is no direct access to the canvas outside of the onDraw method.
Although we can detect the clipping rect with the function Canvas.getClipBounds(), the getClipBounds function always return the entire view area if GPU is enabled. When GPU is not used, getClipBounds() returns the actual dirty area. Since there is a GPU in most phones, it makes the function getClipBounds pretty much useless.
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.
I've been working on this for a while but can't find anything that exactly addresses my question (at least not something easy to understand).
I have a main layout XML file where I define various layout objects like a Button or a TextView (and I know I can add SurfaceView, View, and view and other things too). I want to draw a shape (in my case it's an arc) in just one of these objects so it doesn't take up the whole screen and so I can position it relative to other things.
(In my case it will ultimately re-draw the arc kind of like a circle with a gap in a different position every time I call a method depending on a value I pass to the method, but that's separate from my basic question.)
I know the answer will have something to do with a canvas, an onDraw method, maybe Paint, probably a view. I have been able to draw a circle from a custom View object by setting the main java file's layout as that View (as opposed to R.layouts.main), but that takes up the whole screen, and I'm unsure how I might be able to have that dynamically draw with modifications.
A really clear explanation or better yet an actual example would just be awesome.
As i see it u need to draw a specific shape on widget and not on complete screen. Try using layer List.
you can refer this link for sample Link
In Android 2.2, I want to display a few sprites and clickable animations over an existing view. I just discovered that SurfaceView cannot be transparent
I tried overriding dispatchDraw() of a LinearLayout but that doesn't seem to be callable via a Runnable Thread.
I also tried to extend Canvas directly, but that quickly turned into a mess when trying to place it in my XML layout.
Do I have to use GLSurfaceView to have a drawing view whose background is transparent?
Optimally, I'd like to just have a Canvas on which I can draw Bitmap at various coordinates, instead of dealing with the details of GL (unless GL is the only way I can do transparency).
Silly Rabbit. Just use Views and move them around wherever you want within a FrameLayout. SurfaceView is not designed for what you're trying to do.
I'm going to try Switching from Canvas to OpenGL and toss in parts of TranslucentGLSurfaceView.
I'm still open to selecting an answer that doesn't require OpenGL, just for the sake of it solving my original question.