Chuyển đến nội dung chính

Google Maps Android Custom Info Window Example

https://www.zoftino.com/google-maps-android-custom-info-window-example

You can display information about a location where you add a marker on the Google map by customizing info window. This post shows how to define custom info window layout and custom info window adapter and use it to display customized info window on the Google map.


You can read my previous tutorial about Google maps android API to know how to use Google play service API in android applications and view Google maps android API examples.
Before you continue with this example, you may want to learn android and latest features with examples. Please visit android tutorials for all android concepts, components and libraries with examples which use latest components and API.

Google Maps Android Custom Info Window Example Output

android google maps custom info window example

Google Maps Android Custom Info Window Example

To create custom info window, first you need to define layout for info window with elements such as image and text view which you want to display in your custom info window.
 <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="@style/TextAppearance.AppCompat.Headline"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
    <ImageView
        android:id="@+id/pic"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/name"/>
    <TextView
        android:id="@+id/details"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="false"
        android:layout_marginTop="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/pic" />
    <TextView
        android:id="@+id/hotels"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:textColor="#c2185b"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/details"/>
    <TextView
        android:id="@+id/food"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:textColor="#1976d2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/hotels"/>
    <TextView
        android:id="@+id/transport"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:textColor="#64dd17"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/food"/>

</android.support.constraint.ConstraintLayout>
 
After custom info window layout is defined, you need to define custom InfoWindowAdapter class by implementing GoogleMap.InfoWindowAdapter interface. InfoWindowAdapter interface has two methods getInfoContents and getInfoWindow methods which you need to implement.
If you want to define your own window, you need to implement getInfoWindow method otherwise just return null to indicate that you use default window. To provide content for info window, you need to implement getInfoContents methods. You need to use your custom layout in this method and populate values into the elements of the layout.
To pass information from activity to custom InfoWindowAdapter, you can create data transfer object. In your activity, this object is added to marker using setTag method passing the object. Since Marker object is passed to getInfoContents method, you can get tag object and use data to populate elements in info window layout as show in the example.
 import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.Marker;

public class CustomInfoWindowGoogleMap implements GoogleMap.InfoWindowAdapter {

    private Context context;

    public CustomInfoWindowGoogleMap(Context ctx){
        context = ctx;
    }

    @Override
    public View getInfoWindow(Marker marker) {
        return null;
    }

    @Override
    public View getInfoContents(Marker marker) {
        View view = ((Activity)context).getLayoutInflater()
.inflate(R.layout.map_custom_infowindow, null);

        TextView name_tv = view.findViewById(R.id.name);
        TextView details_tv = view.findViewById(R.id.details);
        ImageView img = view.findViewById(R.id.pic);

        TextView hotel_tv = view.findViewById(R.id.hotels);
        TextView food_tv = view.findViewById(R.id.food);
        TextView transport_tv = view.findViewById(R.id.transport);

        name_tv.setText(marker.getTitle());
        details_tv.setText(marker.getSnippet());

        InfoWindowData infoWindowData = (InfoWindowData) marker.getTag();

        int imageId = context.getResources().getIdentifier(infoWindowData.getImage().toLowerCase(),
                "drawable", context.getPackageName());
        img.setImageResource(imageId);

        hotel_tv.setText(infoWindowData.getHotel());
        food_tv.setText(infoWindowData.getFood());
        transport_tv.setText(infoWindowData.getTransport());

        return view;
    }
}
 
In the activity, first define marker options and add to map, then instantiate data object, populate values and add it to Marker by calling setTag and finally instantiate custom info window class and add it to Marker by calling setInfoWindowAdapter method.
 import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
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;

