Thursday, August 1, 2013

Display Custom Info Window with ImageView on Google Map V2

Display Custom Info Window with ImageView on Google Map V2

 


To display image on Google Map V2 Bubble, we will be integrating Universal Image Loader
In Map V2, to display custom bubble, there is a InfoWindowAdapter class.

Implement the InfoWindowAdapter class and override 2 methods :
1. getInfoContents(Marker marker)
2. getInfoWindow(Marker marker)

Set InfoWindowAdapter
googleMap.setInfoWindowAdapter(new CustomInfoWindowAdapter());
Store Marker id in variable with each marker image URL. So, in CustomInfoWindowAdapter class, it can be accessed using Marker Id. Fro now we will store id in Hashtable:
markers.put(hamburg.getId(), "http://img.india-forums.com/images/100x100/37525-a-still-image-of-akshay-kumar.jpg");
Create custom_info_window.xml layout. It will be displayed when click on Marker.
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/custom_info_bubble"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/badge"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginRight="5dp"
        android:adjustViewBounds="true" >
    </ImageView>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:singleLine="true"
            android:textColor="#ff000000"
            android:textSize="14dp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/snippet"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#ff7f7f7f"
            android:textSize="14dp" />
    </LinearLayout>

</LinearLayout>

CustomInfoWindowAdapter 

package com.ngshah.goglemapv2withlazyloading;

import java.util.Hashtable;

import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.ngshah.goglemapv2withlazyloading.R;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.cache.memory.impl.FIFOLimitedMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.assist.SimpleImageLoadingListener;

public class MainActivity extends FragmentActivity {

    private GoogleMap googleMap;
    private final LatLng HAMBURG = new LatLng(53.558, 9.927);
    private final LatLng KIEL = new LatLng(53.551, 9.993);
    private Marker marker;
    private Hashtable<String, String> markers;
    private ImageLoader imageLoader;
    private DisplayImageOptions options;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                .getMap();
        
        initImageLoader();
        markers = new Hashtable<String, String>();
        imageLoader = ImageLoader.getInstance();
        
        options = new DisplayImageOptions.Builder()
            .showStubImage(R.drawable.ic_launcher)        //    Display Stub Image
            .showImageForEmptyUri(R.drawable.ic_launcher)    //    If Empty image found
            .cacheInMemory()
            .cacheOnDisc().bitmapConfig(Bitmap.Config.RGB_565).build();
        
        if ( googleMap != null ) {
           
            googleMap.setInfoWindowAdapter(new CustomInfoWindowAdapter());
           
            final Marker hamburg = googleMap.addMarker(new MarkerOptions().position(HAMBURG)
                        .title("Hamburg"));
            markers.put(hamburg.getId(), "http://img.india-forums.com/images/100x100/37525-a-still-image-of-akshay-kumar.jpg");
           
            final Marker kiel = googleMap.addMarker(new MarkerOptions()
                        .position(KIEL)
                        .title("Kiel")
                        .snippet("Kiel is cool")
                        .icon(BitmapDescriptorFactory
                            .fromResource(R.drawable.ic_launcher)));
            markers.put(kiel.getId(), "http://www.yodot.com/images/jpeg-images-sm.png");
             
            googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));
            googleMap.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
        }
    }
    
    private class CustomInfoWindowAdapter implements InfoWindowAdapter {

        private View view;

        public CustomInfoWindowAdapter() {
            view = getLayoutInflater().inflate(R.layout.custom_info_window,
                    null);
        }

        @Override
        public View getInfoContents(Marker marker) {

            if (MainActivity.this.marker != null
                    && MainActivity.this.marker.isInfoWindowShown()) {
                MainActivity.this.marker.hideInfoWindow();
                MainActivity.this.marker.showInfoWindow();
            }
            return null;
        }

        @Override
        public View getInfoWindow(final Marker marker) {
            MainActivity.this.marker = marker;

            String url = null;

            if (marker.getId() != null && markers != null && markers.size() > 0) {
                if ( markers.get(marker.getId()) != null &&
                        markers.get(marker.getId()) != null) {
                    url = markers.get(marker.getId());
                }
            }
            final ImageView image = ((ImageView) view.findViewById(R.id.badge));

            if (url != null && !url.equalsIgnoreCase("null")
                    && !url.equalsIgnoreCase("")) {
                imageLoader.displayImage(url, image, options,
                        new SimpleImageLoadingListener() {
                            @Override
                            public void onLoadingComplete(String imageUri,
                                    View view, Bitmap loadedImage) {
                                super.onLoadingComplete(imageUri, view,
                                        loadedImage);
                                getInfoContents(marker);
                            }
                        });
            } else {
                image.setImageResource(R.drawable.ic_launcher);
            }

            final String title = marker.getTitle();
            final TextView titleUi = ((TextView) view.findViewById(R.id.title));
            if (title != null) {
                titleUi.setText(title);
            } else {
                titleUi.setText("");
            }

            final String snippet = marker.getSnippet();
            final TextView snippetUi = ((TextView) view
                    .findViewById(R.id.snippet));
            if (snippet != null) {
                snippetUi.setText(snippet);
            } else {
                snippetUi.setText("");
            }

            return view;
        }
    }

    private void initImageLoader() {
        int memoryCacheSize;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
            int memClass = ((ActivityManager) 
                    getSystemService(Context.ACTIVITY_SERVICE))
                    .getMemoryClass();
            memoryCacheSize = (memClass / 8) * 1024 * 1024;
        } else {
            memoryCacheSize = 2 * 1024 * 1024;
        }

        final ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
                this).threadPoolSize(5)
                .threadPriority(Thread.NORM_PRIORITY - 2)
                .memoryCacheSize(memoryCacheSize)
                .memoryCache(new FIFOLimitedMemoryCache(memoryCacheSize-1000000))
                .denyCacheImageMultipleSizesInMemory()
                .discCacheFileNameGenerator(new Md5FileNameGenerator())
                .tasksProcessingOrder(QueueProcessingType.LIFO).enableLogging() 
                .build();

        ImageLoader.getInstance().init(config);
    }
} 

