Android中如何在ImageView上绘制多个点位?
Let's break down the best way to implement this feature, since your current approach of creating a bitmap for each marker can get inefficient with multiple points. Here's a clean, maintainable solution:
1. Create a Data Class to Store Marker Details
First, define a simple class to hold each marker's position, icon, and text. This makes it easy to manage multiple markers:
public class MarkerPoint { public float x; public float y; public int iconResId; public String label; public MarkerPoint(float x, float y, int iconResId, String label) { this.x = x; this.y = y; this.iconResId = iconResId; this.label = label; } }
2. Build a Custom MarkerImageView
Instead of modifying bitmaps directly, create a custom ImageView that handles drawing markers dynamically. This is far more efficient for multiple points:
public class MarkerImageView extends ImageView { private List<MarkerPoint> markers = new ArrayList<>(); private Paint textPaint; public MarkerImageView(Context context) { super(context); init(); } public MarkerImageView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MarkerImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } // Initialize styling for text labels private void init() { textPaint = new Paint(); textPaint.setColor(Color.BLACK); textPaint.setTextSize(getResources().getDimension(R.dimen.text_size_medium)); textPaint.setAntiAlias(true); textPaint.setTextAlign(Paint.Align.CENTER); } // Add a new marker and trigger a redraw public void addMarker(MarkerPoint marker) { markers.add(marker); invalidate(); } // Clear all markers public void clearMarkers() { markers.clear(); invalidate(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // Draw the original image first for (MarkerPoint marker : markers) { // Draw the marker icon (centered on the x/y position) Drawable icon = getResources().getDrawable(marker.iconResId, getContext().getTheme()); if (icon != null) { int iconWidth = icon.getIntrinsicWidth(); int iconHeight = icon.getIntrinsicHeight(); int left = (int) (marker.x - iconWidth / 2); int top = (int) (marker.y - iconHeight / 2); icon.setBounds(left, top, left + iconWidth, top + iconHeight); icon.draw(canvas); } // Draw the label below the icon float textY = marker.y + (icon != null ? icon.getIntrinsicHeight() / 2 : 0) + textPaint.getTextSize(); canvas.drawText(marker.label, marker.x, textY, textPaint); } } }
3. Update Your Layout XML
Replace your regular ImageView with the custom view in your layout:
<com.your.package.name.MarkerImageView android:id="@+id/my_view" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/your_base_image" />
4. Add Markers in Your Activity
Now you can easily add markers to your view with just a few lines of code:
MarkerImageView myView = findViewById(R.id.my_view); // Add first marker MarkerPoint point1 = new MarkerPoint(150f, 200f, R.drawable.ic_launcher_background, "est"); myView.addMarker(point1); // Add second marker MarkerPoint point2 = new MarkerPoint(400f, 350f, R.drawable.ic_marker_icon, "Another Site"); myView.addMarker(point2);
Optional: Let Users Tap to Add Markers
If you want users to add markers by tapping the image, add this to your custom MarkerImageView:
@Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { // Get touch coordinates relative to the view float tapX = event.getX(); float tapY = event.getY(); // Add a marker at the tapped position addMarker(new MarkerPoint(tapX, tapY, R.drawable.ic_launcher_background, "New Point")); return true; } return super.onTouchEvent(event); }
Why This Approach is Better Than Your Original Code
Your initial method of creating a bitmap for each marker is inefficient because:
- It creates multiple bitmap copies, which uses unnecessary memory
- You have to manually manage merging bitmaps for each new marker
- The custom view approach dynamically draws markers only when needed, making it easier to update/remove points later
内容的提问来源于stack exchange,提问作者Aris_choice

