How to wrap the content of a SurfaceView? - android

I have surfaceView class that is modeled after this, I populated it with 6 bitmaps. Is there a way to wrap the surfaceView around the bitmaps, instead of it covering the entire screen.
I have try this in my xml file:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<com.android.customclasses.Panel
android:layout_height="wrap_content"
android:layout_width="wrap_content">
</com.android.customclasses.Panel>
</LinearLayout>
but this does not work. it just fill the parent.
Thanks.

I don't think that SurfaceView has a notion of "wrap_content" (other than perhaps interpreting it to mean "fill_parent"). You would have to override onMeasure in your custom class Panel and call setMeasuredDimension with the appropriate size.
If you think about this it makes sense: your bitmaps are not inside the SurfaceView in the view hierarchy. They are simply being drawn by graphics commands to a SurfaceView which has a predetermined size.

Related

Changing view size in run-time efficiently

I've a surfaceview to do some drawing stuff. My view supports zoom in/out feature. Now when user zoom in/out by finger gesture, I want to resize the surfaceview, I've tried resizing by changing surfaceview's layout params. Although this works, but it's slow, and while doing the resize work, I see some big jumps (lags), Which is no usable. Here, I want to know how can I resize the surfaceview efficiently (without that jump)?
Here sniped of my view structure,
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:fillViewport="true"
android:layout_above="#+id/bottomMenu"
android:layout_height="match_parent">
<MySurfaceView
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout> ...
And the params changing code,
ViewGroup.LayoutParams params = surface.getLayoutParams();
params.height = (int) (750*factor);
surface.setLayoutParams(params);
Well in the end I found a method of surfaceHolder to set the canvas size fixed,
holder.setFixedSize(canvasW, canvasH);
With this method I'm able to resize layout with layout params, without any kind of lagging. Here, I need to know the canvas size before setting it up, so I added my SurfaceView from Java code with predefined size and it's working smoothly.
**I'm not still sure, why setting up canvas fixed size done the trick. You are welcome to explain a bit (may be edit this answer).

Crop image and retain positioning android

I have two images that are positioned in the same space, effectively overlapping one another.
They are slightly different but identically sized.
I want to be able to crop the top laying image but retain the initial positioning.
So almost like cutting it in half, and keeping the left half in place, which would perfectly overlap the underlaying image.
The following is the code I have, just two ImageView's within a FrameLayout.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_gravity="center_horizontal"
android:layout_width="380dp"
android:layout_height="wrap_content"
android:src="#drawable/level_off">
</ImageView>
<ImageView
android:layout_gravity="center_horizontal"
android:layout_width="190dp"
android:layout_height="wrap_content"
android:src="#drawable/level_on">
</ImageView>
</FrameLayout>
Any ideas? I've done my best to explain what I mean! Thanks!
You could try an programmatic approach by inheriting ImageView and override onDraw(), doing so will also save you an extra layout group.
In onDraw()you have to:
obtain the imageMatrix from your original image
alter the canvas to left/right half of your original size
draw the second image in that altered canvas with the same matrix as the original image
I've done a similar thing and theoretically it should work for your case as well.

Android Camera Preview centered in an image

I am creating a Camera application where I want to restrict the camera preview to be centered and around 60% of total size of the phone screen.
One way is to have the FrameLayout of Preview with padding so that the usable screen size is restricted , but I also want to show borders (around the corners) inside the restricted area which is not possible in this options.Also it not possible to show padding in percentage so that I can restrict user to 60% of screen size.
Other way is to have a image having a transparent center rectangular area and having border in inner rectangle corners . But I somehow need to restrict the FrameLayout of preview inside this rectangle which I am not able to do . Any suggestions on this option ?
Please also let me know if there are any other options .
Thanks.
Unless I don't fully understand your issues with using android:padding to provide space around your layout, you should be able to use android:layout_margin instead to accomplish the same goal but overcome the problems you mentioned. Adding padding creates space between the border of the View and its content. However, adding margin creates space between the border of the View and its parent, so the content still fills the View itself to the edges. However, you still can't define your view spacing in terms of percentage direct from XML...you would need to define the margin as static or apply the LayoutParams in Java code where you could calculate the required margin based on the current screen size.
Another option is to take advantage of the android:layout_weight property inside of a nested LinearLayout. The calculated weight sum could give you the 60% you're looking for directly in XML. Something like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:weightSum="1.0" >
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.6"
android:gravity="center"
android:weightSum="1.0">
<SurfaceView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.6" />
</LinearLayout>
</LinearLayout>
Where the SurfaceView is the location of your Camera Preview, now centered with 20% of the screen on all sides. If you wanted to place things over or under this preview you would obviously want to place this entire block into a RelativeLayout or FrameLayout along with other components.
HTH!

Cropping/Clipping camera preview to just show top half of image

I'm developing an app that shows a camera preview on a SurfaceView but I only want to show the top half of the preview.
Is there a way of cropping/clipping the view or will I have to resort to obscuring the bottom half with something like an image,other view or drawing?
regards
Simon
I am currently using this method to do the cropping (basically using the clip child ability of an absolute layout to clip a surfaceview child)
<AbsoluteLayout android:clipChildren="true" android:layout_alignParentRight="true" android:layout_width="240dp" android:id="#+id/absoluteLayout1" android:layout_height="80dp">
<SurfaceView android:id="#+id/swSurfaceView" android:layout_width="240dp" android:layout_height="160dp" android:visibility="visible"></SurfaceView>
</AbsoluteLayout>
Overlaying the SurfaceView with another view is the easiest way to do it... however, it's quite ugly if you ask me.
Why don't just set the SurfaceView height manually? Make it take the 50% of the screen space and it will do what you want. You don't provide code so we'll have to do some guesses: let's suppose you have a LinearLayout, then inside it you put two views: your surface view and another kind of view. Then, you set their height to be 0dip, and their weight to be 1... that should do it.

Compositing Android MapView and SurfaceView

I have an application with a SurfaceView and a MapView. They are displayed in a single view, like so:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainlayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<com.google.android.maps.MapView
android:id="#+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:apiKey="XXXXXXXXredactedXXXXXXXXXXXXx"
/>
<class.that.extends.SurfaceView
android:id="#+id/surfaceview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#00000000"
/>
</RelativeLayout>
Note the MapView comes before the SurfaceView. Because of this, the MapView is drawn "under" the SurfaceView, and all that I see is a black background, with the things that I draw on the SurfaceView showing. If I swap the order, and put SurfaceView first in the file and MapView second, the MapView is drawn, with none of the SurfaceView showing.
According to the SurfaceView Javadoc:
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.
To me, this means that I should be able to put the SurfaceView first in the file, and have it "punch through" the MapView and display what it has. But, as it is, they seem to be two views, and only one is visible at a time.
After thought: I tried setting the background to #00000000 so that the alpha of the background would be zero (i.e. transparent), but it doesn't have any effect.
The alpha setting alone won't really help in this case.
When you setup your views, set the PixelFormat of the view's SurfaceHolder:
glsView = (GLSurfaceView) findViewById(R.id.surfaceview);
glsView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
I ended up abandoning SurfaceView, despite it's wonderful features for drawing smoothly. Now I'm just using a regular old View, overriding its onDraw method. The MapView underneath is currently being refreshed every time this new View is drawn, but I'm looking in to using the drawing cache feature of Views to simplify that.

Categories

Resources