Obecnie rozwijam system śledzenia, aby wykreślić trajektorię ruchu użytkownika wewnątrz pomieszczenia lub co innego.Jak narysować mały obraz znacznika i dalej odświeżać jego pozycję na moim obrazie mapy CUSTOM? - Android
Teraz udało mi się zaimportować mapę do aplikacji, a mapę można powiększać i przenosić. Następnym krokiem jest umieszczenie znacznika, który wskaże lokalizację użytkownika na mapie i przesunie znacznik wokół OVER na mapie. (jak unoszący się na mapie)
Przeczytałem go gdzieś i wydaje mi się, że można to zrobić za pomocą MyLocationOverlay
, ale większość przykładów online to zastosowanie go do google map
. Jednak w moim przypadku moja mapa nie jest google map
, jest to moja mapa OWN. (Mapa może być mapą mojego pokoju lub nawet mapą, którą sam rysuję!)
Wykonałem algorytm śledzenia, tj. Wiem, gdzie umieścić mój obraz znacznika.
Tak więc pozostaje tylko pytanie, jak przedstawić obraz znacznika na obrazie mapy.
W szczegółach, mam własny pogląd, MapView zdefiniowane w następujący sposób:
package com.example.drsystem;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
public class MapView extends View {
private static final int INVALID_POINTER_ID = -1;
private Drawable mImage;
private float mPosX;
private float mPosY;
private float mLastTouchX;
private float mLastTouchY;
private int mActivePointerId = INVALID_POINTER_ID;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
public MapView(Context context) {
this(context, null, 0);
mImage = getResources().getDrawable(R.drawable.lv12n);
mImage.setBounds(0, 0, mImage.getIntrinsicWidth(), mImage.getIntrinsicHeight());
}
// called when XML tries to inflate this View
public MapView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
mImage = getResources().getDrawable(R.drawable.lv12n);
mImage.setBounds(0, 0, mImage.getIntrinsicWidth(), mImage.getIntrinsicHeight());
}
public MapView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(ev);
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = ev.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE: {
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);
// Only move if the ScaleGestureDetector isn't processing a gesture.
if (!mScaleDetector.isInProgress()) {
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
invalidate();
}
mLastTouchX = x;
mLastTouchY = y;
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
}
break;
}
}
return true;
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
Log.d("MapView", "X: " + mPosX + " Y: " + mPosY);
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
mImage.draw(canvas);
canvas.restore();
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
// Don't let the object get too small or too large.
mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f));
invalidate();
return true;
}
}
}
Maksymalnie tutaj, mapa jest z powodzeniem wprowadzane do aplikacji, i to zarówno ruchomy i zoomable.
A potem wstawić ten widok niestandardowy do pliku XML układu następująco:
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MapView" >
<com.example.drsystem.MapView
android:id="@+id/mapView1"
android:layout_width="fill_parent"
android:layout_height="400dp"
android:layout_above="@+id/button2"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" />
...
</RelativeLayout>
Na podstawie wszystkich tych informacji, w jaki sposób mogę narysować kropkę i stale aktualizować swoją pozycję na mojej mapie?
Aktualizacja:
Pytanie jest po prostu o oddanie kolejny mały obraz na szczycie widoku niestandardowym i przesuwając go dookoła.
ja również dołączyć tutaj zrzut ekranu w celach:
Obszar nad przyciskami i TextView Is My MapView
Sprawdź źródło Redpin. Dokładnie to robi – Reno