Goal:
Create an imageview that is drawable and zoomable,
That means when I press a button to on , it is drawable,
or when I turn o
I don't have complete solution. However I can suggest you to take a look at PhotoView which has zoom implementation and my custom CanvasView which I used in one of the old projects. It allows to draw using "pen" tool and type text on it. Text feature is unnecessary for you and probably was too specific for that part so you can skip it. Maybe it'll help you. It supports screen rotation which leads to new drawable dimensions and both text and curves are scaled in this case.
public class CanvasView extends View {
// -----------------------------------------------------------------------
//
// Constants
//
// -----------------------------------------------------------------------
@SuppressWarnings("unused")
private static final String TAG = CanvasView.class.getSimpleName();
private static final String EXTRA_SUPER_STATE = "EXTRA_SUPER_STATE";
private static final String EXTRA_COLOR = "EXTRA_COLOR";
private static final String EXTRA_ACTION = "EXTRA_ACTION";
private static final String EXTRA_MODIFICATIONS = "EXTRA_MODIFICATIONS";
private static final String EXTRA_CURRENT_MODIFICATION = "EXTRA_CURRENT_MODIFICATION";
// -----------------------------------------------------------------------
//
// Enums
//
// -----------------------------------------------------------------------
public static enum ACTION {
PEN, TEXT
};
// -----------------------------------------------------------------------
//
// Fields
//
// -----------------------------------------------------------------------
private ArrayList mItems;
private ACTION mAction;
private int mColor;
private float mDensityScale;
private DrawableItem mCurrentItem;
private EditText mEditText;
// -----------------------------------------------------------------------
//
// Constructor
//
// -----------------------------------------------------------------------
public CanvasView(Context context, AttributeSet attrs) {
super(context, attrs);
mItems = new ArrayList();
mAction = ACTION.PEN;
mDensityScale = getResources().getDisplayMetrics().density;
}
// -----------------------------------------------------------------------
//
// Setters
//
// -----------------------------------------------------------------------
public void setAction(ACTION action) {
if (mCurrentItem != null)
saveCurrentModification();
mAction = action;
invalidate();
}
public void setColor(int color) {
mColor = color;
hideKeyboard();
}
public void saveCurrentModification() {
if (mCurrentItem instanceof Curve || !((Text) mCurrentItem).isEmpty())
mItems.add(mCurrentItem);
mCurrentItem = null;
}
// -----------------------------------------------------------------------
//
// Methods
//
// -----------------------------------------------------------------------
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (DrawableItem item : mItems)
item.draw(canvas, getMeasuredWidth(), getMeasuredHeight());
if (mCurrentItem != null)
mCurrentItem.draw(canvas, getMeasuredWidth(), getMeasuredHeight());
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (mAction) {
case PEN:
onTouchPen(event);
break;
case TEXT:
onTouchText(event);
break;
default:
break;
}
return true;
}
private void onTouchPen(MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mCurrentItem = new Curve(mColor);
break;
case MotionEvent.ACTION_MOVE:
Curve currentItem = (Curve) mCurrentItem;
currentItem.addPoint(event.getX(), event.getY());
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
saveCurrentModification();
break;
default:
}
invalidate();
}
private void onTouchText(MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
if (mCurrentItem != null)
saveCurrentModification();
mCurrentItem = new Text(new PointF(event.getX(), event.getY()),
mDensityScale);
showKeyboard();
}
break;
default:
}
}
private void showKeyboard() {
mEditText.setVisibility(View.VISIBLE);
mEditText.setText("");
mEditText.requestFocus();
InputMethodManager inputMethodManager = (InputMethodManager) getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(mEditText,
InputMethodManager.SHOW_IMPLICIT);
}
private void hideKeyboard() {
mEditText.setVisibility(View.INVISIBLE);
InputMethodManager imm = (InputMethodManager) getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
}
@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putParcelable(EXTRA_SUPER_STATE, super.onSaveInstanceState());
bundle.putInt(EXTRA_COLOR, mColor);
bundle.putSerializable(EXTRA_ACTION, mAction);
bundle.putParcelableArrayList(EXTRA_MODIFICATIONS, mItems);
return bundle;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
setColor(bundle.getInt(EXTRA_COLOR));
setAction((ACTION) bundle.getSerializable(EXTRA_ACTION));
mItems = bundle.getParcelableArrayList(EXTRA_MODIFICATIONS);
super.onRestoreInstanceState(bundle
.getParcelable(EXTRA_SUPER_STATE));
return;
} else
super.onRestoreInstanceState(state);
}
public OnEditorActionListener getEditorActionListener() {
return mEditorActionListener;
}
public TextWatcher getTextWatcher() {
return mTextWatcher;
}
public void setTextProvider(EditText editText) {
mEditText = editText;
mEditText.setOnEditorActionListener(getEditorActionListener());
mEditText.addTextChangedListener(mTextWatcher);
}
public void clearSession() {
mItems.clear();
mCurrentItem = null;
hideKeyboard();
invalidate();
}
// -----------------------------------------------------------------------
//
// Listeners
//
// -----------------------------------------------------------------------
private OnEditorActionListener mEditorActionListener = new OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
saveCurrentModification();
hideKeyboard();
}
return false;
}
};
private TextWatcher mTextWatcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
if (mCurrentItem instanceof Text) {
((Text) mCurrentItem).setText(s.toString());
invalidate();
}
}
};
// -----------------------------------------------------------------------
//
// Inner classes
//
// -----------------------------------------------------------------------
public static interface OnStartTextInputListener {
public void onTextInputStarted(CanvasView view);
}
private static interface DrawableItem extends Parcelable {
public void draw(Canvas canvas, float viewWidth, float viewHeight);
}
private static class Curve implements DrawableItem {
// -----------------------------------------------------------------------
//
// Fields
//
// -----------------------------------------------------------------------
private ArrayList mPoints;
private int mColor;
private Paint mPaint;
// -----------------------------------------------------------------------
//
// Constructor
//
// -----------------------------------------------------------------------
public Curve(int color) {
mPoints = new ArrayList();
mColor = color;
mPaint = new Paint();
mPaint.setColor(mColor);
mPaint.setStrokeWidth(2);
}
private Curve(Parcel parcel) {
mColor = parcel.readInt();
parcel.readList(mPoints, PointF.class.getClassLoader());
}
// -----------------------------------------------------------------------
//
// Methods
//
// -----------------------------------------------------------------------
@Override
public void draw(Canvas canvas, float viewWidth, float viewHeight) {
for (int i = 1; i < mPoints.size(); ++i) {
PointF prev = mPoints.get(i - 1);
PointF current = mPoints.get(i);
canvas.drawLine(prev.x / viewWidth * canvas.getWidth(), prev.y
/ viewHeight * canvas.getHeight(), current.x
/ viewWidth * canvas.getWidth(), current.y / viewHeight
* canvas.getHeight(), mPaint);
}
}
public void addPoint(float x, float y) {
mPoints.add(new PointF(x, y));
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mColor);
dest.writeList(mPoints);
}
// -----------------------------------------------------------------------
//
// Inner classes
//
// -----------------------------------------------------------------------
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Curve createFromParcel(Parcel in) {
return new Curve(in);
}
public Curve[] newArray(int size) {
return new Curve[size];
}
};
}
private static class Text implements DrawableItem {
// -----------------------------------------------------------------------
//
// Constatns
//
// -----------------------------------------------------------------------
private static final int FONT_SIZE = 14;
private static final int PADDING = 4;
private static final int BORDER_WIDTH = 2;
private static final int BORDER_COLOR = Color.rgb(0, 0, 0);
private static final int BOX_COLOR = Color.rgb(255, 255, 255);
private static final int FONT_COLOR = Color.rgb(0, 0, 0);
// -----------------------------------------------------------------------
//
// Fields
//
// -----------------------------------------------------------------------
private Paint mBoxPaint;
private Paint mBorderPaint;
private Paint mTextPaint;
private float mDensityScale;
private PointF mPoint;
private String mTextString = "";
// -----------------------------------------------------------------------
//
// Constructor
//
// -----------------------------------------------------------------------
public Text(PointF point, float densityScale) {
mPoint = point;
mDensityScale = densityScale;
mBoxPaint = new Paint();
mBoxPaint.setStyle(Style.FILL);
mBoxPaint.setColor(BOX_COLOR);
mBorderPaint = new Paint();
mBorderPaint.setStyle(Style.STROKE);
mBorderPaint.setColor(BORDER_COLOR);
mBorderPaint.setStrokeWidth(getBorderWidth());
mTextPaint = new Paint();
mTextPaint.setTextSize(getFontSize());
mTextPaint.setAntiAlias(true);
mTextPaint.setTextAlign(Paint.Align.LEFT);
mTextPaint.setColor(FONT_COLOR);
}
// -----------------------------------------------------------------------
//
// Methods
//
// -----------------------------------------------------------------------
public void setText(String text) {
mTextString = text;
}
public boolean isEmpty() {
return Utils.isEmpty(mTextString);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
}
private float getFontSize() {
return FONT_SIZE * mDensityScale;
}
private float getPadding() {
return PADDING * mDensityScale;
}
private float getBorderWidth() {
return BORDER_WIDTH * mDensityScale;
}
private float getStringWidth(String string) {
Rect bounds = new Rect();
mTextPaint.getTextBounds(string, 0, string.length(), bounds);
return bounds.width();
}
@Override
public void draw(Canvas canvas, float viewWidth, float viewHeight) {
ArrayList labelList = new ArrayList();
String[] lines = mTextString.split(" ");
String prevLine = "";
float textHeight = (2 * getBorderWidth() + 2 * getPadding())
/ viewHeight * canvas.getHeight();
float textWidth = 0;
for (int i = 0; i < lines.length; ++i) {
String string = lines[i];
String newline = prevLine.concat(" " + string).trim();
float prevLineWidth = (getStringWidth(prevLine) + 2
* getBorderWidth() + 2 * getPadding())
/ viewWidth * canvas.getWidth();
float newLineWidth = (getStringWidth(newline) + 2
* getBorderWidth() + 2 * getPadding())
/ viewWidth * canvas.getWidth();
float availableWidth = canvas.getWidth() - mPoint.x / viewWidth
* canvas.getWidth() + 1;
if (newLineWidth > availableWidth) {
if (!Utils.isEmpty(prevLine)) {
labelList.add(prevLine);
textHeight += (getFontSize() + getPadding())
/ viewHeight * canvas.getHeight();
if (prevLineWidth >= textWidth)
textWidth = prevLineWidth;
}
prevLine = string;
if (i == lines.length - 1) {
prevLineWidth = (getStringWidth(prevLine) + 2
* getBorderWidth() + 2 * getPadding())
/ viewWidth * canvas.getWidth();
labelList.add(prevLine);
if (prevLineWidth > textWidth)
textWidth = prevLineWidth;
textHeight += getFontSize() / viewHeight
* canvas.getHeight();
}
} else if (i == lines.length - 1) {
labelList.add(newline);
if (newLineWidth > textWidth)
textWidth = newLineWidth;
textHeight += getFontSize() / viewHeight
* canvas.getHeight();
} else {
prevLine = newline;
}
}
textHeight = Math.min(textHeight, canvas.getHeight() - mPoint.y
/ viewHeight * canvas.getHeight());
textWidth = Math.min(textWidth, canvas.getWidth() - mPoint.x
/ viewWidth * canvas.getWidth());
if (isEmpty()) {
textWidth = (getPadding() * 2 + getBorderWidth() * 2)
/ viewWidth * canvas.getWidth();
}
canvas.drawRect(mPoint.x / viewWidth * canvas.getWidth(), mPoint.y
/ viewHeight * canvas.getHeight(), mPoint.x / viewWidth
* canvas.getWidth() + textWidth, mPoint.y / viewHeight
* canvas.getHeight() + textHeight, mBoxPaint);
mBorderPaint.setStrokeWidth(getBorderWidth() / viewWidth
* canvas.getWidth());
canvas.drawRect(mPoint.x / viewWidth * canvas.getWidth(), mPoint.y
/ viewHeight * canvas.getHeight(), mPoint.x / viewWidth
* canvas.getWidth() + textWidth, mPoint.y / viewHeight
* canvas.getHeight() + textHeight, mBorderPaint);
mBorderPaint.setStrokeWidth(getBorderWidth());
float offset = (getBorderWidth() + getPadding() + getFontSize())
/ viewWidth * canvas.getWidth();
mTextPaint.setTextSize(getFontSize() / viewHeight
* canvas.getHeight());
for (String string : labelList) {
canvas.drawText(string, (mPoint.x + getBorderWidth())
/ viewWidth * canvas.getWidth(), mPoint.y / viewHeight
* canvas.getHeight() + offset, mTextPaint);
offset += (getFontSize() + getPadding()) / viewHeight
* canvas.getHeight();
}
mTextPaint.setTextSize(getFontSize());
}
}