Draw and resize

Description

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

Example

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;
/*  w  w  w .  ja v a2  s  . 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;
    }    
}
Draw and resize




















Home »
  Android »
    Android UI »




UI Basics
Action Bar
Animation
Button
Canvas
CheckBox
Clock Date Picker
Dialog
EditText
Event
Fragment
Gesture
GridView
ImageView
Layout
ListView
Map
Menu
Model
OpenGL
ProgressBar
RadioButton
Spinner
Tab
TextView
Thread
Toast
Video
View
WebView