Adding an overlay to the camera view rather than the map view - android

I am trying to add a 'target' which would be represented as a circle which must always remain at the center of the current map view. Looking through the API I see a lot about adding Markers, Shapes, Ground overlays and Tile overlays but none seem to be adaptable to my needs.
Basically they are all used to draw elements 'on the map' at specified locations. What I need is some sort of overlay for the actual camera view. A good example would be when looking through the lens of the camera where a circle denotes the center of the frame.

You can use a RelativeLayout, which contains the MapFragment plus an additional custom view:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<fragment android:id="#+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent" android:layout_height="match_parent" />
<mypackage.MyCustomView
android:id="#+id/mapOverlay" android:layout_width="match_parent"
android:layout_height="match_parent" android:background="#android:color/transparent" />
</RelativeLayout>
Whatever you draw into the custom view, e.g. a circle in the center, is drawn on top of the map, and will stay there, independent of the maps movement.
If you want to adapt the shape to the zoom, tilt, etc. you need to listen to camera changes and adapt the drawing accordingly. Unfortunately the CameraChangeListener is only called, after the change is finished. So you can not immediately follow the zoom or tilt gesture with your drawing.

Related

Why cant I draw anything on my SurfaceView canvas?

I tried to match LunarLander's implementation of a SurfaceView style of drawing.
I am starting really simple, and just trying to draw circles underneath the user's touch input, but I can't seem to draw anything! All my app gets is a green screen (which is the background color of the view in the layout xml).
In an attempt to draw something, I have tried drawing a black rectangle on the entire canvas, a circle at 0,0 and a bitmap image. None of these draws succeed. They all get called, and none throw exceptions, but the screen never changes from green.
I am at wits end trying to figure this out so here is my code (minus the game engine, which is irrelevant at this point).
The layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.jknight.particletoy.view.GameEngineView
android:id="#+id/gameengineview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF66FF33"/>
</FrameLayout>
EDIT:
Figured it out:
You cannot have a background color property in the layout for a surface view. It was rendering overtop.

9-patch drop shadow technique works for image view but not camera preview

I use to following 9-patch image to create drop shadow effect.
It works pretty well for the following image view.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#FFFFFF"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center" >
<ImageView
android:id="#+id/image_test"
android:background="#drawable/dropshadow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/pic1"
/>
</LinearLayout>
I am able to get a perfect shadow dropped effect. Note that, there is a 1 pixel wide red line at picture right/bottom. I purposely place the 1 pixel wide red line around picture right/ bottom, to proof there are no pixel from 9-patch image cover up my original picture.
However, when I try to apply the exact same technique on camera preview view, things getting complicated. I do a slight modification on API Demo example com.example.android.apis.graphics.CameraActivity
I modify the GUI view, by performing the following modification.
class Preview extends ViewGroup implements SurfaceHolder.Callback {
// ...
Preview(Context context) {
// ...
mSurfaceView.setBackgroundDrawable(getResources().getDrawable(drawable.dropshadow));
this.setBackgroundColor(Color.WHITE);
// ...
}
}
I get the following outcome. Note that, shadow effect begin to appear, before end of picture right edge and bottom edge. Its distance is 9 pixels before reaching end of edge.
I am pretty sure I am having correct image filename dropshadow.9.png for both project. However, I lack of idea why the latter doesn't work as expected?
This is because you are using a SurfaceView which provides you with a dedicated drawing surface that will not respect the content boundaries you have defined in your nine patch image.
A possible workaround would be to place your camera's SurfaceView on top of a slightly larger view that holds the drop shadow as a background.

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!

Draw an always centered overlay on MapView in Android

I would like to draw an always centered image overlay in MapView in Android, like a targeting reticle
The way that I am going to approach it is to use the onTouchEvent of Overlay and the
MotionEvent.Move to move the location of the overlay around.
Is there a better way of doing this?
You should be able to accomplish this with a RelativeLayout that contains a MapView and an ImageView for your centered image. Here's some sample XML:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.maps.MapView android:id="#+id/google_maps"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:apiKey="#string/maps_key"/>
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="#drawable/mapcenter"/>
</RelativeLayout>
This will center your image and cut down on any processing that would otherwise be needed to center/keep the image centered. There is of course other ways to do this with an OverlayItem, let me know if the XML approach doesn't work and I'll post an Overlay Example.

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