Android 有没有一种方法可以实现Mapfragment的圆角?

Android 有没有一种方法可以实现Mapfragment的圆角?,android,android-layout,android-maps-v2,Android,Android Layout,Android Maps V2,我想给地图一个好看的圆角,因为下面的两个框有。 我不能用它自己的映射片段来完成它,因为它本身没有一个背景属性 碎片。 在布局中设置地图并将其背景设置为圆形对我没有帮助 这就是结果: 我可以合并地图,但这会使它变小,我想避免它 编辑: @Ryan这是新的结果#2: 我想这还不错,即使是靠近其他盒子的角落, 但还是不错,再多做一点工作,我就没有一个普通的图像编辑器了。 但有一件事现在仍然困扰着我,那就是“位置”文本视图和地图本身之间的分离。我能不能换一种方式画这块地,这样就有了距离?我就是这样做

我想给地图一个好看的圆角,因为下面的两个框有。 我不能用它自己的映射片段来完成它,因为它本身没有一个背景属性 碎片。 在布局中设置地图并将其背景设置为圆形对我没有帮助 这就是结果:

我可以合并地图,但这会使它变小,我想避免它

编辑: @Ryan这是新的结果#2:

我想这还不错,即使是靠近其他盒子的角落, 但还是不错,再多做一点工作,我就没有一个普通的图像编辑器了。 但有一件事现在仍然困扰着我,那就是“位置”文本视图和地图本身之间的分离。我能不能换一种方式画这块地,这样就有了距离?我就是这样做的:

我终于明白了这一点:

这是我在补丁中使用的:


谢谢。

我还没有试过,但是我在mapView/mapFragment的顶部放了一个圆角和透明中间的视图

也就是说,将mapFragment和圆角视图放置在框架布局中,两者都填充框架布局,然后使圆角视图的中间透明

为了进一步澄清,您可以在布局中执行此操作,如下所示:-

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<fragment
    xmlns:map="http://schemas.android.com/apk/res-auto"
    android:id="@+id/mapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    class="com.google.android.gms.maps.MapFragment" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/rounded_background"
    android:orientation="vertical" >
</LinearLayout>

</FrameLayout>

圆形的_背景是一个带有圆角和透明中间的9面片。例如

希望有帮助


Ryan

对于其他研究此问题的人,我只是使用GoogleMap.snapshot解决了此问题,并使用此堆栈溢出答案处理位图结果:

请注意,只有当您将拥有一个不与之交互的静态映射时,这才有效

确保在加载地图后拍摄快照

我更新了图像视图辅助程序代码,以使用路径绘制,从而仅支持圆角。如果你只想把其中两个角弄圆

您只需要采用浮点[]的path round rect函数

我会显示一个进度条,直到我从GoogleMap加载的侦听器中得到一个回调,然后再拍摄快照

如果太早拍摄快照,则会出现“无法创建宽度和高度为0的位图”错误


希望这对在静态地图快照中查找圆角或其他奇怪形状的人有所帮助。

最简单的方法是将地图片段与ImageView一起包装在FrameLayout中。Imageview将在地图片段顶部显示一个圆角矩形。在最简单的形式中,您将看到圆角矩形内的地图片段,其角突出圆角矩形,因为地图视图本身不是圆角。为了克服这种视觉上的奇怪现象,只需在地图片段上应用一个layout_边距值。该值应等于矩形的边框宽度

   <FrameLayout
    android:id="@+id/map_container"
    android:layout_width="wrap_content"
    android:layout_height="340dp" >

    <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="3dp"
        android:name="com.google.android.gms.maps.SupportMapFragment"/>

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/map_bg_box" />

</FrameLayout>

可绘制的矩形定义为xml形状,如下所示

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <stroke android:width="3dp"
    android:color="#ff000000" />

    <corners android:bottomRightRadius="7dp" android:bottomLeftRadius="7dp"
    android:topLeftRadius="7dp" android:topRightRadius="7dp"/>

</shape>

请注意,矩形的笔划宽度为3dp,与我们应用于贴图片段的layout_margin属性的值完全相同。结果是一个很好的圆角地图片段,如下面的屏幕截图所示

如果您只想针对API 21(棒棒糖)及更高版本


这是可能的最简单的方法

parentView.setCliptOutline(true)

结果


在此布局中包装地图片段:

package com.example.yourpackage;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.widget.RelativeLayout;

/**
 * Just extend any Layout you like/need
 */
