I started with the sample code CurrentPlaceDetailsOnMap from here:
CurrentPlaceDetailsOnMap
I changed it adding an image to the info view. and then I tried to load the image in the getInfoContents
#Override
public View getInfoContents(final Marker marker) {
// Inflate the layouts for the info window, title and snippet.
View infoWindow = getLayoutInflater().inflate(R.layout.custom_info_contents, (FrameLayout)findViewById(R.id.map), false);
TextView title = ((TextView) infoWindow.findViewById(R.id.title));
title.setText(marker.getTitle());
TextView snippet = ((TextView) infoWindow.findViewById(R.id.snippet));
snippet.setText(marker.getSnippet());
final ImageView imageView = ((ImageView) infoWindow.findViewById(R.id.image));
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Bitmap bitmap = getBitmap(MapsActivityCurrentPlace.this, R.drawable.my_bitmap;
imageView.setImageBitmap(bitmap);
}
});
return infoWindow;
}
In the code above I used the Handleronly to simulate what happens when I load the image asynchronously by calling Places.GeoDataApi.getPlacePhotos.
The result is that the image is not shown.
If I call:
Bitmap bitmap = getBitmap(MapsActivityCurrentPlace.this, R.drawable.my_bitmap;
imageView.setImageBitmap(bitmap);
synchronously everything is fine.
It looks like google Map caches the view creating an image of the entire view. From the doc:
Note: The info window that is drawn is not a live view. The view is rendered as an image (using View.draw(Canvas)) at the time it is returned. This means that any subsequent changes to the view will not be reflected by the info window on the map. To update the info window later (for example, after an image has loaded), call showInfoWindow(). Furthermore, the info window will not respect any of the interactivity typical for a normal view such as touch or gesture events. However you can listen to a generic click event on the whole info window as described in the section below.
How can I set the image in the InfoView?
The only solution I found so far is to load the bitmap in advance and to store it in a cache and then assign the bitmap to the infoview.imageView synchronously.
But this means that I have to load the images in advance.
Related
I have implemented a custom view that has a DraweeHolder. I have implemented all callbacks and listeners for my custom view (attach / detach / invalidateDrawable / setListener).
If I set a GIF image url to controller - it does not play gif correctly. It refreshes the gif only when the view is redrawn. I guess that animated GIF should have some invalidation callback or something.
P.S. Gif does work correctly if I use DraweeView. Also all other images work correctly inside my custom view.
Creating holder:
private DraweeHolder<GenericDraweeHierarchy> createComponentHolder(View parent, Context context) {
GenericDraweeHierarchy componentHierarchy = new GenericDraweeHierarchyBuilder(parent.getResources())
.setRoundingParams(RoundingParams.fromCornersRadius(LayoutHelper.dp(3)).setBorder(Theme.COLOR_MEDIA_BORDER, 1))
.build();
DraweeHolder<GenericDraweeHierarchy> holder = DraweeHolder.create(componentHierarchy, context);
holder.getTopLevelDrawable().setCallback(parent);
return holder;
}
Setting controller:
PipelineDraweeControllerBuilder controllerBuilder = Fresco.newDraweeControllerBuilder()
.setImageRequest(MediaHelper.getImageRequest(filePath))
.setAutoPlayAnimations(true)
.setControllerListener(controllerListener)
.setOldController(draweeHolder.getController());
if (thumbUrl != null) {
controllerBuilder.setLowResImageRequest(getThumbnailRequest(thumbUrl));
}
draweeHolder.setController(controllerBuilder.build());
Image request:
public static ImageRequest getImageRequest(String filePath) {
int imageSize = LayoutHelper.dp(100);
return ImageRequestBuilder.newBuilderWithSource(Uri.fromFile(new File(filePath)))
.setResizeOptions(new ResizeOptions(imageSize, imageSize))
.setAutoRotateEnabled(true)
.build();
}
There is no custom invalidation callback for GIFs, the animated drawable just invalidates itself for each frame, so if you set the callbacks the invalidation should just work.
However, if your Drawable callback (in your case parent) does not invalidate the correct area (or everything), the animated drawable invalidation will not refresh correctly.
An example when this can happen is when the callback does not know the exact location of the Drawable and invalidates a wrong area.
You can try debugging what the Drawable.Callback of your custom view does or write a custom Drawable.Callback class that invalidates the whole view including the GIF drawable.
Also, make sure to override verifyDrawable and follow all other steps for custom views as described in the Custom View documentation.
I have a task to show 5 images periodically. I'm using ViewFlipper for this. The images are loaded dynamically from gallery or camera.
I got stuck with modifying the image source at runtime i.e user should be able to change the current image he is viewing.
I can get the current index, now I want to change the image source from gallery at run time
// code to initialise the flipper
vf_profile_slide = (ViewFlipper) this.findViewById(R.id.profile_slide_vf);
int gallery_grid_Images[]={R.drawable.image1,R.drawable.image2};
for(int i=0;i<gallery_grid_Images.length;i++)
{
setFlipperImage(gallery_grid_Images[i]);
}
/* tempBmp = BitmapFactory.decodeFile(imgPath);
addNewImageToFlipper(mContext, tempBmp);
*/
vf_profile_slide.setAutoStart(true);
vf_profile_slide.setFlipInterval(5000);
vf_profile_slide.startFlipping();
//On button click i m feteching the image index
PROFILE_INDEX = vf_profile_slide.getDisplayedChild();
//calling this function...
private void addImageToFlipperAt(Context mContext,int index,Bitmap bm)
{
ImageView iv_new = (ImageView) findViewById(vf_profile_slide.getChildAt(index).getId());
iv_new.setImageBitmap(bm);
vf_profile_slide.addView(iv_new,index);
}
the new image is added successfully.... but i want the current image at that index gone... that is not happening .... tell me where i m going wrong
Is this possible?
I think I have the same issue with the post on this link
Different markers show same infowindow content android google map v2
I am currently developing an app that integrates Google Maps v2 to allow users to take picture and automatically plotting a marker on the map.
I have a working InfoWindowAdapter but it seems that when I set a Bitmap as you can see below:
ImageView ivIcon = ((ImageView)myContentsView.findViewById(R.id.iconImg));
ivIcon.setImageBitmap(getResizedBitmap(myBitmap.getBp(),100,100));
When taking multiple pictures using my camera (which means it will have respective markers plotted on the map), the markers all share the same image, which is the latest image taken from the camera. I thought creating a Class by checking for difference in Bitmap object name would solve the problem but it did not.
It seems that when applying:
myMap.setInfoWindowAdapter(new MyInfoWindowAdapter());
it applies to all markers.
How do I go around doing it that each marker would have its own custom info window adapter?
Thanks!
======================================== EDIT =================================
I have an application that will allow users to take pictures which will also plot a marker on the map of the location of image capture. The marker will have a custom InfoWindow. I tried the solution but they are vague to me.
Do you mind explaining what did you do to your code such that doing:
googleMap.setInfoWindowAdapter(new InfoWindowAdapter());
will not affect all the markers on the map?
My current code for the CustomInfoBox is as follows:
class MyInfoWindowAdapter implements InfoWindowAdapter{
private final View myContentsView;
MyInfoWindowAdapter(){
myContentsView = getLayoutInflater().inflate(R.layout.custom_info_window, null);
}
#Override
public View getInfoContents(Marker marker) {
//TextView tvTitle = ((TextView)myContentsView.findViewById(R.id.title));
// tvTitle.setText(marker.getTitle());
TextView tvSnippet = ((TextView)myContentsView.findViewById(R.id.snippet));
tvSnippet.setText(marker.getSnippet());
ImageView ivIcon = ((ImageView)myContentsView.findViewById(R.id.badge));
ivIcon.setImageBitmap(getResizedBitmap(myBitmap.getBp(),100,100));
System.out.println("Custom Info Window: " + myBitmap.getBp());
return myContentsView;
}
#Override
public View getInfoWindow(Marker marker) {
// TODO Auto-generated method stub
return null;
}
}
When I call googleMap.setInfoWindowAdapter(MyInfoWindowAdapter);, all markers have the same layout and thus same picture (last picture taken by user!) which is not something that I want.
Any help will be much appreciated! thanks
i am retriving around 20 images url from an xml , and appearing them in gridview.
thing going nice except one.
when i scroll down new images start loading , but when i again scrolls up. the previously loaded images again stars loading .
how can i resolve this bug. the previously loaded image should be retained in the layout , why it is not retaining itself .
I am using the adapter extends the BaseAdapter to view the images
Gridview like any other views that inherit AdapterView only uses the amount of views that you see on the screen. So when you scroll your views going to be reused. The Adapter's responsibility is to reassign the content to the views.
So, you need to cache your bitmaps. There is a very nice tutorial about this on the Android developer side.
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
(I uses grid view in the example)
Every time you scroll, getView() method of the adapter is called.
So every time one view come in to the screen is built in the getView() method.
You build the new view in that method, I suppose you download the image when that method is called, then one solution is caching the images. If you download few images and they are small size, a simply Map with key url and value bitmap solves the problem, if not, use database.
Every time getView() is called, check first if image is in cache, if image is in cache use it to build the view, if not download it.
use LoaderImageView from this blog http://blog.blundell-apps.com/imageview-with-loading-spinner/ & add following function
public void setImageDrawable(final MyGridViewItem obj) {
mDrawable = null;
if(obj.mDrawable != null){
mDrawable = obj.mDrawable
imageLoadedHandler.sendEmptyMessage(COMPLETE);
return;
}
mSpinner.setVisibility(View.VISIBLE);
mImage.setVisibility(View.GONE);
new Thread(){
public void run() {
try {
mDrawable = getDrawableFromUrl(imageUrl);
obj.mDrawable = mDrawable;
imageLoadedHandler.sendEmptyMessage(COMPLETE);
} catch (MalformedURLException e) {
imageLoadedHandler.sendEmptyMessage(FAILED);
} catch (IOException e) {
imageLoadedHandler.sendEmptyMessage(FAILED);
}
};
}.start();
}
I want to take a screen shot of my Activity and components of Activity (View).
This Activity contains a SurfaceView and a layout on the top of each other.
When I take screen shot of Surface view it works well, but when I take screen shot of whole Activity I do not get the surface view in it. I am using the following code:
public class Screenshot {
private final View view;
/** Create snapshots based on the view and its children. */
public Screenshot(View root) {
this.view = root;
}
/** Create snapshot handler that captures the root of the whole activity. */
public Screenshot(Activity activity) {
final View contentView = activity.findViewById(android.R.id.content);
this.view = contentView.getRootView();
}
/** Take a snapshot of the view. */
public Bitmap snap() {
Bitmap bitmap = Bitmap.createBitmap(this.view.getWidth(), this.view.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
}
What you can do as a workaround is capture both the layout and the SurfaceView images and draw the SurfaceView image over the layout image (using Canvas.drawBitmap) at the right coordinates using the properties of the SurfaceView.
Change this.view = contentView.getRootView(); to this.view = contentView;
Hope it will help.
I'm not sure if this is going to help or not but can't you just take the screen shot using DDMS directly?
EDIT
Have you tried getting the Window for the Activity and seeing what views/image cache you can pull out of that?