在我的
Android应用程序中,我有一个裁剪图像.所以,我将自定义视图编程为我的裁剪框.我可以移动裁剪框.但我的问题是如何拖动裁剪框的边框并更改它的宽度和高度.我该怎么做?
Attr类:
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类:
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_END_X,{Attr.CROP_Box_START_X,Attr.CROP_Box_END_Y},(Attr.CROP_Box_START_Y + Attr.CROP_Box_END_Y) / 2},(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_END_Y,Attr.CROP_Box_START_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][3],paint); } }
CropTestActivity类:
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)); } }
作物种类:
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:
<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>
调整大小之前:
调整大小后:
谢谢你的帮助.
解决方法
以下是解决方案,
修改了onCreate from Activity
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,imageView); relativeLayout = (RelativeLayout)findViewById(R.id.crop_test_layout); relativeLayout.addView(cropBox); }
public class CropBox extends View { private static final int CROP_Box_START_X = 5; private static final int CROP_Box_START_Y = 5; private static final int CROP_Box_END_X = 305; private static final int CROP_Box_END_Y = 105; private static final int DRAG_SQUARE = 75; public ImageView mImageView; boolean mIsFirstClick = false; private Paint paint = new Paint(); private Rect mRect; public CropBox(Context context,ImageView aBaseView) { super(context); mImageView = aBaseView; mRect = new Rect(CROP_Box_START_X,CROP_Box_START_Y,CROP_Box_END_X,CROP_Box_END_Y); setOnTouchListener(new Crop()); } public CropBox(Context context,attributeSet); } @Override public void onDraw(Canvas canvas) { paint.setStrokeWidth(2); paint.setColor(Color.CYAN); paint.setStyle(Paint.Style.STROKE); canvas.drawRect(mRect,paint); canvas.drawLine(mRect.right-DRAG_SQUARE,mRect.bottom-DRAG_SQUARE,mRect.right,mRect.right-DRAG_SQUARE,mRect.bottom,paint); } 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 PointF start = new PointF(); 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() <= mRect.right && event.getX() >=(mRect.right - DRAG_SQUARE)) && (event.getY() >= mRect.top && event.getY() >=(mRect.bottom - DRAG_SQUARE))){ mode = BORDER_DRAG; mIsFirstClick = false; } else if(mRect.contains((int)event.getX(),(int)event.getY())) { mode = Box_DRAG; if (mIsFirstClick){ mRect = new Rect(CROP_Box_START_X,CROP_Box_END_Y); mIsFirstClick = false; } else { mIsFirstClick = true; } } else{ mode = NONE; mIsFirstClick = true; } break; case MotionEvent.ACTION_UP: mode = NONE; break; case MotionEvent.ACTION_MOVE: mIsFirstClick = false; if(mode == Box_DRAG) { layoutParams.leftMargin = (int)event.getX() - (int)start.x + view.getLeft(); layoutParams.topMargin = (int)event.getY() - (int)start.y + view.getTop(); } else if(mode == BORDER_DRAG) { if (event.getX() > view.getLeft() && event.getY() > view.getTop()){ mRect.right = (int) event.getX(); mRect.bottom = (int) event.getY(); } } while(layoutParams.topMargin + 5 < mImageView.getTop()) layoutParams.topMargin++; while(layoutParams.leftMargin + mRect.right > mImageView.getRight()) layoutParams.leftMargin--; while(layoutParams.topMargin + mRect.bottom > mImageView.getBottom()) layoutParams.topMargin--; while(layoutParams.leftMargin + 5 < mImageView.getLeft()) layoutParams.leftMargin++; break; } view.setLayoutParams(layoutParams); invalidate(); return true; } } }
我想提一点.
>在CropBox中合并Attr和Crop
>无需从行创建矩形.你可以使用Rect.
>永远不要在Draw方法中初始化数组/对象
>添加了一项功能:如果在矩形上双击,则返回原始位置
>在imageview中限制rect可能会有一些障碍.我相信你可以修复那些……