I am always confused about this and I need a pointer on how you would do it. If create a an xml layout with multiple imagesview and text view. And Lets say I want to draw line between two images and move an image along this line. How do I draw this line? I know I can get location of both images view so I have x1,y1 and x2,y2. My problem is with drawing.
Do I need surface view to have the drawing capabilities and loading bitmaps on the screen along the line?
If yes, then I guess I should always surface view to fill the screen and views on top just incase I need to draw which seems kinda wrong?
IF no (I hope thats the answer), then how do I draw lines, or load bitmaps on screen using only X,Y values?
I hope I was able to explain my confusion
Thanks
EDIT: Actually I thougth of a way of explaining my confusion better.
When you create an activity with xml layout you have something like
onCreate (){
setContentView(R.id.layout)
}
but when you have activity with drawing view you have something like
onCreate (){
SurfaceView v = new Surfaceview(this);
setContentView(v)
}
My problem is that we have to set the content layout to EITHER xml layout or to be drawing area . What if I want to set it to my xml layout and at the same time I can draw anywhere on the screen (over images view, empty areas, TextViews ..etc)
See my question?
That depends on what your desired result is and how much flexibility you need. You can have a look at this android Animations tutorial (the site is down at the time of posting but google has it cached).
If you don't need flexibility, then for your line, you might be able to create a View in your xml with an android:background fill color and a size that makes it look as you wish. You could then use an Animation on your bitmap's ImageView to translate it along the line, and use a listener on said Animation to show/hide the various Views as necessary at the beginning or end of your Animation.
If you need flexibility, the SurfaceView is probably your best bet.
Related
I'm tackling the task of an overlaying drawable over a view that animates the drawing of a checkmark as in the following video https://vid.me/MsQj
I don't have a preferred method for doing this but it's just not coming out the way I wanted it to, I tried:
Two views, each with on side of the checkmark to be revealed with an animation, however I'm stuck at the "revealed with an animation" since I can't use the circular reveal on -21
Frame by frame animation, this is the easiest but I'd hate to have 60 images for this stupid animation if it can be done programmatically
Drawing on a custom view canvas
My question would be, is there anything that can make this easier on me, or do I have to tackle it head first and just get on with it
You could create a custom View class which contains two lines defined by ShapeDrawables, one for each leg of the tick. Expose the lengths of these two lines as properties of the class, and then use Property Animation to animate the lengths of the lines.
Property Animation is flexible enough to handle pretty complex timing and sequencing of various properties. In this particular case you would probably want to use an AnimatorSet to sequence the two line animations so the second starts once the first has finished.
I ended up developing a custom View thanks to #SoundConception suggestion and finding out about ObjectAnimator which are very powerful in Android. In essence what goes on is we set a width for the first and second line that make the checkmark and using the animator change the value of those properties from 0 to the desired one.
On the setter for the property, we invalidate the View to redraw it with the new value and with a little tweaking I made a nice View that while its currently only working for my specific layout (ie it needs some more work on the offset calculation) it's able to draw an animated checkmark with some stuff that is customizable.
Precisely, you can set the line width, the color, the length and the animation time. And touching the java file, you can change the interpolator and all the rest of the stuff.
Hopefully the code, while not really commented serves as a basis for someone trying something similar.
For example the following code would generate something like this video, although not really because I was testing opacity and thinner lines, but you get my drift.
<coop.devtopia.CheckmarkView
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_centerInParent="true"
android:id="#+id/view"
app:first_leg_length="50"
app:second_leg_length="100"
app:total_duration="1500"
app:stroke_width="20"
app:stroke_color="#22000000"/>
Repository
Update 4/2/15
I've played with this a little further and added dynamic offset calculation (fancy way of saying centering) to the tick, meaning we can generate big checkmarks, small checkmarks, skinny or thick, reversed or straight and they will be centered in the view. Can't guarantee the same for checkmarks bigger than the container, they will likely be cropped.
Here are a few of the checkmarks generated for this demonstration, of course the animate as if drawn and the effect can be very pleasing and resource friendly. This turn out to be a pretty interesting subject after all.
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
I am working on a project that involves painting on images.
To delete the unwanted lines or curves i have to draw a border and X button to delete it.
I have a relative layout where i have the freehand drawing canvas. on edit mode i should make them as u see in the pic, where i have to create button on a varying x,y positions.
i am confused how to achieve this.
Thanks in advance.
Jana.
I suggest doing this manually rather than using the Button widget. Override the onTouchEvent on the view holding your painting and use MotionEvent.getX and MotionEvent.getY in combination with MotionEvent.getAction to determine behaviour when the user touches the 'button'. Skipping widget creation will improve performance and open up doors to other types of functionality.
You could use the deprecated AbsoluteLayout container for this or keep the RelativeLayout and use layoutMargins to set the location of the buttons. The former is the route you should take despite the container being deprecated as the later breaks the layout paradigm by misusing margins...
You should keep in mind that there are a variety of devices with different screen sizes and setting explicit, pixel based locations is going to be awkward.
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.