public class GoogleMapInfoWindowActivity extends AppCompatActivity implements OnMapReadyCallback {

    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.maps_infowindow);

        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.gmap);
        mapFragment.getMapAsync(this);
    }


    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        mMap.getUiSettings().setZoomControlsEnabled(true);
        mMap.setMinZoomPreference(11);

        LatLng snowqualmie = new LatLng(47.5287132, -121.8253906);

        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(snowqualmie)
                .title("Snowqualmie Falls")
                .snippet("Snoqualmie Falls is located 25 miles east of Seattle.")
                .icon(BitmapDescriptorFactory.defaultMarker( BitmapDescriptorFactory.HUE_BLUE));

        InfoWindowData info = new InfoWindowData();
        info.setImage("snowqualmie");
        info.setHotel("Hotel : excellent hotels available");
        info.setFood("Food : all types of restaurants available");
        info.setTransport("Reach the site by bus, car and train.");

        CustomInfoWindowGoogleMap customInfoWindow = new CustomInfoWindowGoogleMap(this);
        mMap.setInfoWindowAdapter(customInfoWindow);

        Marker m = mMap.addMarker(markerOptions);
        m.setTag(info);
        m.showInfoWindow();

        mMap.moveCamera(CameraUpdateFactory.newLatLng(snowqualmie));
    }
}
 
Below is the data transfer object used to transfer data from activity to info window adapter class.
 public class InfoWindowData {
    private String image;
    private String hotel;
    private String food;
    private String transport;

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public String getHotel() {
        return hotel;
    }

    public void setHotel(String hotel) {
        this.hotel = hotel;
    }

    public String getFood() {
        return food;
    }

    public void setFood(String food) {
        this.food = food;
    }

    public String getTransport() {
        return transport;
    }

    public void setTransport(String transport) {
        this.transport = transport;
    }
}

Nhận xét

Bài đăng phổ biến từ blog này

NHỮNG WIDGET THƯỜNG DÙNG TRONG FLUTTER

 https://baoflutter.com/nhung-widget-thuong-dung-trong-flutter/ Trong bài viết trước về  cách xây dựng màn hình ứng dụng Flutter , các bạn biết rằng các màn hình ứng dụng được tạo ra bởi các widget ghép lại với nhau. Vì vậy việc hiểu và sử dụng các Widget là rất quan trọng. Vì vậy trong bài viết này, tôi sẽ giới thiệu cho các bạn về những widget quan trọng trong Flutter. Hầu hết các Widget đều có các phần sau đây: + Đặc tính của Widget như : color, theme, height, weight, decoration, onTap, onPressed + Liên kết với các Widget khác với từ khoá: child, children, home hoặc body Ví dụ : 1 2 3 4 5 6 Container ( color : Colors . blue , height : 300 , weight : 300 , child : Text ( "Widget con" ) , ) Khi làm một số App cơ bản, bạn sẽ nắm chắc được cách sử dụng các Widget hay dùng. MaterialApp – Là widget rất liện lợi, cung cấp các widget cho việc xây dựng ứng dụng sử dụng thư viện Material Design UI của google. – Widget này được sử dụng trong hàm build đầu tiên của hầu hết các ứn...

Các bước cơ bản sử dụng Retrofit để thao tác với API và MVP

 Cài đặt  Retrofit //Retrofit implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' Cài đặt Gson implementation 'com.google.code.gson:gson:2.8.9' Cài thư viện Okhttp implementation 'com.squareup.okhttp3:okhttp:3.12.0' Sử dụng Gson ở trong project: 1. Tạo class App import android.app.Application ; import com.google.gson.Gson ; public class App extends Application { private static App mSelf ; private Gson mGSon ; public static App self () { return mSelf ; } @Override public void onCreate () { super .onCreate() ; mSelf = this; mGSon = new Gson() ; } public Gson getGSon () { return mGSon ; } } 2. Chỉnh file AndroidManifest: <? xml version ="1.0" encoding ="utf-8" ?> <manifest xmlns: android ="http://schemas.android.com/apk/res/android" xmlns: tools ="http://schemas.android....

Cấu trúc cơ bản layout trong Flutter