The following code shows how to Draw and resize.
Code revised from
Android Recipes:A Problem-Solution Approach
http://www.apress.com/9781430234135
ISBN13: 978-1-4302-3413-5
res\drawable\box.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@android:color/transparent"/> <stroke android:width="3dp" android:color="#F00" /> </shape>
res\layout\activity_main.xml
<LinearLayout 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:orientation="vertical" tools:context=".MainActivity" > <TextView android:id="@+id/textview" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:text="Android Recipes" /> <RadioGroup android:id="@+id/container_options" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:background="#CCC"> <RadioButton android:id="@+id/option_box" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Box" /> <RadioButton android:id="@+id/option_arrow" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="Arrow" /> </RadioGroup> </LinearLayout>
MainActivity.java
import android.app.Activity; import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.widget.RadioGroup; /*from w w w.ja v a 2s . c om*/ import java.util.ArrayList; public class MainActivity extends Activity implements View.OnTouchListener { private RadioGroup mOptions; private ArrayList<Drawable> mMarkers; private Drawable mTrackingMarker; private Point mTrackingPoint; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Receive touch events for the view we want to draw on findViewById(R.id.textview).setOnTouchListener(this); mOptions = (RadioGroup) findViewById(R.id.container_options); mMarkers = new ArrayList<Drawable>(); } /* * Touch events from the view we are monitoring * will be delivered here. */ @Override public boolean onTouch(View v, MotionEvent event) { switch (mOptions.getCheckedRadioButtonId()) { case R.id.option_box: handleEvent(R.id.option_box, v, event); break; case R.id.option_arrow: handleEvent(R.id.option_arrow, v, event); break; default: return false; } return true; } /* * Process touch events when user has selected to draw a box */ private void handleEvent(int optionId, View v, MotionEvent event) { int x = (int) event.getX(); int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Drawable current = markerAt(x, y); if (current == null) { //Add a new marker on a new touch switch(optionId) { case R.id.option_box: mTrackingMarker = addBox(v, x, y); mTrackingPoint = new Point(x, y); break; case R.id.option_arrow: mTrackingMarker = addFlag(v, x, y); break; } } else { //Remove the existing marker removeMarker(v, current); } break; case MotionEvent.ACTION_MOVE: //Update the current marker as we move if (mTrackingMarker != null) { switch(optionId) { case R.id.option_box: resizeBox(v, mTrackingMarker, mTrackingPoint, x, y); break; case R.id.option_arrow: offsetFlag(v, mTrackingMarker, x, y); break; } } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: //Clear state when gesture is over mTrackingMarker = null; mTrackingPoint = null; break; } } private Drawable addBox(View v, int x, int y) { Drawable box = getResources().getDrawable(R.drawable.box); Rect bounds = new Rect(x, y, x, y); box.setBounds(bounds); mMarkers.add(box); v.getOverlay().add(box); return box; } private void resizeBox(View v, Drawable target, Point trackingPoint, int x, int y) { Rect bounds = new Rect(target.getBounds()); if (x < trackingPoint.x) { bounds.left = x; } else { bounds.right = x; } if (y < trackingPoint.y) { bounds.top = y; } else { bounds.bottom = y; } //Update drawable bounds and redraw target.setBounds(bounds); v.invalidate(); } /* * Add a new flag marker at the given coordinate */ private Drawable addFlag(View v, int x, int y) { //Make a new marker drawable Drawable marker = getResources().getDrawable(R.drawable.flag_arrow); //Create bounds to match image size Rect bounds = new Rect(0, 0, marker.getIntrinsicWidth(), marker.getIntrinsicHeight()); //Center marker bottom around coordinate bounds.offset(x - (bounds.width() /2), y - bounds.height()); marker.setBounds(bounds); //Add to the overlay mMarkers.add(marker); v.getOverlay().add(marker); return marker; } /* * Update the position of an existing flag marker */ private void offsetFlag(View v, Drawable marker, int x, int y) { Rect bounds = new Rect(marker.getBounds()); //Move drawable bounds to the next align with the new coordinate bounds.offset(x - bounds.left - (bounds.width() / 2), y - bounds.top - bounds.height()); //Update and redraw marker.setBounds(bounds); v.invalidate(); } /* * Remove the requested marker item */ private void removeMarker(View v, Drawable marker) { mMarkers.remove(marker); v.getOverlay().remove(marker); } /* * Find the first marker that contains the requested * coordinate, if one exists. */ private Drawable markerAt(int x, int y) { //Return the first marker found containing the given point for (Drawable marker : mMarkers) { if (marker.getBounds().contains(x, y)) { return marker; } } return null; } }