Использование Android Google Maps v2 с пользовательским View или ImageView - PullRequest
0 голосов
/ 28 мая 2018

В основном я хочу иметь возможность использовать Google Maps v2 для рисования изображений RADAR на Карте, с хорошей производительностью, без мерцания или задержки растровых изображений.

В настоящее время я использую Карты v1 для выполненияэто, и это прекрасно работает, но Maps v2 не очень подходит для этого.

Можно подумать, что GroundOverlay или TileOverlay могут работать, но из того, что я читал от людей, которые пытались их использовать, вынеобходимо удалить () предыдущее изображение перед тем, как нарисовать следующее, или попытаться нарисовать растровое изображение как маркер или что-то еще.Он должен иметь хорошую производительность.

Поэтому я хотел бы иметь возможность использовать либо пользовательский вид, либо ImageView и использовать его onDraw () для рисования растрового изображения и отображения его на карте идвигайтесь вместе с ним.

Как:

<Outer Container>

    <fragment .. />

    <com.my.customView .. />

    or

    <ImageView .. />

</Outer Container>

Я искал повсюду в Интернете возможные примеры деталей, как сделать что-то подобное, с помощью Maps v2, но нашелничего.

Я использую несколько пользовательских видов в моем текущем приложении, так что я знаком с ними, и у меня есть сведения о растровых изображениях в Bounding Box, и я почти уверен, что могу использовать информацию Projection, чтобы помочьНарисуйте их.

Другая проблема заключается в том, как вызвать invalidate (), чтобы вызывать onDraw ().

Мне просто нужен пример кода, который показал бы, как использовать onDraw ()из какого-то объекта на основе View, который я мог бы попытаться увидеть, работает ли он, но тот, который не пытается использовать GroundOverlay, TileOverlay или Marker, я действительно оценил бы это!

Спасибо!

1 Ответ

0 голосов
/ 29 мая 2018

Если вы знакомы с , реализующим пользовательский вид , вы можете создать собственный вид, который расширяет класс MapView для полного контроля над рисованием на холсте вида.Но поскольку MapView расширяет FrameLayout, то есть ViewGroup, вы должны переопределить метод dispatchDraw(), а не onDraw() и реализовать в нем радиолокационное изображение.Примерно так:

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

и вам нужно вызывать его через invalidate() при каждом перемещении / увеличении / повороте карты.Для обнаружения движения / масштабирования / поворота карты вам понадобится GoogleMap (точнее GoogleMap.setOnCameraMoveListener() метод).Вы можете объявить GoogleMap объект внутри вашего пользовательского класса MapView и установить его через установщик, но лучше, если пользовательский класс MapView реализует интерфейс OnMapReadyCallback и получит его в onMapReady() обратном вызове.

Полный исходный код пользовательского представления на основе MapView (например, RadarMapView) может выглядеть следующим образом:

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

}

И вы можете использовать его в .xml файле:

<?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>

для MainActivity вроде:

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

}

и вы должны получить что-то вроде этого:

Radar MapView

Также вы можете нарисоватьРастровое изображение радара на пользовательском холсте с помощью метода canvas.drawBitmap().

А также вы можете разместить ImageView над MapView или MapFragment (например, в пределах 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>

и нарисуйте (или даже просто установите) радарные изображения на ImageView.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...