user8210794
user8210794

Reputation:

Android Google Maps Custom InfoWindow

I want to design a different info window on my own but couldn't find the right way for it.

As image shows here :

enter image description here

When I clicked to the marker I want to show a bar on bottom. I will give the details about marker on there. (It will include name, adress, icons) and also these name, address, must be clickable.

What are the possible methods (ways) to do it?

Upvotes: 1

Views: 8629

Answers (2)

Om Infowave Developers
Om Infowave Developers

Reputation: 1565

GoogleMap.InfoWindowAdapter will display the custom window that attach with marker if you want to display marker details at bottom of screen hide the custom window and and display the custom view on the MapView

main.xml

 <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <fragment xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:id="@+id/map"
            android:name="com.google.android.gms.maps.SupportMapFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context="com.iphonealsham.speedli.activitys.MapsActivity" />

        <LinearLayout
            android:id="@+id/linearLayoutCustomView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center_horizontal"
            android:orientation="vertical">

            <TextView
                android:id="@+id/textViewTitle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <TextView
                android:id="@+id/textViewOtherDetails"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </FrameLayout>

hide the InfoWidow by return true in onMarkerClick and display customView

 @Override
    public void onMapReady(GoogleMap googleMap) {
            mGoogleMap = googleMap;
            mGoogleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
                @Override
                public boolean onMarkerClick(Marker marker) {
                    Log.d("GoogleMap", " click");
//focus the market
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLng(marker.g‌​etPosition()));
                    if (linearLayoutCustomView.getVisibility() == View.VISIBLE)
                        linearLayoutCustomView.setVisibility(View.GONE);
                    else
                        displayCustomeInfoWindow(marker);
                    return true;
                }
            });
    }

Set details in view

 private void displayCustomeInfoWindow(Marker marker) {
        linearLayoutCustomView.setVisibility(View.VISIBLE);
        TextView textViewTitle = linearLayoutCustomView.findViewById(R.id.textViewTitle);
        TextView textViewOtherDetails = linearLayoutCustomView.findViewById(R.id.textViewOtherDetails);
        textViewTitle.setText(marker.getTitle());
        textViewOtherDetails.setText("LatLong :: " + marker.getPosition().latitude + "," + marker.getPosition().longitude);

    }

Upvotes: 1

Dipali Shah
Dipali Shah

Reputation: 3798

For Setting custom Marker

 googleMap.addMarker(iconGenerator.createMarker(latitude, longitude, your_string to display))

You can use com.google.maps.android.ui.IconGeneratorclass to generate Custom marker of Google Map utils.

Gradle line to include is

compile 'com.google.maps.android:android-maps-utils:0.3+

In my case I didn't wanted add one more library so pulled needed class and data from here..

public class IconGenerator {


    private static final int STYLE_DEFAULT = 1;
    private static final int STYLE_WHITE = 2;
    private static final int STYLE_RED = 3;
    private static final int STYLE_BLUE = 4;
    private static final int STYLE_GREEN = 5;
    private static final int STYLE_PURPLE = 6;
    private static final int STYLE_ORANGE = 7;
    private final Context mContext;
    private BubbleDrawable mBackground;
    private ViewGroup mContainer;
    private TextView mTextView;

