In my Android app, I have a crop image. So, I am programming a custom view as a crop field. I can move the crop frame. But my problem is how can I drag the border of the crop field and change its width and height. How can i do this?
Attr Class:
public class Attr { public static final float CROP_BOX_START_X = 5; public static final float CROP_BOX_START_Y = 5; public static final float CROP_BOX_END_X = 305; public static final float CROP_BOX_END_Y = 105; }
CropBox Class:
public class CropBox extends View { private Paint paint = new Paint(); public CropBox(Context context) { super(context); } public CropBox(Context context, AttributeSet attributeSet) { super(context, attributeSet); } @Override public void onDraw(Canvas canvas) { float[][] circleXY = { {Attr.CROP_BOX_START_X, Attr.CROP_BOX_START_Y}, {(Attr.CROP_BOX_START_X + Attr.CROP_BOX_END_X) / 2, Attr.CROP_BOX_START_Y}, {Attr.CROP_BOX_END_X, Attr.CROP_BOX_START_Y}, {Attr.CROP_BOX_START_X, Attr.CROP_BOX_END_Y}, {(Attr.CROP_BOX_START_X + Attr.CROP_BOX_END_X) / 2, Attr.CROP_BOX_END_Y}, {Attr.CROP_BOX_END_X, Attr.CROP_BOX_END_Y}, {Attr.CROP_BOX_START_X, (Attr.CROP_BOX_START_Y + Attr.CROP_BOX_END_Y) / 2}, {Attr.CROP_BOX_END_X, (Attr.CROP_BOX_START_Y + Attr.CROP_BOX_END_Y) / 2} }; float[][] lineXY = { {Attr.CROP_BOX_START_X, Attr.CROP_BOX_START_Y, Attr.CROP_BOX_END_X, Attr.CROP_BOX_START_Y}, {Attr.CROP_BOX_START_X, Attr.CROP_BOX_END_Y, Attr.CROP_BOX_END_X, Attr.CROP_BOX_END_Y}, {Attr.CROP_BOX_START_X, Attr.CROP_BOX_START_Y, Attr.CROP_BOX_START_X, Attr.CROP_BOX_END_Y}, {Attr.CROP_BOX_END_X, Attr.CROP_BOX_START_Y, Attr.CROP_BOX_END_X, Attr.CROP_BOX_END_Y} }; paint.setColor(Color.CYAN); paint.setStrokeWidth(1); for(int i = 0 ; i < circleXY.length ; i++) canvas.drawCircle(circleXY[i][0], circleXY[i][1], 5, paint); paint.setStrokeWidth(2); for(int i = 0 ; i < lineXY.length ; i++) canvas.drawLine(lineXY[i][0], lineXY[i][2], lineXY[i][2], lineXY[i][3], paint); } }
CropTestActivity Class:
public class CropTestActivity extends Activity { private ImageView imageView; private CropBox cropBox; private RelativeLayout relativeLayout; private RelativeLayout.LayoutParams layoutParams; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.crop_test_layout); imageView = (ImageView)findViewById(R.id.android_image); cropBox = new CropBox(this); relativeLayout = (RelativeLayout)findViewById(R.id.crop_test_layout); layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT); imageView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { public void onGlobalLayout() { imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this); layoutParams.leftMargin = imageView.getWidth() / 2 - (int)((Attr.CROP_BOX_START_X + Attr.CROP_BOX_END_X) / 2) + imageView.getLeft(); layoutParams.topMargin = imageView.getHeight() / 2 - (int)((Attr.CROP_BOX_START_Y + Attr.CROP_BOX_END_Y) / 2) + imageView.getTop(); } }); relativeLayout.addView(cropBox, layoutParams); cropBox.setOnTouchListener(new Crop(imageView)); } }
Harvest Class:
public class Crop implements OnTouchListener { private static final int NONE = 0; private static final int BOX_DRAG = 1; private static final int BORDER_DRAG = 2; private int mode = NONE; private float cropBoxStartX = Attr.CROP_BOX_START_X; private float cropBoxStartY = Attr.CROP_BOX_START_Y; private float cropBoxEndX = Attr.CROP_BOX_END_X; private float cropBoxEndY = Attr.CROP_BOX_END_Y; private ImageView imageView; private PointF start = new PointF(); public Crop(ImageView imageView) { this.imageView = imageView; } public boolean onTouch(View view, MotionEvent event) { RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)view.getLayoutParams(); switch(event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: start.set(event.getX(), event.getY()); if(event.getX() > cropBoxStartX && event.getX() < cropBoxEndX && event.getY() > cropBoxStartY && event.getY() < cropBoxEndY) mode = BOX_DRAG; else if(event.getX() == cropBoxStartX || event.getX() == cropBoxEndX || event.getY() == cropBoxStartY || event.getY() == cropBoxEndY) mode = BORDER_DRAG; else mode = NONE; break; case MotionEvent.ACTION_UP: mode = NONE; break; case MotionEvent.ACTION_MOVE: if(mode == BOX_DRAG) { layoutParams.leftMargin = (int)event.getX() - (int)start.x + view.getLeft(); layoutParams.topMargin = (int)event.getY() - (int)start.y + view.getTop(); while(layoutParams.topMargin + 5 < imageView.getTop()) layoutParams.topMargin++; while(layoutParams.leftMargin + (cropBoxEndX - cropBoxStartX + 5) > imageView.getRight()) layoutParams.leftMargin--; while(layoutParams.topMargin + (cropBoxEndY - cropBoxStartY + 5) > imageView.getBottom()) layoutParams.topMargin--; while(layoutParams.leftMargin + 5 < imageView.getLeft()) layoutParams.leftMargin++; } else if(mode == BORDER_DRAG) { } break; } view.setLayoutParams(layoutParams); return true; } }
XML format:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/crop_test_layout" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ImageView android:id="@+id/android_image" android:src="@drawable/android" android:layout_width="fill_parent" android:layout_height="300dp" android:layout_marginTop="10dp" android:layout_marginRight="10dp" android:layout_marginBottom="10dp" android:layout_marginLeft="10dp" android:layout_gravity="center" android:scaleType="fitXY" android:contentDescription="@string/android_image_description" > </ImageView> </RelativeLayout>
Before resizing:

After resizing:

Thank you for your help.