88 comments:

  1. Nishant, thanks for this great example! But I have one question: imagine I would like to make my info window exactly the same as the original, and the only thing I would like to change is its background color and opacity. Do you think there would be a simpler way to do that?

    ReplyDelete
  2. Hello Nishant ,
    Perfect example .
    But i want to set googleMap.addMarker(new MarkerOptions().icon using Lazy loading .

    Thanks
    Parag

    ReplyDelete
  3. Hello Nishant, Thanks for your sharing.
    This is very helpful for me.

    Thanks!

    ReplyDelete
  4. Nice tutorial..pls add the date when it is posted... :)

    ReplyDelete
  5. Thanks for solution... Point is that on UniversalImageLoader and onLoadingComplete(), call getInfoContents(marker) and after it calls rerun infoWindow with loaded image... :)

    ReplyDelete
  6. getInfoWindow() -> onLoadingComplete() -> getInfoContents(marker). This call comes in loop as showInfoWindow() again call getInfoWindow. This increases memory consumption and GC get called continuously.

    instaead of calling getInfoContents(marker) explicitly, image.setImageBitmap(loadedImage) will work perfect.

    ReplyDelete
  7. hi is there any way to get data in info window at multiple marker different data load from list

    ReplyDelete
  8. Hi!
    Thanks for your sharing,

    But I have problem in code:

    markers.put(hamburg.getId(), "http://img.india-forums.com/images/100x100/37525-a-still-image-of-akshay-kumar.jpg");

    I want picture url is a SDcard url...How do I change code?

    Thanks for all the help!

    ReplyDelete
  9. @drawable/custom_info_bubble is missing

    ReplyDelete
  10. Hi
    Thanks for sharing your code but i have a problem with onclick on textview in infowindow,Is it possible to make textview as a clickable in Infowindow?

    ReplyDelete
  11. * Project GogleMapV2WithLzyLoading:/home/jenya1/Downloads/GogleMapV2WithLzyLoading-master/project.properties:
    Library reference ../google-play-services_lib could not be found
    Path is /home/jenya1/Downloads/GogleMapV2WithLzyLoading-master/../google-play-services_lib which resolves to /home/jenya1/Downloads/google-play-services_lib

    ReplyDelete
  12. Great Article… I love to read your articles because your writing style is too good, its is very very helpful for all of us and I never get bored while reading your article because, they are becomes a more and more interesting from the starting lines until the end.
    python training in Bangalore

    ReplyDelete
  13. I'm here representing the visitors and readers of your own website say many thanks for many remarkable

    Tableau online training

    ReplyDelete
  14. Great post! I am actually getting ready to across this information, It’s very helpful for this blog.Also great with all of the valuable information you have Keep up the good work you are doing well.
    Sql server dba online training

    ReplyDelete
  15. Excellant post!!!. The strategy you have posted on this technology helped me to get into the next level and had lot of information in it..
    Oracle DBA Online Training

    ReplyDelete
  16. nice blog
    get best placement at VSIPL

    get digital marketing and web development service
    seo network point

    ReplyDelete
  17. I would like to thank you for the efforts you have made in writing this article. I am hoping the same best work from you in the future as well. In fact your creative writing abilities has inspired me to start my own BlogEngine blog now. Really the blogging is spreading its wings rapidly. Your write up is a fine example of it.
    Software testing online training
    Software testing certification training
    Software testing online course
    Software testing training course

    ReplyDelete
  18. Thanks for sharing it.I got Very valuable information from your blog.your post is really very Informatve. I got Very valuable information from your blog.I’m satisfied with the information that you provide for me.

    Python Training in Pune
    Python Classes
    Python Placement
    Python Institute Pune
    Python courses

    ReplyDelete
  19. Nice post
    For Python training in Bangalore, Visit:
    Python training in Bangalore

    ReplyDelete
  20. This is the exact information I am been searching for, Thanks for sharing the required infos with the clear update and required points. To appreciate this I like to share some useful information.python training in bangalore

    ReplyDelete
  21. Thanks for your excellent blog and giving great kind of information. So useful. Nice work keep it up thanks for sharing the knowledge.
    Devops training in Pune with placement

    ReplyDelete
  22. I am a regular reader of your blog and I find it really informative. Hope more Articles From You.Best Tableau tutorial video available Here. hope more articles from you.

    ReplyDelete
  23. Thanks a lot for sharing it, that’s truly has added a lot to our knowledge about this topic. Have a more success ful day. Amazing write-up, always find something interesting and here i want to share some thing about mulesoft training hyderabad .

    ReplyDelete
  24. Thanks for your excellent blog and giving great kind of information. So useful. Nice work keep it up thanks for sharing the knowledge.
    Visit us
    Click Here
    For More Details
    Visit Website

    ReplyDelete
  25. Thanks for your excellent blog and giving great kind of information. So useful. Nice work keep it up thanks for sharing the knowledge.
    Visit us
    Click Here
    For More Details
    Visit Website
    See More

    ReplyDelete
  26. Such a terrific facts for blogger i am a professional blogger thanks…

    click here formore info.

    ReplyDelete
  27. Nice post. Thanks for sharing! I want humans to understand simply how excellent this facts is to your article.
    It’s thrilling content material and Great work.
    isaimini movies hd

    ReplyDelete
  28. Thanks for sharing it.I got Very valuable information from your blog.your post is really very Informative.I’m satisfied with the information that you provide for me.Software testing is a process ensure that the product is defect free.By reading your blog, i get inspired and this provides some useful information. Keep it up and best of luck for your future blogs posts.

    software testing institute in pune at 3ri Technologies

    ReplyDelete
  29. Thanks for sharing it.I got Very valuable information from your blog.your post is really very Informative.I’m satisfied with the information that you provide for me.Nice post. By reading your blog, i get inspired and this provides some useful information.

    sap mm training in pune with placement

    ReplyDelete
  30. After I initially commented I seem to have clicked on the -Notify me when new comments are
    added- checkbox and now every time a comment is added I receive 4 emails with the exact same comment.
    There has to be an easy method you are able to remove me from that service? Kudos!
    Click here to more info.



    ReplyDelete
  31. I think this is one of the most important info for me.And i am glad reading your article. But want to remark on few general things, The site style is good , the articles is really excellent and also check Our Profile for
    sql training courses and sql server training videos.

    ReplyDelete

  32. This post is really nice and informative. The explanation given is really comprehensive and informative. I want to share some information about the best oracle dba training and oracle weblogic tutorial training videos. Thank you .Hoping more articles from you.

    ReplyDelete
  33. Thanks for the informative article About Reactjs. This is one of the best resources I have found in quite some time. Nicely written and great info. I really cannot thank you enough for sharing.

    Java training in chennai | Java training in annanagar | Java training in omr | Java training in porur | Java training in tambaram | Java training in velachery

    ReplyDelete
  34. I am inspired with your post writing style & how continuously you describe this topic. After reading your post, thanks for taking the time to discuss this servicenow training , I feel happy about it and I love learning more about this topic.

    ReplyDelete
  35. I use Facebook, along with Twitter and YouTube, as an important piece of my social media strategy.  I have made many great contacts on Facebook, and usually log in a couple of times a day. Resurge Diet Supplement

    ReplyDelete
  36. Amazing Article ! I have bookmarked this article page as i received good information from this. All the best for the upcoming articles. I will be waiting for your new articles. Thank You !
    AWS training in Chennai

    AWS Online Training in Chennai

    AWS training in Bangalore

    AWS training in Hyderabad

    AWS training in Coimbatore

    AWS training

    AWS online training

    ReplyDelete


  37. Wow. That is so elegant and logical and clearly explained. Brilliantly goes through what could be a complex process and makes it obvious.I want to refer about the best msbi training in hyderabad

    ReplyDelete
  38. Good Post! , it was so good to read and useful to improve my knowledge as an updated one, keep blogging.After seeing your article I want to say that also a well-written article with some very good information which is very useful for the readers....thanks for sharing it and do share more posts like this.
    https://www.3ritechnologies.com/course/mern-stack-training-in-pune/

    ReplyDelete
  39. Good Post! , it was so good to read and useful to improve my knowledge as an updated one, keep blogging. After seeing your article I want to say that also a well-written article with some very good information which is very useful for the AWS Cloud Practitioner Online Training

    ReplyDelete
  40. Thanks for this valuable piece of information... Saved the day.
    Also sharing hands to help for DevOps Online Training

    ReplyDelete
  41. Thanks for Sharing This Article.It is very so much valuable content. I hope these Commenting lists will help to my website
    top mulesoft online training

    ReplyDelete
  42. Thanks for your excellent blog and giving great kind of information. So useful. Nice work keep it up thanks for sharing the knowledge.
    DevOps Training in Chennai

    DevOps Course in Chennai

    ReplyDelete
  43. Good Post! , it was so good to read and useful to improve my knowledge as an updated one, keep blogging. After seeing your article I want to say that also a well-written article with some very good information which is very useful for the readers.thanks for sharing it and do share more posts like this.


    IT Training in Pune with placements

    IT Training in Pune

    ReplyDelete
  44. Keto Pills are the most popular type of weight loss product and chances are you’ve probably seen advertisements for keto products by now. These keto pure diet pills may help enhance your weight loss, boost your energy levels, and can make it easier for you to stick to your keto diet. Many of the most popular keto products contain exogenous ketones – ketones made outside of the body. These ketones are the fuel that your body burns instead of carbohydrates when you are on the keto diet. Check now the full Keto pure diet pills reviews for clear your doubt with full information. Some keto products may contain one or many other natural ingredients that may help boost your metabolism in addition to these exogenous ketones.

    ReplyDelete
  45. I’m glad you like my post! I learned many new things myself
    by cloudi5 is the digital marketing company in coimbatore

    ReplyDelete
  46. Actually your blog is very interesting; it contains extraordinary and remarkable data. I appreciated visiting your blog…

    DevOps Training in Hyderabad

    ReplyDelete
  47. thank you for sharing we are looking forward for more
    aws Training in Hyderabad

    ReplyDelete
  48. well, thats a great blog. Really so much impressive and i love that type of post. thank you.

    If you ssearching for a legit financial service .Check it out. Link below.
    Unclaimed Mystery Box
    deep web money transfer
    legit paypal transfer dark web
    darknet paypal transferpa
    dark web financial services .
    Please carry on and keep blogging . Thanks again

    ReplyDelete
  49. This comment has been removed by the author.

    ReplyDelete
  50. This comment has been removed by the author.

    ReplyDelete
  51. wow what is this really? Why aren't you doing this now? I think it's so awesome and awesome I have to 서울출장아로마
    인천출장아로마
    세종출장아로마
    서귀포출장아로마 share this with my friends and my son and wife right now I feel like I found an oasis in the desert Thank you so much for finding your site.

    ReplyDelete
  52. Really Nice Article! You post inspire me too much.
    lottery sambad from lotterysambad24hr.com

    ReplyDelete
  53. wordpress website design agency in united states Need professional WordPress Web Design Services? We're experts in developing attractive mobile-friendly WordPress websites for businesses. Contact us today!

    ReplyDelete
  54. Thanks for your excellent blog and giving great kind of information. So useful. Nice work keep it up thanks for sharing the knowledge.
    Hot Foil Stamping Machine
    Sweet Box Making Machine
    Die Punching Machine in India

    ReplyDelete
  55. This comment has been removed by the author.

    ReplyDelete
  56. The ultimate aim of installing ransomware into your system is to demand a lumpsum amount from you in the form of ransom. It may ask you to buy the Xhamster file decryption tool available online at an exorbitant price. xhamster ransomware

    ReplyDelete
  57. Get counselling sessions right away if you need assistance with an addiction.
    Best Rehab Center in India

    ReplyDelete
  58. cPanel License is a popular web hosting control panel that simplifies the process of website and server management.

    ReplyDelete