In my app i am using surface view for drawing perspective and some buttons on the same layout.
I am done with the drawing part but don't know how to make surface view transparent for the current layout only.
When i use holder.setFormat(PixelFormat.TRANSLUCENT); it shows my previous screen.
I have also tried the setZOrderOnTop(true); method but it makes my other buttons hidden/covered when drawing.
And using setZOrderMediaOverlay(true); put the view beyond current layout, if i am moving my finger over the screen it is drawing there as i can see the saved file, but not showing on screen.
I want to make it transparent for current screen without setting the z order.
Forks, help me to make this happen.
Thanks in advance.
Related
I have a custom GLSurfaceView that I want to mask a portion of.
Lets say I only want to draw a circular portion of it on screen.
I tried to override the dispathDraw method and use the clipPath method as suggested here
I ensured that the Hardware Acceleration is turned off but the GLsurfaceView renders without any change.
EDIT 1
I realized now that in android studio, after i hit run, the preview does update to show a clipped GLSurfaceView. The output on the screen remains rectangular.
EDIT 2
I figured that this only happens when the child view of the parent FrameLayout is GlSurfaceView. WHen I replace that with a imageview (containing blue background) it works as expected on the device.
Any suggestions?
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 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.
I am building a paint application for android. Extending the FingerPaint application sample provided with the SDK. However, unlike FingerPaint, I'm using SurfaceView with a separate rendering thread to draw to the surface. All this is very standard and straightforward. Working well. I want to, however, give a White coloured background to the painting surface, so it's like drawing on a white paper. The default background is black coloured.
The thread of my surface view, calls the onDraw() method of the view.
The problem I'm facing here is, if I set a background colour or background resource to my SurfaceView, this background overwrites the previous drawing of the surface, when the view is rendered the next time. I will explain this with an example:
Suppose I set the background to white colour. Now, the application starts, with my SurfaceView having the white colour. Ok, so far good. Now, I draw a red coloured line on this surface, with my finger. The line is now shown on the white surface. Good. Now, this is supposed to be a painting app, and suppose I want to draw a car. So, then, I draw my 2nd red line, with my finger. The 2nd line is drawn on the screen, but the 1st one, which I drew previously, vanishes. That is, because I have set some background to my SurfaceView, the background is drawn again, thus overwriting the 1st line that was drawn. Now the screen shows only the 2nd line drawn.
Obviously, I do not want this to happen. The code works perfectly, when I don't attempt to change the background (that is, both lines are shown, on a default black background, no background effectively). But when I set some desired background, this thing happens. Is there a way to somehow have a static background, that is not drawn every time? I want the background to be drawn only once, all the subsequent drawings should happen on this background. I don't want the android runtime , to draw the background, every time it draws my view, thus overwriting all drawing present on that view, from previous renderings. Any way to work around this?
The things I have tried, to achieve this are:
Setting the background colour of my SurfaceView using android:background in XML.
Doing the above, using the concept of style. (specifying a style value and referencing it in the layout file). The style just defines the background colour as #FFFFFFFF (white).
Setting the style of 2, to the parent view of the SurfaceView (a RelativeLayout).
Setting the style of 2, to the entire application, as a theme,using android:theme in my manifest file.
Setting the background drawable of my SurfaceView to an image which is plain and white-coloured.
Calling the setBackgroundColor for my SurfaceView from the code as, this.setBackgroundColor(Color.WHITE).
Thanks.
according to android's doc:
The surface is Z ordered so that it is behind the window holding its
SurfaceView; the SurfaceView punches a hole in its window to allow its
surface to be displayed. The view hierarchy will take care of
correctly compositing with the Surface any siblings of the SurfaceView
that would normally appear on top of it. This can be used to place
overlays such as buttons on top of the Surface, though note however
that it can have an impact on performance since a full alpha-blended
composite will be performed each time the Surface changes
so if you change the z order of surface view via:
setZOrderOnTop(true);
this will work, but then you cannot put any other view on top of surface view.
Now I also tried overlaying my SurfaceView over another View with a white background, and setting the SurfaceView to be fully transparent. I used FrameLayout for this. That is, a View with a white background, overlayed upon which is my SurfaceView set to fully transparent.
This also failed to work. So now I have come to conclusion that the background colour of SurfaceView cannot be changed. So now I have dropped SurfaceView, and using a normal view, instead for my drawings. So far, there has not been any performance loss observed. But, it feels kind of wrong to drop an efficient implementation , just because SurfaceView doesn't let me change it's background colour.
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.