How to custom marker InfoWindow in googleMap on android

Viewed 1241

In my application I want to make custom marker InfoWindow and transparent background for this.
I wrote the code below but it shows me wrong background again. I want the transparent background, not white.

My code:

       this.infoWindow = (ViewGroup) getLayoutInflater().inflate(R.layout.custominfowindow_one_button, null);

    this.infoButton = (Button) infoWindow.findViewById(R.id.button);
    this.infoButton_cancel=(Button) infoWindow.findViewById(R.id.btn_close_infowindow) ;
    mapWrapperLayout = (MapWrapperLayout) findViewById(R.id.map_relative_layout);
    mapWrapperLayout.init(mMap, getPixelsFromDp(this, 39 + 20));
    infoButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            infoWindowReady = !infoWindowReady;
        }
    });

    this.infoButtonListener = new OnInfoWindowElemTouchListener(infoButton, getResources().getDrawable(R.color.trans),
            getResources().getDrawable(R.color.trans),context) {
        @Override
        protected void onClickConfirmed(View v, Marker marker) {

        }
    };

    this.infoButton.setOnTouchListener(infoButtonListener);
    this.infoButton_cancelListener = new OnInfoWindowElemTouchListener(infoButton_cancel, getResources().getDrawable(R.drawable.ic_cancel3),
            getResources().getDrawable(R.drawable.ic_cancel3),context) {
        @Override
        protected void onClickConfirmed(View v, Marker marker) {
            addmarker_map.hideInfoWindow();

        }
    };

    this.infoButton_cancel.setOnTouchListener(infoButton_cancelListener );

    mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
        @Override
        public View getInfoWindow(Marker marker) {
            return null;
        }

        @Override
        public View getInfoContents(Marker marker) {

            if (serviceName == "geocode" && !hasGeoInfo) {
                if (__counter == 1) {
                    infoButton.setText("نشانگر");
                    togglePopup();
                } else if (__counter + "" == null) {
                    __counter = 0;
                    __counter++;
                } else {
                    __counter++;
                }
            }
            infoButtonListener.setMarker(marker);
            mapWrapperLayout.setMarkerWithInfoWindow(marker, infoWindow);
            return infoWindow;
        }
    });

My XML codes:

    <?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/dfhdfthd">

    <Button
        android:id="@+id/btn_close_infowindow"
        android:layout_width="@dimen/size25dp"
        android:layout_height="@dimen/size25dp"
        android:layout_marginLeft="@dimen/size70dp"
        android:background="@drawable/ic_cancel3"
        android:backgroundTint="#868585" />


    <Button
        android:id="@+id/button"
        android:layout_width="@dimen/size100dp"
        android:layout_height="@dimen/size30dp"
        android:layout_below="@+id/btn_close_infowindow"
        android:layout_marginTop="-5dp"
        android:background="@color/trans" />


</RelativeLayout>

please see this image to understand what i mean : https://image.ibb.co/bsx7W5/photo_2017_09_21_12_44_22.jpg

How can i make transparent background for infoWindows? Please help me.

5 Answers

Download below image copy into drawable with the name of custom_info_bubble.9.png

enter image description here

Add backgound on custominfowindow_one_button root layout

android:background="@drawable/custom_info_bubble"

Xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">

    <Button
        android:id="@+id/btn_close_infowindow"
        android:layout_width="@dimen/size25dp"
        android:layout_height="@dimen/size25dp"
        android:layout_marginLeft="@dimen/size70dp"
        android:background="@drawable/ic_cancel3"
         />

    <Button
        android:id="@+id/button"
        android:layout_width="@dimen/size100dp"
        android:layout_height="@dimen/size30dp"
        android:layout_below="@+id/btn_close_infowindow"
        android:layout_marginTop="-5dp"
         />
</RelativeLayout>

You can use @android:color/transparent color for your custominfowindow_one_button layout's background color

Create /res/layout/custom_info_contents.xml to define the layout of our custom info contents.

