将 Android Google Maps v2 与自定义 View 或 ImageView 结合使用 [英] Using Android Google Maps v2 with custom View or ImageView

查看:18
本文介绍了将 Android Google Maps v2 与自定义 View 或 ImageView 结合使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上我希望能够使用 Google Maps v2在地图上绘制雷达图像,具有良好的位图图像无闪烁或延迟.

我目前正在使用 Maps v1 来执行此操作,并且效果很好,但是 Maps v2不太适合这样做.

你会认为 GroundOverlay 或 TileOverlay 可能有用,但从我从尝试使用它们的人那里读到的,在绘制下一张图像之前,您必须删除()上一张图像,或者尝试将位图图像绘制为标记或者其他的东西.它必须具有良好的性能.

所以我希望能够使用自定义视图或 ImageView并使用它的 onDraw() 绘制位图并使其在地图上可见并随之移动.

喜欢:

<外部容器><片段../><com.my.customView ../>或者<图像视图../></外部容器>

我在网上到处找可能的例子有关如何使用 Maps v2 执行此类操作的详细信息,但已发现什么都没有.

我在当前的应用程序中使用了几个自定义视图所以我对这些很熟悉,而且我有位图的边界框详细信息我很确定我可以使用投影信息帮助他们画画.

另一个问题是如何调用 invalidate() 以便onDraw() 将被调用.

我只需要一些示例代码来展示如何使用 onDraw()从某种基于视图的对象中,我可以尝试查看它是否有效,但一个不尝试使用GroundOverlay"、TileOverlay"或Marker"的,我真的很感激!

谢谢!

解决方案

如果你熟悉

您也可以通过 canvas 在自定义视图画布上绘制位图雷达图像.drawBitmap() 方法.

您也可以将 ImageView 放在 MapViewMapFragment 上(例如在 RelativeLayout 内)

<片段android:id="@+id/地图"android:layout_width="match_parent"android:layout_height="match_parent"class="com.google.android.gms.maps.MapFragment"/><图像视图android:layout_width="wrap_content"android:layout_height="wrap_content"机器人:layout_centerInParent =真"android:src="@drawable/雷达"/></RelativeLayout>

并在 ImageView 上绘制(甚至只是设置)雷达图像.

Basically I want to be able to use Google Maps v2 to draw RADAR images over the Map, with good performance and no flickering or delay of the Bitmap images.

I'm currently using Maps v1 to do this, and it works great, but Maps v2 is not well suited to do that.

You would think that GroundOverlay or TileOverlay might work, but from what I've read from people who have tried using them, you have to remove() the previous image before you draw the next one, or do some kludge of trying to draw the Bitmap image as a Marker or something. It has to have good performance.

So I'd like to be able to use either a custom View, or an ImageView and use it's onDraw() to draw the Bitmap and have it be visible on the Map and move with it.

Like:

<Outer Container>

    <fragment .. />

    <com.my.customView .. />

    or

    <ImageView .. />

</Outer Container>

I've looked everywhere over the web for possible examples of the details of how to do something like that, with Maps v2, but have found nothing.

I use several custom Views in my current application so I'm familiar with those, and I have the Bounding Box details of the Bitmaps and I'm pretty sure that I can use the Projection information to help draw them.

Another issue is how to call invalidate() so that the onDraw() will be called.

I just need some example code that would show how to use the onDraw() from some kind of a View based object that I could try to see if it works, but one that doesn't try to use 'GroundOverlay', 'TileOverlay' or "Marker', I'd really appreciate it!

Thanks!

解决方案

If you familiar with implementing custom view, you can create custom view which extends MapView class for full control of drawing on view canvas. But because MapView extends FrameLayout which is ViewGroup, you should override dispatchDraw() method, not onDraw() and implement within it radar drawing. Something like that:

@Override
public void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(canvas);
    canvas.save();
    drawRadarOverTheMap(canvas);
    canvas.restore();
}

