Android Google 地图自定义信息窗口

Android Google Maps Custom InfoWindow

我想自己设计一个不同的信息window,但找不到合适的方法。

如图所示:

当我点击标记时,我想在底部显示一个栏。我将在那里提供有关标记的详细信息。 (它将包括名称、地址、图标)并且这些名称、地址必须是可点击的。

有哪些可能的方法(ways)可以做到?

用于设置自定义标记

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

您可以使用 com.google.maps.android.ui.IconGeneratorclass 生成 Google 地图实用程序的自定义标记。

Gradle 要包含的行是

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

在我的例子中,我不想再添加一个库,所以需要 class 和来自 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);
        }
    }

}

自定义Window

在为标记创建标记集详细信息并通过 googleMap.setInfoWindowAdaptergetInfoContents 方法访问这些详细信息时,还可以使用详细信息设置您的自定义视图。

 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;
            }
        });

像这样将数据设置为标记。

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

GoogleMap.InfoWindowAdapter 将显示带有标记的自定义 window 如果您想在屏幕底部显示标记详细信息隐藏自定义 window 并在屏幕上显示自定义视图地图视图

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>

onMarkerClickreturn true 隐藏 InfoWidow 并显示 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;
                }
            });
    }

在视图中设置详细信息

 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);

    }