    public IconGenerator(Context context) {
        mContext = context;
        mBackground = new BubbleDrawable(mContext.getResources());
        mContainer = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.amu_text_bubble, null);
        RotationLayout mRotationLayout = (RotationLayout) mContainer.getChildAt(0);
        mTextView = mRotationLayout.findViewById(R.id.amu_text);
        setStyle();
    }

    private static int getStyleColor(int style) {
        switch (style) {

            case STYLE_RED:
                return 0xffcc0000;
            case STYLE_BLUE:
                return 0xff0099cc;
            case STYLE_GREEN:
                return 0xff669900;
            case STYLE_PURPLE:
                return 0xff9933cc;
            case STYLE_ORANGE:
                return 0xffff8800;
            case STYLE_DEFAULT:
            case STYLE_WHITE:
            default:
                return 0xffffffff;
        }
    }

    private static int getTextStyle(int style) {
        switch (style) {
            case STYLE_RED:
            case STYLE_BLUE:
            case STYLE_GREEN:
            case STYLE_PURPLE:
            case STYLE_ORANGE:
                return R.style.amu_Bubble_TextAppearance_Light;
            case STYLE_DEFAULT:
            case STYLE_WHITE:
            default:
                return R.style.amu_Bubble_TextAppearance_Dark;
        }
    }

    public MarkerOptions createMarker(double latitude, double longitude, String text) {
        LatLng latLng = new LatLng(latitude, longitude);
        float mAnchorV = 1F;
        float mAnchorU = 0.5F;
        return new MarkerOptions().
                icon(BitmapDescriptorFactory.fromBitmap(makeIcon(text))).
                position(latLng).
                anchor(mAnchorU, mAnchorV);
    }

    private Bitmap makeIcon(CharSequence text) {
        if (mTextView != null) {
            mTextView.setText(text);
        }

        return makeIcon();
    }

    private Bitmap makeIcon() {
        int measureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        mContainer.measure(measureSpec, measureSpec);
        int measuredWidth = mContainer.getMeasuredWidth();
        int measuredHeight = mContainer.getMeasuredHeight();
        mContainer.layout(0, 0, measuredWidth, measuredHeight);
        Bitmap r = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888);
        r.eraseColor(Color.TRANSPARENT);
        Canvas canvas = new Canvas(r);
        mContainer.draw(canvas);
        return r;
    }

    private void setStyle() {
        setColor(getStyleColor(IconGenerator.STYLE_RED));
        setTextAppearance(mContext, getTextStyle(IconGenerator.STYLE_RED));
    }

    private void setColor(int color) {
        mBackground.setColor(color);
        setBackground(mBackground);
    }

    @SuppressWarnings("deprecation")
    // View#setBackgroundDrawable is compatible with pre-API level 16 (Jelly Bean).
    private void setBackground(Drawable background) {
        mContainer.setBackgroundDrawable(background);

        // Force setting of padding.
        // setBackgroundDrawable does not call setPadding if the background has 0 padding.
        if (background != null) {
            Rect rect = new Rect();
            background.getPadding(rect);
            mContainer.setPadding(rect.left, rect.top, rect.right, rect.bottom);
        } else {
            mContainer.setPadding(0, 0, 0, 0);
        }
    }

    private void setTextAppearance(Context context, int resid) {
        if (mTextView != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                mTextView.setTextAppearance(resid);
            } else
                mTextView.setTextAppearance(context, resid);
        }
    }

}

For custom Window

While creating marker set detail to marker and access those detail on getInfoContents method of googleMap.setInfoWindowAdapter also set your custom view with detail.

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

            @Override
            public View getInfoContents(Marker marker) {
                YourModelClassName detailDto = (YourModelClassName ) marker.getTag();
                View v = View.inflate(MapViewActivity.this, R.layout.custom_info_window, null);
               // set widget of your custom_layout like below
                CustomFTextView txtResourceName = v.findViewById(R.id.txt_resource_name);
                CustomFTextView txtResourceAddress = v.findViewById(R.id.txt_resource_address);
                ImageView imageViewPic = v.findViewById(R.id.img_event);
                if (detailDto != null) {
                    txtResourceName.setText(detailDto.getResourceName());
                    txtResourceAddress.setText(detailDto.getAddress());
                    String mUrl = base_Url + detailDto.getImageUrl();
                    Picasso.with(MapViewActivity.this).load(mUrl).resize(TARGET_WIDTH, TARGET_HEIGHT).centerInside().into(imageViewPic);
                }
                return v;
            }
        });

Set data to marker like this.

this.googleMap.addMarker(new MarkerOptions().position(sydney)).setTag(detailDto);

Upvotes: 0

Related Questions