1

I have a class called AnimalMarker which should represent the bare minimum of a normal google maps Marker (latitude, longitutde, location) and an object Animal. And I'm using the Firebase Realtime Database to store those AnimalMarkers.

What I want to do, but don't know how to do it, is create a custom InfoWindow (I've created the new layout and an Adapter that should be passed in the MapActivity) that even though is binding to the google maps Markers, should take data from the corresponding AnimalMarker of that Marker.

The logic of my MapActivity is:

  • create an AnimalMarker using the latitude,longitute, and taking user input for adding an animal to it. now the AnimalMarker object has been created
  • add the AnimalMarker to the Firebase Realtime Database
  • when the DatabaseListener gets the update, it will call a method in the MapActivity to re-create the List of google-maps Markers and re-draw them.

I realise now that instead of saving just the google-maps Markers in a List, a Hashmap < AnimalMarker, Marker > would be better, and update the Hashmap when the database Listener notices the update But even so, I wouldn't know how to make the InfoWindowAdapter take the data from the associated AnimalMarker of a Marker.

Here is my code:

MapActivity

public class MapActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.OnConnectionFailedListener {

...

private void initListeners() {
        Log.d(TAG, "initListeners: initializing SearchText");

        firebaseAuth = FirebaseAuth.getInstance();
        geocoder = new Geocoder(MapActivity.this);
        markersDatabase = new MarkersDatabase();
        myMarkersList = new ArrayList<>();
        allMarkersList = new ArrayList<>();


        mMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener(){
            @Override
            public void onMapLongClick(LatLng latLng) {
                List<Address> addresses = new ArrayList<>();
                try {
                    addresses = geocoder.getFromLocation(latLng.latitude, latLng.longitude, 1);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                String locationTitle = addresses.get(0).getAddressLine(0);
                Log.d(TAG, "onMapLongClick: addresses = " + addresses.get(0));

                AnimalMarker marker = new AnimalMarker(latLng.latitude, latLng.longitude, locationTitle, firebaseAuth.getCurrentUser().getUid());
                markersDatabase.addMarker(marker);
                mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(marker.getLatitude(), marker.getLongitude()), DEFAULT_ZOOM));

            }
        });


    }



...



    private void startMarkersListener() {
        markersDatabase.readCurrentUserMarkers(new MarkersDatabaseListener() {
            @Override
            public void onCurrentUserMarkersCallBack(List<AnimalMarker> list) {
                Log.d(TAG, "onCurrentUserMarkersCallBack: myMarkersList updated");

                clearAllMyMarkers();
                for (AnimalMarker animalMarker : list) {
                    Marker marker = mMap.addMarker(new MarkerOptions()
                            .position(new LatLng(animalMarker.getLatitude(), animalMarker.getLongitude()))
                            .title(animalMarker.getLocation())
                            .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN))
                            .visible(myMarkersVisible));

                    Log.d(TAG, "onCurrentUserMarkersCallBack: created a marker at: " + marker.getTitle());
                    myMarkersList.add(marker);
                }
            }

            @Override
            public void onAllMarkersCallBack(List<AnimalMarker> list) {
                Log.d(TAG, "onCurrentUserMarkersCallBack ----> onAllMarkersCallBack: should never reach here");

            }
        });

}


MarkerInfoWindowAdapter

public class MarkerInfoWindowAdapter implements GoogleMap.InfoWindowAdapter{

    private final View mWindow;
    private Context context;

    public MarkerInfoWindowAdapter(Context context) {
        this.context = context;
        mWindow = LayoutInflater.from(context).inflate(R.layout.marker_info_window, null);
    }

    private void renderWindowText(Marker marker, View view) {

        // example code to come here
        String title = marker.getTitle();
        TextView titleTextView = (TextView) view.findViewById(R.id.miwLocation);
        if(!title.equals("")) {
            titleTextView.setText(title);
        }

    }


    @Override
    public View getInfoWindow(Marker marker) {
        renderWindowText(marker, mWindow);
        return mWindow;
    }

    @Override
    public View getInfoContents(Marker marker) {
        renderWindowText(marker, mWindow);
        return mWindow;
    }
}



layout of my desired information in the custom InfoWindow:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/white_border"
    android:orientation="horizontal"
    android:padding="10dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/miwLocation"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_alignParentTop="true"
            android:layout_gravity="center_horizontal"
            android:layout_marginStart="150dp"
            android:layout_marginTop="5dp"
            android:ellipsize="end"
            android:maxLines="2"
            android:text="miwLocation"
            android:textColor="#000000"
            android:textSize="20sp"
            android:textStyle="bold" />

        <ImageView
            android:src="@drawable/dog_icon"
            android:id="@+id/miwImage"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_below="@+id/miwLocation"
            android:layout_alignParentStart="true"
            android:layout_marginStart="18dp"
            android:layout_marginTop="10dp" />

        <TextView
            android:id="@+id/miwAnimalName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/miwLocation"
            android:layout_marginStart="30dp"
            android:layout_marginTop="12dp"
            android:layout_toEndOf="@+id/miwImage"
            android:layout_toRightOf="@id/miwImage"
            android:ellipsize="end"
            android:maxLines="2"
            android:text="miwAnimalName"
            android:textColor="#000000"
            android:textSize="17sp" />

        <TextView
            android:id="@+id/miwAnimalAge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/miwAdultCB"
            android:layout_marginStart="20dp"
            android:layout_marginTop="10dp"
            android:layout_toRightOf="@id/miwImage"
            android:text="3 yrs"
            android:textColor="#000000"
            android:textSize="20sp" />

        <CheckBox
            android:id="@+id/miwAdultCB"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/miwAnimalName"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="8dp"
            android:layout_toRightOf="@id/miwImage"
            android:text=" Adult"
            android:textSize="20dp" />

        <CheckBox
            android:id="@+id/miwNeuteredCB"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/miwAnimalName"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="8dp"
            android:layout_toRightOf="@id/miwAdultCB"
            android:text=" Neutered"
            android:textSize="20dp" />

    </RelativeLayout>

</LinearLayout>

Image of it:

Imgur

Andy
  • 141
  • 3
  • 13

1 Answers1

0

I've found the solution after understanding the answer in this post

custom info window adapter with custom data in map v2

The easiest approach would to create an anonymous Adapter and use the global HashMap< Marker, AnimalMarker > inside it.

Something like this


getMap().setInfoWindowAdapter(new InfoWindowAdapter() {

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

        @Override
        public View getInfoContents(Marker arg0) {

            // set layout, use Marker/AnimalMarker here

        }
    });

Andy
  • 141
  • 3
  • 13