Смотри в сторону использования ImageView. Создаешь собственный класс, родителем которого является ImageView. При создании объекта или вызова иного метода накладываешь рисунок (фон) карты. Подключаешь методы onTouchEvent (обработчик нажатия на элемент, к пример, для клика на нарисованный маркер или объект), onDraw (отрисовка элементов через Canvas, в моём случае на карте рисую метки и маршрут) и другие.
Грубо говоря, ты соберешь свой собственный ImageView, который будет выполнять все нужные действия.
Класс у меня большой, кину несколько моментов.
Конструктор
public DrawView(Context context, View parent, String appName) {
super(context);
navigator = MainActivity.university.getNavigator();
setHorizontalScrollBarEnabled(true);
setVerticalScrollBarEnabled(true);
markers = new naviMarkers();
gestureDetector = new GestureDetector(context, new MyGestureListener());
scaleGestureDetector = new ScaleGestureDetector(context, new MyScaleGestureListener());
scroller = new Scroller(context);
final TypedArray a = (TypedArray) context.obtainStyledAttributes(R.styleable.View);
a.recycle();
CheckDisplay();
p = new Paint();
loadImage(corp, stage);
AdaptToScreen(false, ScreenWidth, ScreenHeight);
}
Отрисовка маркеров и маршрутов:
@Override
protected void onDraw(Canvas canvas) {
canvas.drawARGB(0, 0, 0, 0);
markers.markersRefresh(30, 30);
Rect rect = new Rect(0, 0, getScaledWidth(), getScaledHeight());
canvas.drawBitmap(image, null, rect, p);
p.setStyle(Paint.Style.FILL);
p.setAntiAlias(true);
//p.setColor(Color.RED);
float minWidth = 0;
if (isCampus)
minWidth = (float) (getWidth() * 0.065);
else
minWidth = (float) (getWidth() * 0.059);
float kWidth = (int) (minWidth * (scaleFactor));
if (kWidth < minWidth)
kWidth = (int) minWidth;
MarkerWidth = kWidth;
MarkerHeight = kWidth;
markers.markersRefresh(MarkerWidth, MarkerHeight);
naviCampus nCampus = navigator.getCampus();
if (isCampus) {
for(int i = 1; i <= nCampus.getCount(); i++) {
naviCorp corp = nCampus.getCorpus(i);
if (corp != null) {
Bitmap marker = markers.getMarker(naviMarkers.ID_MARKER_CAMPUS);
if (marker != null)
canvas.drawBitmap(marker, corp.getX() * scaleFactor - marker.getWidth() / 2,
corp.getY() * scaleFactor - marker.getHeight() / 2, p);
}
}
}
else {
ArrayList<naviAuditor> auditorlist = nCampus.getCorpus(corp).getAuditors(stage);
// Рисуем точки аудиторий
if ((isAuditor) && (scaleFactor >= 0.7)) {
for (int i = 0; i < auditorlist.size(); i++) {
naviAuditor auditor = auditorlist.get(i);
Bitmap marker = markers.getMarker(naviMarkers.ID_MARKER_AUDITOR);
if (marker != null)
canvas.drawBitmap(marker, auditor.getX() * scaleFactor - marker.getWidth() / 2,
auditor.getY() * scaleFactor - marker.getHeight() / 2, p);
//canvas.drawCircle(auditor.getX() * scaleFactor, auditor.getY() * scaleFactor, 20, p);
}
}
// Рисуем лестницы
if ((isSteps) && (steps != null)) {
for (int i = 0; i < steps.size(); i++) {
Bitmap marker = markers.getMarker(naviMarkers.ID_MARKER_STEPS);
if (marker != null)
canvas.drawBitmap(marker, steps.get(i).getX() * scaleFactor - marker.getWidth() / 2,
steps.get(i).getY() * scaleFactor - marker.getHeight() / 2, p);
}
}
// Отображаем маршрут
if (points != null) {
p.setStrokeWidth(9 * getResources().getDisplayMetrics().density * scaleFactor);
p.setColor(Color.RED);
p.setStrokeMiter(0);
naviGraps gr = navigator.getGraps();
Point pBeginNavi = null, pEndNavi = null;
ArrayList<Point> pGraphicsSteps = new ArrayList<>(); // begin-..STEPS..-end
Path path = new Path();
boolean first_point = false;
for(int i = 0; i < points.FItems.size() - 1; i++) {
int bPoint = points.FItems.get(i);
int ePoint = points.FItems.get(i + 1);
if ((gr.Points.get(bPoint).getStage() == stage) &&
(gr.Points.get(bPoint).getStage() == gr.Points.get(ePoint).getStage())) {
float X1 = gr.Points.get(bPoint).getX() * scaleFactor;
float Y1 = gr.Points.get(bPoint).getY() * scaleFactor;
float X2 = gr.Points.get(ePoint).getX() * scaleFactor;
float Y2 = gr.Points.get(ePoint).getY() * scaleFactor;
if (!first_point) {
path.moveTo(X1, Y1);
first_point = true;
}
path.lineTo(X2, Y2);
if (i == 0)
pBeginNavi = new Point((int)X1, (int)Y1);
else if (i == points.FItems.size() - 2)
pEndNavi = new Point((int)X2, (int)Y2);
}
}
p.setStyle(Paint.Style.STROKE);
canvas.drawPath(path, p);
if (pBeginNavi != null) {
Bitmap marker = markers.getMarker(naviMarkers.ID_MARKER_POINT_A);
if (marker != null)
canvas.drawBitmap(marker, pBeginNavi.x - marker.getWidth() / 2, pBeginNavi.y - marker.getHeight() / 2, p);
}
if (pEndNavi != null) {
Bitmap marker = markers.getMarker(naviMarkers.ID_MARKER_POINT_B);
if (marker != null)
canvas.drawBitmap(marker, pEndNavi.x - marker.getWidth() / 2, pEndNavi.y - marker.getHeight() / 2, p);
}
}
if ((isSearch) && (activeAuditory != null)) {
int findInd = -1;
for (int i = 0; (i < auditorlist.size()) && (findInd == -1); i++)
if (activeAuditory.equals(auditorlist.get(i).getAuditor()))
findInd = i;
if (findInd != -1) {
naviAuditor auditor = auditorlist.get(findInd);
Bitmap marker = markers.getMarker(naviMarkers.ID_MARKER_AUDITOR);
if (marker != null)
canvas.drawBitmap(marker, auditor.getX() * scaleFactor - marker.getWidth() / 2,
auditor.getY() * scaleFactor - marker.getHeight() / 2, p);
}
}
}
}
Обработка нажатий на карту
@Override
public boolean onTouchEvent(MotionEvent event)
{
if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
if (!scroller.isFinished()) scroller.abortAnimation();
}
scaleGestureDetector.onTouchEvent(event);
if (gestureDetector.onTouchEvent(event)) {
return true;
}
if ((event.getPointerCount() == 1) && ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP))
{
int newScrollX = getScrollX();
if (getScaledWidth() < getWidth()) newScrollX = -(getWidth() - getScaledWidth()) / 2;
else if (getScrollX() < 0) newScrollX = 0;
else if (getScrollX() > getScaledWidth() - getWidth()) newScrollX = getScaledWidth() - getWidth();
int newScrollY = getScrollY();
if (getScaledHeight() < getHeight()) newScrollY = -(getHeight() - getScaledHeight()) / 2;
else if (getScrollY() < 0) newScrollY = 0;
else if (getScrollY() > getScaledHeight() - getHeight()) newScrollY = getScaledHeight() - getHeight();
if ((newScrollX != getScrollX()) || (newScrollY != getScrollY()))
{
scroller.startScroll(getScrollX(), getScrollY(), newScrollX - getScrollX(), newScrollY - getScrollY());
awakenScrollBars(scroller.getDuration());
computeScroll();
return true;
}
}
if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE) {
return true;
}
if ((event.getPointerCount() == 1) && (event.getAction() == MotionEvent.ACTION_UP) && (event.getAction() != MotionEvent.ACTION_MOVE)) {
clickOnMarker(getScrollX() + (int) event.getX(), getScrollY() + (int) event.getY(), event);
return true;
}
return true;
}