and you need to call it via invalidate() on every map move/zoom/rotate. For detect map move/zoom/rotate you need GoogleMap (exactly GoogleMap.setOnCameraMoveListener() method). You can declare GoogleMap object inside your custom MapView class and set it via setter, but better if custom MapView class will implement OnMapReadyCallback interface and get it in onMapReady() callback.

Full source code of MapView-based custom view (e.g. RadarMapView) can be like that:

public class RadarMapView extends MapView implements OnMapReadyCallback {

    private OnMapReadyCallback mMapReadyCallback;
    private GoogleMap mGoogleMap;
    private Marker mMarker;
    private Paint mPaintRadar;

    public RadarMapView(@NonNull Context context) {
        super(context);
        init();
    }

    public RadarMapView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public RadarMapView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public RadarMapView(@NonNull Context context, @Nullable GoogleMapOptions options) {
        super(context, options);
        init();
    }

    @Override
    public void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        canvas.save();
        drawRadarOverTheMap(canvas);
        canvas.restore();
    }

    private void drawRadarOverTheMap(Canvas canvas) {
        if (mGoogleMap == null) {
            return;
        }

        final float centerX = getX() + getWidth() / 2;
        final float centerY = getY() + getHeight() / 2;

        canvas.drawCircle(centerX, centerY, 150, mPaintRadar);
        canvas.drawCircle(centerX, centerY, 300, mPaintRadar);
        canvas.drawCircle(centerX, centerY, 450, mPaintRadar);
    }

    private void init() {
        setWillNotDraw(false);

        mPaintRadar = new Paint();
        mPaintRadar.setColor(Color.GREEN);
        mPaintRadar.setStyle(Paint.Style.STROKE);
        mPaintRadar.setStrokeWidth(10);
    }

    @Override
    public void getMapAsync(OnMapReadyCallback callback) {
        mMapReadyCallback = callback;
        super.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;
        mGoogleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
            @Override
            public void onCameraMove() {
                invalidate();
            }
        });
        if (mMapReadyCallback != null) {
            mMapReadyCallback.onMapReady(googleMap);
        }
    }

}

And you can use it in .xml file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="{your_package_name}.MainActivity">

    <{your_package_name}.RadarMapView
        android:id="@+id/mapview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        />
</RelativeLayout>

for MainActivity like:

public class MainActivity extends AppCompatActivity {

    private static final String MAP_VIEW_BUNDLE_KEY = "MapViewBundleKey";

    private GoogleMap mGoogleMap;
    private RadarMapView mMapView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Bundle mapViewBundle = null;
        if (savedInstanceState != null) {
            mapViewBundle = savedInstanceState.getBundle(MAP_VIEW_BUNDLE_KEY);
        }

        mMapView = (RadarMapView) findViewById(R.id.mapview);
        mMapView.onCreate(mapViewBundle);
        mMapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap googleMap) {
                mGoogleMap = googleMap;
            }
        });

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        Bundle mapViewBundle = outState.getBundle(MAP_VIEW_BUNDLE_KEY);
        if (mapViewBundle == null) {
            mapViewBundle = new Bundle();
            outState.putBundle(MAP_VIEW_BUNDLE_KEY, mapViewBundle);
        }

        mMapView.onSaveInstanceState(mapViewBundle);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    protected void onStart() {
        super.onStart();
        mMapView.onStart();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mMapView.onStop();
    }
    @Override
    protected void onPause() {
        mMapView.onPause();
        super.onPause();
    }
    @Override
    protected void onDestroy() {
        mMapView.onDestroy();
        super.onDestroy();
    }
    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mMapView.onLowMemory();
    }

}

and you should get something like that:

Also you can draw bitmap Radar image on custom view canvas via canvas.drawBitmap() method.

And also you can place ImageView over MapView or MapFragment (e.g. within RelativeLayout)

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

    <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.MapFragment"
    />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/radar"
    />

</RelativeLayout>

and draw (or even just set) Radar images on ImageView.

这篇关于将 Android Google Maps v2 与自定义 View 或 ImageView 结合使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