Java 在Android中更改自定义视图宽度和高度

Java 在Android中更改自定义视图宽度和高度,java,android,android-layout,crop,android-view,Java,Android,Android Layout,Crop,Android View,在我的android应用程序中,我有一个裁剪图像。因此,我编写了一个自定义视图作为裁剪框。我可以移动收割机。但我的问题是如何拖动裁剪框的边框并更改其宽度和高度。我怎么做 属性类: 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_

在我的android应用程序中,我有一个裁剪图像。因此,我编写了一个自定义视图作为裁剪框。我可以移动收割机。但我的问题是如何拖动裁剪框的边框并更改其宽度和高度。我怎么做

属性类:

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_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);
    }

}
作物类别:

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;
    }

}
public类Crop实现了ontouch侦听器{
私有静态final int NONE=0;
专用静态最终整型框_DRAG=1;
私有静态最终整型边界_阻力=2;
私有int模式=无;
私有浮动cropBoxStartX=Attr.CROP_BOX_START_X;
私有浮动cropBoxStartY=Attr.CROP_BOX_START_Y;
私有浮动CropBox=Attr.CROP\u BOX\u END\u X;
私有浮动cropBoxEndY=Attr.CROP\u BOX\u END\Y;
私人影像视图;
private PointF start=new PointF();
公共作物(图像视图){
this.imageView=imageView;
}
公共布尔onTouch(视图、运动事件){
RelativeLayout.LayoutParams LayoutParams=(RelativeLayout.LayoutParams)视图。getLayoutParams();
开关(event.getAction()&MotionEvent.ACTION\u掩码){
case MotionEvent.ACTION\u DOWN:
set(event.getX(),event.getY());
if(event.getX()>cropBoxStartX&&event.getX()cropBoxStartY&&event.getY()imageView.getRight()
layoutParams.leftMargin--;
while(layoutParams.topMargin+(cropBoxEndY-cropBoxStartY+5)>imageView.getBottom()
layoutParams.topMargin--;
while(layoutParams.leftMargin+5
布局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活动

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);
}
修改的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 attributeSet) {
        super(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.bottom-DRAG_SQUARE, paint);

        canvas.drawLine(mRect.right-DRAG_SQUARE, mRect.bottom-DRAG_SQUARE, 
                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_START_Y, 
                                    CROP_BOX_END_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扩展视图{
专用静态最终整数裁剪框开始X=5;
专用静态最终整数裁剪框开始Y=5;
专用静态最终整数裁剪框结束X=305;
专用静态最终整数裁剪框结束Y=105;
专用静态最终整数拖动平方=75;
公共图像视图mImageView;
布尔值mIsFirstClick=false;
私人油漆=新油漆();
私人直肠;
公共CropBox(上下文,ImageView-aBaseView){
超级(上下文);
mImageView=aBaseView;
mRect=新矩形(裁剪框开始、裁剪框开始、裁剪框结束、裁剪框结束);
setOnTouchListener(新裁剪());
}
公共CropBox(上下文、属性集、属性集){
super(上下文、属性集);
}
@凌驾
公共空白onDraw(画布){
油漆。设置行程宽度(2);
油漆.setColor(颜色为青色);
绘制.设置样式(绘制.样式.笔划);
画布.drawRect(mRect,油漆);
画布.抽绳(mRect.right-DRAG\u SQUARE,mRect.bottom-DRAG\u SQUARE,
mRect.right,mRect.bottom-DRAG_SQUARE,paint);
画布.抽绳(mRect.right-DRAG\u SQUARE,mRect.bottom-DRAG\u SQUARE,
mRect.右拖拽(方形,mRect.底部,油漆);
}
类Crop实现OnTouchListener{
私有静态final int NONE=0;
专用静态最终整型框_DRAG=1;
私有静态最终整型边界_阻力=2;
私有int模式=无;
private PointF start=new PointF();
公共布尔onTouch(视图、运动事件){
RelativeLayout.LayoutParams LayoutParams=(RelativeLayout.LayoutParams)视图。getLayoutParams();
开关(event.getAction()&MotionEvent.ACTION\u掩码){
case MotionEvent.ACTION\u DOWN:
set(event.getX(),event.getY());
if((event.getX()=(mRect.right-拖动_SQUARE))
&&(event.getY()>=mRect.top&&event.getY()>=(mRect.bottom-DRAG_SQUARE))){
模式=边界拖动;
mIsFirstClick=false;
}
else if(mRect.contains((int)event.getX(),(int)event.getY()){
模式=长方体拖动;
如果(单击错误){
mRect=新矩形(裁剪框开始,裁剪框开始,
裁剪盒(末端)X、裁剪盒(末端)Y);
mIsFirstClick=false;
}否则{
mIsFirstClick=true;
}
}
否则{
模式=无;
mIsFirstClick=true;
}
打破
case MotionEvent.ACTION\u UP:
模式=无;
打破
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 attributeSet) {
        super(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.bottom-DRAG_SQUARE, paint);

        canvas.drawLine(mRect.right-DRAG_SQUARE, mRect.bottom-DRAG_SQUARE, 
                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_START_Y, 
                                    CROP_BOX_END_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;
        }
    }
}