I have spend about 3 hours trying to figure this out and it seems so simple but i cant seem to work it out! Could someone please help me! All i want it to do it display an image from the drawable resources folder. It says that "cannot convert from Bitmap to Drawable".
package com.CS3040.Places;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import com.CS3040.*;
import com.CS3040.Coursework.R;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;
public class PlaceOverlayItem extends OverlayItem {
private final GeoPoint point;
private final Place place;
private final Drawable marker;
//private final Context context;
public PlaceOverlayItem(Context context, Place p, String type) {
super(p.getGeoPoint(), p.getName(), p.getFormatted_address());
if(type.equals("restaurant"))
{
//this.marker =
Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), R.drawable.restaurant);
this.marker = bmp;
}
//super.setMarker(this.marker);
this.point = p.getGeoPoint();
this.place = p;
}
/**
* #return the point
*/
public GeoPoint getPoint() {
return point;
}
/**
* #return the place
*/
public Place getPlace() {
return place;
}
}
Well it's right - Bitmap doesn't extend Drawable. I haven't done any Android development, but it sounds like you want a BitmapDrawable:
Resources resources = context.getResources();
Bitmap bmp = BitmapFactory.decodeResource(resources, R.drawable.restaurant);
this.marker = new BitmapDrawable(resources, bmp);
change this:
Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), R.drawable.restaurant);
this.marker = bmp;
to this:
Drawable d = context.getResources().getDrawable(R.drawable.restaurant);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
this.marker = d;
You need to get your resource as a Drawable:
if(type.equals("restaurant"))
{
this.marker = context.getResources().getDrawable(R.drawable.restaurant);
} else {
// marker would get no value without that else case - not allowed if you declare it final
this.marker = null;
}
Related
I created a class MiOverlay that extends from Overlay.
And it doesn't recognize the getResources method.. What do I have to do. Here the full code of my class
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.location.Location;
import com.google.android.maps.MapView;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.Overlay;
public class MiOverlay extends Overlay {
GeoPoint point;
public MiOverlay(GeoPoint point)
{
super();
this.point = point;
}
#Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when){
super.draw(canvas, mapView, shadow);
Point scrnPoint = new Point();
mapView.getProjection().toPixels(this.point, scrnPoint);
Bitmap marker = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
canvas.drawBitmap(marker, scrnPoint.x - marker.getWidth() / 2, scrnPoint.y - marker.getHeight() /2 , null);
return true;
}
I disagree with Luis Lavieri's answer. Your easiest solution would be to use the MapView's context:
Bitmap marker = BitmapFactory.decodeResource(mapView.getContext().getResources(), R.drawable.ic_launcher);
Easy and no potential memory leaks.
You are in an Non-Activity Class, so you must refer to what is discussed in this question. However, it is not recommended to pass the Context due to a possible memory leaking. Try to implement your resources within your Activity using getResources() or if you are using Fragments, use getActivity().getResources()...
Anyway, your easiest option would be:
private Context context;
public MiOverlay(GeoPoint point, Context _context)
{
super();
this.point = point;
context = _context;
}
#Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when){
super.draw(canvas, mapView, shadow);
Point scrnPoint = new Point();
mapView.getProjection().toPixels(this.point, scrnPoint);
Bitmap marker = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
canvas.drawBitmap(marker, scrnPoint.x - marker.getWidth() / 2, scrnPoint.y - marker.getHeight() /2 , null);
return true;
}
I have an ImageView, which will fill the entire width of the screen and will also be animated up and down like a wave at the bottom of the screen. I have used scaleType="matrix" since it should not stretch to fit within the screen.
However, once it has been layouted, Android crops everything away that was outside at the time of layout-update, so once it starts to animate the bottom part is missing.
So my question is, how can I prevent Android from cropping my ImageView?
I wrote a class that seems to solve the problem, thought I´d share it if someone else faces this problem..
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.ImageView;
public class NoCropImageView extends ImageView
{
private int fixedWidth = 0;
private int fixedHeight = 0;
private int[] attrsArray = new int[] { android.R.attr.layout_width, android.R.attr.layout_height };
public NoCropImageView(final Context context, final AttributeSet attrs)
{
super(context, attrs);
TypedArray ta = context.obtainStyledAttributes(attrs, attrsArray);
int layout_width = ta.getDimensionPixelSize(0, ViewGroup.LayoutParams.MATCH_PARENT);
int layout_height = ta.getDimensionPixelSize(1, ViewGroup.LayoutParams.MATCH_PARENT);
ta.recycle();
fixedWidth = layout_width;
fixedHeight = layout_height;
}
#Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec)
{
this.setMeasuredDimension(fixedWidth, fixedHeight);
}
}
I'm trying to fix my camera app. When i hold the camera in landscape mode, it previews on the screen sideways.
I found this fix on stack : Android - Camera preview is sideways
In my CameraSurfaceView class constructor, I get the surface like this this.Surface = getHolder();.
In the surfaceChanged method i check the display rotation against Surface.ROTATION_<#> for 0,90,180,and 270 degrees (method below). However, each one of the ROTATIONSurface constants is underlined with the following error ROTATION_<#> cannot be resolved or is not a field. I am not sure what I am doing wrong. My CameraSurfaceView is separate from my activity so I'm wondering if the display has something to do with it?
Hope this is explained correctly, if you need more code or anything let me know. I appreciate this in advance!
import java.io.IOException;
import java.util.List;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.ZoomControls;
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
int orientation = 0;
Camera.Parameters params = Cam.getParameters();
WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
android.view.Display display = window.getDefaultDisplay();
if(display.getRotation() == Surface.ROTATION_0)
{
params.setPreviewSize(height, width);
Cam.setDisplayOrientation(90);
}
if(display.getRotation() == Surface.ROTATION_90)
{
params.setPreviewSize(height, width);
}
if(display.getRotation() == Surface.ROTATION_180)
{
params.setPreviewSize(height, width);
}
if(display.getRotation() == Surface.ROTATION_270)
{
params.setPreviewSize(height, width);
Cam.setDisplayOrientation(180);
}
List<Camera.Size> previewSizes = params.getSupportedPreviewSizes();
Camera.Size previewSize = getBestPreviewSize(width, height);
params.setPreviewSize(previewSize.width, previewSize.height);
int zoom = 0;
params.setZoom(zoom);
zoomControls.setOnZoomInClickListener(new View.OnClickListener(){
public void onClick(View v){
Camera.Parameters params = Cam.getParameters();
maxZoomLevel = params.getMaxZoom();
if(currentZoomLevel < maxZoomLevel){
currentZoomLevel++;
Cam.startSmoothZoom(currentZoomLevel);
}
}
});
zoomControls.setOnZoomOutClickListener(new View.OnClickListener(){
public void onClick(View v){
Camera.Parameters params = Cam.getParameters();
maxZoomLevel = params.getMaxZoom();
if(currentZoomLevel > 0){
currentZoomLevel--;
Cam.startSmoothZoom(currentZoomLevel);
}
}
});
Cam.setParameters(params);
try {
Cam.setPreviewDisplay(Surface);
} catch (IOException e) {
e.printStackTrace();
}
Cam.startPreview();
}
Since you have a field named Surface, you cannot access the class Surface from within your class.
Instead, you will have to write
android.view.Surface.ROTATION_0
or rename your field.
You've named your field Surface, which is also the name of the type you are trying to reference a constant from. Rename the field so that it does not have the same name as the type, then import android.view.Surface and you should be able to reference Surface.ROTATION_0 etc with no problems.
Note that Java style usually dictates you start variable names with lower case, and types with upper case, which avoids this type of conflict.
I already made a simple android application, which I also have integrated Google Maps in it..
It is also capable of connecting to MySQL (localhost) to display my desired places using longitude and latitude values..
My question is, is it possible to make another overlay item above Google Maps when a marker is clicked (just like what happens in foursquare)?
To be specific, i want to display a text that contains the name of a place.
Heres my class of displaying the overlay items.
I made an onTap method, but it display a dialog box, I want to display a simple text box that shows the name of the place.
package finddroid.map;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;
public class CustomItemizedOverlay extends ItemizedOverlay<OverlayItem>
{
private int markerHeight;
private ArrayList<OverlayItem> mapOverlays = new ArrayList<OverlayItem>();
private Context context;
public CustomItemizedOverlay(Drawable defaultMarker)
{
super(boundCenterBottom(defaultMarker));
markerHeight = ((BitmapDrawable) defaultMarker).getBitmap().getHeight();
populate();
}
public CustomItemizedOverlay(Drawable defaultMarker, Context context)
{
this(defaultMarker);
this.context = context;
}
#Override
protected OverlayItem createItem(int i)
{
return mapOverlays.get(i);
}
#Override
public int size()
{
return mapOverlays.size();
}
#Override
//Event when a place is tapped
protected boolean onTap(int index)
{
OverlayItem item = mapOverlays.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.show();
return true;
}
public void addOverlay(OverlayItem overlay)
{
mapOverlays.add(overlay);
this.populate();
}
}
Have a look at this project - balloon itemized overlay. It is using own class extending FrameLayout to show balloons.
So if you want to modify your code put this into your onTap method to display a TextView above taped item
TextView text = new TextView(context);
text.setText(item.getTitle());
MapView.LayoutParams params = new MapView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, item.getPoint(), MapView.LayoutParams.BOTTOM_CENTER);
params.mode = MapView.LayoutParams.MODE_MAP;
mMapView.addView(text, params);
I think this code is simple and easy to understand and you can improve it accordingly to your needs. To make it work you have to pass instance of MapView to constructor of your overlay and save it to private variable mMapView.
private MapVeiw mMapView;
public CustomItemizedOverlay(Drawable defaultMarker, Context context, MapView mapView) {
this(defaultMarker);
this.context = context;
this.mMapView = mapView;
}
And don't forget to add MapView as one of parameters when you call new CustomItemizedOverlay().
I'm trying to complete the Android MapView tutorial # www.developer.android.com/resources/tutorials/views/hello-mapview.html
I think I've done the entire thing correctly but I'm getting an error message in Eclipse. I'm sure why. The problematic line of code is
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
I'm relatively new to Java but I've gone through the forums of different things and I really have no idea on this one. I've [attached][2] a screen shot of the development environment - hopefully it wont be anything too obvious or hard to fix either!
http://www.limedomains.com/files/download/34780?dirname=&file_name=hellogooglemaps.jpg
Cheers
Tom :)
** As requested heres the source code and the screenshot link is updated to something that works**
package com.example.hellogooglemaps;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
public class HelloItemizedOverlay extends ItemizedOverlay{
public HelloItemizedOverlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
}
#Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}
#Override
public int size() {
return mOverlays.size();
}
public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
super(defaultMarker);
mContext = context;
}
#Override
protected boolean onTap(int index) {
OverlayItem item = mOverlays.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.show();
return true;
}
}
You need to declare the ArrayList inside the class, not outside, like this:
public class HelloItemizedOverlay extends ItemizedOverlay {
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
}
Your screenshot is impossible to read.. please copy/paste what the logcat says...
For my personnal use, i use this code: List mapOverlays;