public class RoundedLayout extends RelativeLayout {

private Path mPathCorners = new Path();
private Path mPathCircle = new Path();
private float mCornerRadius;

/**
 * border path
 */
private Path mPathCornersBorder = new Path();
private Path mPathCircleBorder = new Path();
private int mBorderWidth = 0;
private int mBorderHalf;
private boolean mShowBorder = false;
private int mBorderColor = 0xFFFF7700;

private float mDensity = 1.0f;

/**
 * Rounded corners or circle shape
 */
private boolean mIsCircleShape = false;

private Paint mPaint = new Paint();

private float dpFromPx(final float px) {
    return px / mDensity;
}

private float pxFromDp(final float dp) {
    return dp * mDensity;
}

public RoundedLayout(Context context) {
    this(context, null);
}

public RoundedLayout(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public RoundedLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mDensity = getResources().getDisplayMetrics().density;
    // just a default for corner radius
    mCornerRadius = pxFromDp(25f);

    mPaint.setAntiAlias(true);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setColor(mBorderColor);
    setBorderWidth(Math.round(pxFromDp(2f)));
}

/**
 * Switch to circle or rectangle shape
 *
 * @param useCircle
 */
public void setShapeCircle(boolean useCircle) {
    mIsCircleShape = useCircle;
    invalidate();
}

/**
 * change corner radius
 *
 * @param radius
 */
public void setCornerRadius(int radius) {
    mCornerRadius = radius;
    invalidate();
}

public void showBorder(boolean show) {
    mShowBorder = show;
    invalidate();
}

public void setBorderWidth(int width) {
    mBorderWidth = width;
    mBorderHalf = Math.round(mBorderWidth / 2);
    if (mBorderHalf == 0) {
        mBorderHalf = 1;
    }

    mPaint.setStrokeWidth(mBorderWidth);
    updateCircleBorder();
    updateRectangleBorder();
    invalidate();
}

public void setBorderColor(int color) {
    mBorderColor = color;
    mPaint.setColor(color);
    invalidate();
}

// helper reusable vars, just IGNORE
private float halfWidth, halfHeight, centerX, centerY;
private RectF rect = new RectF(0, 0, 0, 0);
private RectF rectBorder = new RectF(0, 0, 0, 0);

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);

    // just calculate both shapes, is not heavy

    // rounded corners path
    rect.left = 0;
    rect.top = 0;
    rect.right = w;
    rect.bottom = h;
    mPathCorners.reset();
    mPathCorners.addRoundRect(rect, mCornerRadius, mCornerRadius, Path.Direction.CW);
    mPathCorners.close();

    // circle path
    halfWidth = w / 2f;
    halfHeight = h / 2f;
    centerX = halfWidth;
    centerY = halfHeight;
    mPathCircle.reset();
    mPathCircle.addCircle(centerX, centerY, Math.min(halfWidth, halfHeight), Path.Direction.CW);
    mPathCircle.close();

    updateRectangleBorder();
    updateCircleBorder();
}

// helper reusable var, just IGNORE
private int save;

@Override
protected void dispatchDraw(Canvas canvas) {
    save = canvas.save();
    canvas.clipPath(mIsCircleShape ? mPathCircle : mPathCorners);
    super.dispatchDraw(canvas);
    canvas.restoreToCount(save);

    if (mShowBorder) {
        canvas.drawPath(mIsCircleShape ? mPathCircleBorder : mPathCornersBorder, mPaint);
    }
}

private void updateCircleBorder() {
    // border path for circle
    mPathCircleBorder.reset();
    mPathCircleBorder.addCircle(centerX, centerY, Math.min(halfWidth - mBorderHalf,
            halfHeight - mBorderHalf), Path.Direction.CW);
    mPathCircleBorder.close();
}

private void updateRectangleBorder() {
    // border path for rectangle
    rectBorder.left = rect.left + mBorderHalf;
    rectBorder.top = rect.top + mBorderHalf;
    rectBorder.right = rect.right - mBorderHalf;
    rectBorder.bottom = rect.bottom - mBorderHalf;
    mPathCornersBorder.reset();
    mPathCornersBorder.addRoundRect(rectBorder, mCornerRadius - mBorderHalf, mCornerRadius -
            mBorderHalf, Path.Direction.CW);
    mPathCornersBorder.close();
}
}
在布局中,将如下所示:

<com.example.yourpackage.RoundedLayout
    android:id="@+id/maplayout"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:layout_margin="20dp">

    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        tools:context="com.example.yourpackage.MapsMarkerActivity"/>
</com.example.yourpackage.RoundedLayout>
此布局可用于塑造任何视图


令人难以置信的是,谷歌无法为其android API制作合格(可用)的完整演示。

继@Nouman\u Hanif post之后,我最终找到了一个看起来相当不错的解决方案

map_rounded_corner_overlay.xml:

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
  <stroke android:width="1dp"
          android:color="@color/white" />
  <corners android:radius="<your_desired_view_corner_radius>"/>
</shape>

我的地图xml文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
  <fragment
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_margin="1dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
  <ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:src="@drawable/map_rounded_corner_overlay" />
</RelativeLayout>

我知道这是一篇老文章,但你可以试着用这样的卡片:

<android.support.v7.widget.CardView
    android:layout_width="300dp"
    android:layout_height="350dp"
    android:layout_gravity="center_horizontal|center_vertical"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:layout_marginTop="20dp"
    app:cardCornerRadius="12dp"
    app:cardElevation="12dp">

    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</android.support.v7.widget.CardView>

你放视图是什么意思?什么样的观点?我如何使中间部分透明?我只是做了一个非常粗糙的9补丁来告诉你这个想法,并不打算让你按原样使用;-)如果你做了一个像样的资产,它看起来会很好。另外,你需要将它作为一个补丁使用,重命名为filename.9.png。更多详情请参见此处,我尝试这样做,但我想知道是否有其他方法来处理此问题,您使用什么软件来创建这些9-patch?我从未了解如何使用此工具,是否有其他替代方法?什么是“parentView”?我尝试设置setClipToOutline(true);到实际的MapFragment,但这对我不起作用…parentView是MapFragment所在的视图。这是一个包含mapFragment的视图。对我来说不起作用。。。我用一个圆角背景的线性布局包装了地图片段,称为setClipToOutline(true);正如你所建议的。也许这与我正在使用的主题有关,主题是“theme.transparent.NoTitleBar.Fullscreen”…?这对我来说不起作用。我尝试了所有方法,但都没有。按照这里描述的解决方案进行操作后,您得到了什么结果?地图角与黑色圆形重叠:S地图超出了形状。@KinGPinG您确定按照正确的顺序放置形状吗?确实,今天您可以使用卡片来完成此操作。当问到这个问题时,卡片还不存在。回答得很好。
<android.support.v7.widget.CardView
    android:layout_width="300dp"
    android:layout_height="350dp"
    android:layout_gravity="center_horizontal|center_vertical"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:layout_marginTop="20dp"
    app:cardCornerRadius="12dp"
    app:cardElevation="12dp">

    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</android.support.v7.widget.CardView>