<?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:orientation="horizontal">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="5dp"
            android:adjustViewBounds="true"
            android:src="@drawable/ic_launcher"/>
        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="12dp"
            android:textStyle="bold"/>
        <TextView
            android:id="@+id/snippet"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="10dp"/>
    </LinearLayout>

</LinearLayout>

To implement our custom info contents, we have to create our custom InfoWindowAdapter class. Override getInfoContents(Marker marker) to return our custom view. And call myMap.setInfoWindowAdapter(new MyInfoWindowAdapter()) to set our InfoWindowAdapter. In this exercise, we haven't handle getInfoWindow(Marker marker), simple return null.

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.MapFragment;
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 android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity 
 implements OnMapLongClickListener{

 class MyInfoWindowAdapter implements InfoWindowAdapter{

        private final View myContentsView;

  MyInfoWindowAdapter(){
   myContentsView = getLayoutInflater().inflate(R.layout.custom_info_contents, 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());

            return myContentsView;
  }

  @Override
  public View getInfoWindow(Marker marker) {
   // TODO Auto-generated method stub
   return null;
  }

 }

 final int RQS_GooglePlayServices = 1;
 GoogleMap myMap;
 TextView tvLocInfo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvLocInfo = (TextView)findViewById(R.id.locinfo);

        FragmentManager myFragmentManager = getFragmentManager();
        MapFragment myMapFragment 
         = (MapFragment)myFragmentManager.findFragmentById(R.id.map);
        myMap = myMapFragment.getMap();

        myMap.setMyLocationEnabled(true);

        //myMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        //myMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
        //myMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
        myMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);

        myMap.getUiSettings().setZoomControlsEnabled(true);
        myMap.getUiSettings().setCompassEnabled(true);
        myMap.getUiSettings().setMyLocationButtonEnabled(true);

        myMap.getUiSettings().setRotateGesturesEnabled(true);
        myMap.getUiSettings().setScrollGesturesEnabled(true);
        myMap.getUiSettings().setTiltGesturesEnabled(true);
        myMap.getUiSettings().setZoomGesturesEnabled(true);
        //or myMap.getUiSettings().setAllGesturesEnabled(true);

        myMap.setTrafficEnabled(true);

        myMap.setOnMapLongClickListener(this);

        myMap.setInfoWindowAdapter(new MyInfoWindowAdapter());

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  switch (item.getItemId()) {
  case R.id.menu_legalnotices:
   String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(
     getApplicationContext());
   AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MainActivity.this);
   LicenseDialog.setTitle("Legal Notices");
   LicenseDialog.setMessage(LicenseInfo);
   LicenseDialog.show();
   return true; 
  }
  return super.onOptionsItemSelected(item);
 }

 @Override
 protected void onResume() {

  super.onResume();

  int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());

  if (resultCode == ConnectionResult.SUCCESS){
   Toast.makeText(getApplicationContext(), 
     "isGooglePlayServicesAvailable SUCCESS", 
     Toast.LENGTH_LONG).show(); 
  }else{
   GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices); 
  }
 }
 @Override
 public void onMapLongClick(LatLng point) {
  tvLocInfo.setText("New marker added@" + point.toString());
  Marker newMarker = myMap.addMarker(new MarkerOptions()
        .position(point)
        .snippet(point.toString()));
  newMarker.setTitle(newMarker.getId());
 }
}

and change the background colour to transparent

Just posting my solution here:

class InfoWindowAdapter(val context: Context) : GoogleMap.InfoWindowAdapter {
    private val iconFactory: IconGenerator by lazy {
        IconGenerator(context)
    }

    override fun getInfoContents(marker: Marker?): View? {
        return null
    }

    override fun getInfoWindow(marker: Marker?): View? {
        iconFactory.setTextAppearance(context, R.style.MarkerText)
        iconFactory.setColor(ContextCompat.getColor(context, R.color.vz_green))
        return ImageView(context).apply {
            setImageBitmap(iconFactory.makeIcon(marker?.title ?: ""))
        }
    }
}

The IconFactory class is from Google Maps Android Utils. You can find a demo here.

Related