編輯:關於Android編程
本文所需要實現的就是這樣一種有逼格的效果:
右上角加了個圖片框,按下確定可以裁剪正方形區域裡的圖片並顯示在右上角。
實現思路:
1:首先需要自定義一個ZoomImageView來顯示我們需要的圖片,這個View需要讓圖片能夠以合適的位置展現在當前布局的圖片展示區域內(合適的位置值的是:如果圖片長度大於屏幕,則壓縮圖片長度至屏幕寬度,高度等比壓縮並居中顯示,如果圖片高度大於屏幕,則壓縮圖片高度至屏幕高度,長度等比壓縮並居中顯示。);
2:然後需要實現這個拖動的框框,該框框實現的功能有四點:拖動、擴大縮小、觸摸時顯示基准線、截圖。
首先是布局設計image_details.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:layout_width="match_parent" android:layout_height="55dp" android:background="#323441"> <ImageButton android:id="@+id/certification_returnbtn" android:layout_width="55dp" android:layout_height="55dp" android:background="@android:color/transparent" android:padding="15dp" android:scaleType="fitCenter" android:src="@drawable/topbar_returnbtn"/> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginLeft="10dp" android:layout_toRightOf="@id/certification_returnbtn" android:gravity="center_vertical" android:text="裁剪圖片" android:textColor="@android:color/white" android:textSize="20sp"/> <!-- <ImageButton android:layout_width="55dp" android:layout_height="55dp" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:background="@android:color/transparent" android:padding="16dp" android:scaleType="fitCenter" android:src="@drawable/ic_rotate_24dp"/>--> <ImageView android:id="@+id/testimg" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:layout_width="55dp" android:layout_height="55dp"/> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <com.whale.nangua.pubuliuzhaopianqiang.ZoomImageView android:id="@+id/zoom_image_view" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#303030"/> <com.whale.nangua.pubuliuzhaopianqiang.ChoiceBorderView android:id="@+id/zoom_choiceborder_view" android:layout_width="match_parent" android:layout_height="match_parent"/> <Button android:id="@+id/image_details_subbtn" android:text="確定" android:background="@drawable/image_details_submitbtn_shape" android:layout_marginBottom="20dp" android:layout_width="180dp" android:layout_height="40dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true"/> </RelativeLayout> </LinearLayout>
布局比較簡單,兩個View互相層疊。
自定義圖片大小控制視圖:ZoomImageView.java
代碼注釋很詳細就不解釋了。
package com.whale.nangua.pubuliuzhaopianqiang; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; /** * Created by nangua on 2016/7/20. */ public class ZoomImageView extends View { /** * 初始化狀態常量 */ public static final int STATUS_INIT = 1; /** * 用於對圖片進行移動和縮放變換的矩陣 */ private Matrix matrix = new Matrix(); /** * 待展示的Bitmap對象 */ private Bitmap sourceBitmap; /** * 記錄當前操作的狀態,可選值為STATUS_INIT、STATUS_ZOOM_OUT、STATUS_ZOOM_IN和STATUS_MOVE */ private int currentStatus; /** * ZoomImageView控件的寬度 */ private int width; /** * ZoomImageView控件的高度 */ private int height; /** * ZoomImageView構造函數,將當前操作狀態設為STATUS_INIT。 * * @param context * @param attrs */ public ZoomImageView(Context context, AttributeSet attrs) { super(context, attrs); currentStatus = STATUS_INIT; } /** * 將待展示的圖片設置進來。 * * @param bitmap 待展示的Bitmap對象 */ public void setImageBitmap(Bitmap bitmap) { sourceBitmap = bitmap; invalidate(); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (changed) { // 分別獲取到ZoomImageView的寬度和高度 width = getWidth(); height = getHeight(); } } /** * 根據currentStatus的值來決定對圖片進行什麼樣的繪制操作。 */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); initBitmap(canvas); canvas.drawBitmap(sourceBitmap, matrix, null); } float translateY;//Y軸偏移量 float translateX;//X軸偏移量 /** * @param canvas * @autohr nangua * 對圖片進行初始化操作,包括讓圖片居中,以及當圖片大於屏幕寬高時對圖片進行壓縮。 * <p> * 1.當圖片寬度大於顯示寬度、圖片高度小於顯示寬度: * 設置圖片寬度為顯示寬度,高度縮放*(圖片寬度/顯示寬度) * <p> * 2.當圖片寬度小於顯示寬度、圖片高度大於顯示寬度: * 設置圖片高度為顯示高度,寬度縮放*(圖片高度/顯示高 度) * <p> * 3.當圖片寬度大於顯示寬度,圖片高度大於顯示寬度: * 選取差度更大的一邊進行壓縮,另一邊等比縮放 * <p> * 4.當圖片寬度小於顯示寬度,圖片高度小於顯示寬度: * 選取差度更大的一邊進行壓縮,另一邊等比縮放 */ private void initBitmap(Canvas canvas) { if (sourceBitmap != null) { matrix.reset(); //重置矩陣 int bitmapWidth = sourceBitmap.getWidth(); //得到源圖片寬 int bitmapHeight = sourceBitmap.getHeight(); //得到源圖片高 //如果原圖片大小大於控件寬高 if (bitmapWidth > width || bitmapHeight > height) { //如果寬和高都比屏幕大,選擇差度大的一邊縮小,另一邊等比縮小 if (bitmapWidth > width && bitmapHeight > height) { int distanceX = Math.abs(width - bitmapWidth); int distanceY = Math.abs(height - bitmapHeight); float ratio; //找出差值大的一邊,進行縮小 if (distanceX >= distanceY) { ratio = width / (bitmapWidth * 1.0f); matrix.postScale(ratio, ratio); //此時橫軸鋪滿,只需要對豎軸進行平移 translateY = (height - sourceBitmap.getHeight() * ratio) / 2f; matrix.postTranslate(0, translateY); } else { ratio = height / (bitmapHeight * 1.0f); matrix.postScale(ratio, ratio); //此時豎軸鋪滿,只需要對橫軸進行平移 translateX = (width - sourceBitmap.getWidth() * ratio) / 2f; matrix.postTranslate(translateX, 0); //在橫縱軸上進行平移 } //當圖片寬度大於顯示寬度、圖片高度小於顯示寬度: } else if (bitmapWidth > width) { // 當圖片寬度大於屏幕寬度時,將圖片等比例壓縮,使它可以完全顯示出來 float ratio = width / (bitmapWidth * 1.0f); //壓縮比例 matrix.postScale(ratio, ratio); translateY = (height - (bitmapHeight * ratio)) / 2f; // 在縱坐標方向上進行偏移,以保證圖片居中顯示 matrix.postTranslate(0, translateY); //當圖片寬度小於顯示寬度、圖片高度大於顯示寬度: } else if (bitmapHeight > height) { // 當圖片高度大於屏幕高度時,將圖片等比例壓縮,使它可以完全顯示出來 float ratio = height / (bitmapHeight * 1.0f); //壓縮比例 matrix.postScale(ratio, ratio); translateX = (width - (bitmapWidth * ratio)) / 2f; // 在橫坐標方向上進行偏移,以保證圖片居中顯示 matrix.postTranslate(translateX, 0); } } else { // 當圖片的寬高都小於屏幕寬高時,選擇差度小的一邊鋪滿,另一邊等比擴大 //計算長和寬的差值 int distanceX = Math.abs(width - bitmapWidth); int distanceY = Math.abs(height - bitmapHeight); float ratio; //找出差值小的一邊,進行擴大 if (distanceX <= distanceY) { ratio = width / (bitmapWidth * 1.0f); matrix.postScale(ratio, ratio); //此時橫軸鋪滿,只需要對豎軸進行平移 translateY = (height - sourceBitmap.getHeight() * ratio) / 2f; matrix.postTranslate(0, translateY); } else { ratio = height / (bitmapHeight * 1.0f); matrix.postScale(ratio, ratio); //此時豎軸鋪滿,只需要對橫軸進行平移 translateX = (width - sourceBitmap.getWidth() * ratio) / 2f; matrix.postTranslate(translateX, 0); //在橫縱軸上進行平移 } } //進行繪制 canvas.drawBitmap(sourceBitmap, matrix, null); } } }
重點來了,相冊選取框視圖:ChoiceBorderView.java
package com.whale.nangua.pubuliuzhaopianqiang; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.Toast; /** * 相冊選擇框的View * Created by nangua on 2016/7/21. */ public class ChoiceBorderView extends View { private int scale = (int) this.getResources().getDisplayMetrics().density; //屏幕像素密度 private float borderHeight; //總高 private float borderWith; //總寬 private float borderLength = 200 * scale; //邊框長度 private int RECT_BORDER_WITH = 3 * scale; //長方形框框粗 private int RECT_CORNER_WITH = 6 * scale; //四個角的粗 private int RECT_CORNER_HEIGHT = 20 * scale; //四個角的長度 //四個點坐標 private static float[][] four_corner_coordinate_positions; private static int NOW_MOVE_STATE = 1; //移動狀態,默認為1,Y軸=1,X軸=2 private static boolean MOVE_OR_ZOOM_STATE = true; //移動或縮放狀態, true 為移動 public ChoiceBorderView(Context context, AttributeSet attrs) { super(context, attrs); this.setFocusable(true); this.setFocusableInTouchMode(true); init(); } /** * 初始化布局 * @param changed * @param left * @param top * @param right * @param bottom */ @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); borderHeight = this.getHeight(); borderWith = this.getWidth(); //初始化四個點的坐標 four_corner_coordinate_positions = new float[][]{ {(borderWith - borderLength) / 2, (borderHeight - borderLength) / 2}, //左上 {(borderWith + borderLength) / 2, (borderHeight - borderLength) / 2}, //右上 {(borderWith - borderLength) / 2, (borderHeight + borderLength) / 2}, //左下 {(borderWith + borderLength) / 2, (borderHeight + borderLength) / 2}, //右上 }; } private void init() { } private int temp1 = (RECT_CORNER_WITH - RECT_BORDER_WITH) / 2; //長方形的粗半距 private int temp2 = (RECT_CORNER_WITH + RECT_BORDER_WITH) / 2; //四個角的粗半距 /** * RECT_CORNER_WITH = 6 * RECT_BORDER_WITH =3 * * @param canvas */ @Override protected void onDraw(Canvas canvas) { Paint paintRect = new Paint(); //初始化畫筆 //畫邊框的畫筆 paintRect.setColor(getResources().getColor(R.color.bordercolor)); //顏色 paintRect.setStrokeWidth(RECT_BORDER_WITH); //寬度 paintRect.setAntiAlias(true); //抗鋸齒 paintRect.setStyle(Paint.Style.STROKE); //設置空心 canvas.drawRect(four_corner_coordinate_positions[0][0], four_corner_coordinate_positions[0][1], four_corner_coordinate_positions[3][0], four_corner_coordinate_positions[3][1], paintRect); //畫四個角的畫筆 paintRect.setColor(Color.WHITE); paintRect.setStrokeWidth(RECT_CORNER_WITH); paintRect.setAntiAlias(true); //左上角的兩根 canvas.drawLine(four_corner_coordinate_positions[0][0] - temp2, four_corner_coordinate_positions[0][1] - temp1, four_corner_coordinate_positions[0][0] - temp1 + RECT_CORNER_HEIGHT, four_corner_coordinate_positions[0][1] - temp1, paintRect); canvas.drawLine(four_corner_coordinate_positions[0][0] - temp1, four_corner_coordinate_positions[0][1] - temp2, four_corner_coordinate_positions[0][0] - temp1, four_corner_coordinate_positions[0][1] - temp1 + RECT_CORNER_HEIGHT, paintRect); //左下角的兩根 canvas.drawLine(four_corner_coordinate_positions[2][0] - temp2, four_corner_coordinate_positions[2][1] + temp1, four_corner_coordinate_positions[2][0] - temp1 + RECT_CORNER_HEIGHT, four_corner_coordinate_positions[2][1] + temp1, paintRect); canvas.drawLine(four_corner_coordinate_positions[2][0] - temp1, four_corner_coordinate_positions[2][1] + temp1, four_corner_coordinate_positions[2][0] - temp1, four_corner_coordinate_positions[2][1] + temp1 - RECT_CORNER_HEIGHT, paintRect); //右上角的兩根 canvas.drawLine(four_corner_coordinate_positions[1][0] + temp1, four_corner_coordinate_positions[1][1] - temp1, four_corner_coordinate_positions[1][0] + temp1 - RECT_CORNER_HEIGHT, four_corner_coordinate_positions[1][1] - temp1, paintRect); canvas.drawLine(four_corner_coordinate_positions[1][0] + temp1, four_corner_coordinate_positions[1][1] - temp2, four_corner_coordinate_positions[1][0] + temp1, four_corner_coordinate_positions[1][1] - temp1 + RECT_CORNER_HEIGHT , paintRect); //右下角的兩根 canvas.drawLine(four_corner_coordinate_positions[3][0] + temp2, four_corner_coordinate_positions[3][1] + temp1, four_corner_coordinate_positions[3][0] + temp1 - RECT_CORNER_HEIGHT, four_corner_coordinate_positions[3][1] + temp1, paintRect); canvas.drawLine(four_corner_coordinate_positions[3][0] + temp1, four_corner_coordinate_positions[3][1] + temp1, four_corner_coordinate_positions[3][0] + temp1, four_corner_coordinate_positions[3][1] + temp1 - RECT_CORNER_HEIGHT, paintRect); //畫掃描線 if (IF_SCANNING_SHOW) { paintRect.setColor(Color.WHITE); paintRect.setStrokeWidth(1); paintRect.setAntiAlias(true); paintRect.setStyle(Paint.Style.STROKE); //共四根線 //豎1 canvas.drawLine(four_corner_coordinate_positions[0][0] + borderLength / 3, four_corner_coordinate_positions[0][1] + temp1, four_corner_coordinate_positions[2][0] + borderLength / 3, four_corner_coordinate_positions[2][1] - temp1, paintRect); //豎2 canvas.drawLine(four_corner_coordinate_positions[1][0] - borderLength / 3, four_corner_coordinate_positions[1][1] + temp1, four_corner_coordinate_positions[3][0] - borderLength / 3, four_corner_coordinate_positions[3][1] - temp1, paintRect); //橫1 canvas.drawLine(four_corner_coordinate_positions[0][0] + temp1, four_corner_coordinate_positions[0][1] + borderLength / 3, four_corner_coordinate_positions[1][0] - temp1, four_corner_coordinate_positions[1][1] + borderLength / 3, paintRect); //橫2 canvas.drawLine(four_corner_coordinate_positions[2][0] + temp1, four_corner_coordinate_positions[2][1] - borderLength / 3, four_corner_coordinate_positions[3][0] - temp1, four_corner_coordinate_positions[3][1] - borderLength / 3, paintRect); } } private boolean IF_SCANNING_SHOW = false; private int lastX = 0; //上次按下的X位置 private int lastY = 0; //上次按下的Y位置 private int offsetX = 0; //X軸偏移量 private int offsetY = 0; //Y軸偏移量 static int point = -1;// 用戶按下的點 private int POINT_STATE = -1; //判斷用戶是縮小還是放大 0放大 1縮小 @Override public boolean onTouchEvent(MotionEvent event) { int x = (int) event.getX(); int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: IF_SCANNING_SHOW = true;//顯示掃描線 if (isInTheCornerCircle(event.getX(), event.getY()) != -1) { //開始縮放操作 MOVE_OR_ZOOM_STATE = false; //設置false為縮放狀態 point = isInTheCornerCircle(event.getX(), event.getY()); } lastX = x; lastY = y; invalidate(); break; case MotionEvent.ACTION_MOVE: offsetX = x - lastX; offsetY = y - lastY; //判斷當前是擴大還是縮小操作 judgementXandY(); //限定移動范圍 //移動狀態:只有在移動狀態下才能移動 if (MOVE_OR_ZOOM_STATE) { getoffsetXandoffsetY(); //四個點的坐標信息也要隨之改變 for (int i = 0; i < four_corner_coordinate_positions.length; i++) { four_corner_coordinate_positions[i][0] += offsetX; four_corner_coordinate_positions[i][1] += offsetY; //更新回調接口 onImageDetailsSizeChanggedl.onBorderSizeChangged( (int) four_corner_coordinate_positions[0][0], (int) four_corner_coordinate_positions[0][1], (int) borderLength ); invalidate(); } // this.scrollBy(-offsetX, -offsetY); //這裡棄用,後面改用了四點坐標移動代替背景移動 } //在縮放狀態下 else { //按住某一個點,該點的坐標改變,其他2個點坐標跟著改變,對點坐標不變 max = Math.abs(offsetX) >= Math.abs(offsetY) ? Math.abs(offsetX) : Math.abs(offsetY); //只有在擴大操作才進行邊界范圍判斷 if (POINT_STATE == 0) { getoffsetXandoffsetY(); //邊界范圍判斷 } //縮小操作時進行邊界不能太小判斷 else if (POINT_STATE == 1) { //如果邊長+max太小,直接返回 if (borderLength - max <= RECT_CORNER_HEIGHT*2-temp2) { max = 0; } } //改變坐標 changgeFourCoodinatePosition(point, offsetX, offsetY); //更新邊長 notifyNowborderLength(); //更新回調接口 onImageDetailsSizeChanggedl.onBorderSizeChangged( (int) four_corner_coordinate_positions[0][0], (int) four_corner_coordinate_positions[0][1], (int) borderLength ); invalidate(); } lastX = x; lastY = y; break; case MotionEvent.ACTION_UP: IF_SCANNING_SHOW = false; //不顯示掃描線 MOVE_OR_ZOOM_STATE = true; //回歸為默認的移動狀態 invalidate(); break; } return true; } /** * 更新矩形框邊長的方法 */ private void notifyNowborderLength() { float a = four_corner_coordinate_positions[0][0]; float b = four_corner_coordinate_positions[0][1]; float c = four_corner_coordinate_positions[1][0]; float d = four_corner_coordinate_positions[1][1]; float temp1 = (float) Math.pow(a - c, 2); float temp2 = (float) Math.pow(b - d, 2); borderLength = (float) Math.sqrt(temp1 + temp2); } /** * POINT_STATE 為0放大, 1縮小 */ private void judgementXandY() { switch (point) { case 0: if ((offsetX <= 0 && offsetY <= 0) || (offsetX <= 0 && offsetY >= 0)) { POINT_STATE = 0;//擴大 } else { POINT_STATE = 1;//縮小 } break; case 1: if ((offsetX >= 0 && offsetY <= 0) || (offsetX >= 0 && offsetY >= 0)) { POINT_STATE = 0; } else { POINT_STATE = 1; } break; case 2: if ((offsetX <= 0 && offsetY >= 0) || (offsetX <= 0 && offsetY <= 0)) { POINT_STATE = 0; } else { POINT_STATE = 1; } break; case 3: if ((offsetX >= 0 && offsetY >= 0) || (offsetX >= 0 && offsetY <= 0)) { POINT_STATE = 0; } else { POINT_STATE = 1; } break; } } /** * 防止X和Y溢出邊界的算法 */ private void getoffsetXandoffsetY() { //如果是移動狀態 if (MOVE_OR_ZOOM_STATE) { if ((four_corner_coordinate_positions[0][0] + offsetX <= 0) || (four_corner_coordinate_positions[1][0] + offsetX >= borderWith) ) { offsetX = 0; } if ((four_corner_coordinate_positions[0][1] + offsetY <= 0) || (four_corner_coordinate_positions[2][1] + offsetY >= borderHeight) ) { offsetY = 0; } } //如果是縮放狀態 else { switch (point) { case 0: if ((four_corner_coordinate_positions[0][0] - max <= 0) || (four_corner_coordinate_positions[0][1] - max <= 0) ) { max = 0; } break; case 1: if ((four_corner_coordinate_positions[1][0] + max >= borderWith) || (four_corner_coordinate_positions[1][1] - max <= 0) ) { max = 0; } break; case 2: if ((four_corner_coordinate_positions[2][0] - max <= 0) || (four_corner_coordinate_positions[2][1] + max >= borderHeight) ) { max = 0; } break; case 3: if ((four_corner_coordinate_positions[3][0] + max >= borderWith) || (four_corner_coordinate_positions[3][1] + max >= borderHeight) ) { max = 0; } break; } } } static int max; /** * 擴大縮放方法 * 根據用戶傳來的點改變其他點的坐標 * 按住某一個點,該點的坐標改變,其他2個點坐標跟著改變,對點坐標不變 * 點陣示意: * 0 1 * 2 3 * * @param point 用戶按的點 * @param offsetX X軸偏移量 * @param offsetY Y軸偏移量 */ private void changgeFourCoodinatePosition(int point, int offsetX, int offsetY) { switch (point) { case 0: if (offsetX > 0 && offsetY < 0) { //變化0點的位置 suoxiao four_corner_coordinate_positions[0][0] += max; four_corner_coordinate_positions[0][1] += max; //變化1點的Y軸 four_corner_coordinate_positions[1][1] += max; //變化2點的X軸 four_corner_coordinate_positions[2][0] += max; } else if (offsetX < 0 && offsetY > 0) { //變化0點的位置 kuoda four_corner_coordinate_positions[0][0] -= max; four_corner_coordinate_positions[0][1] -= max; //變化1點的Y軸 four_corner_coordinate_positions[1][1] -= max; //變化2點的X軸 four_corner_coordinate_positions[2][0] -= max; } else if (offsetX < 0 && offsetY < 0) { //變化0點的位置 kuoda four_corner_coordinate_positions[0][0] -= max; four_corner_coordinate_positions[0][1] -= max; //變化1點的Y軸 four_corner_coordinate_positions[1][1] -= max; //變化2點的X軸 four_corner_coordinate_positions[2][0] -= max; } else if (offsetX > 0 && offsetY > 0) { //變化0點的位置 suoxiao four_corner_coordinate_positions[0][0] += max; four_corner_coordinate_positions[0][1] += max; //變化1點的Y軸 four_corner_coordinate_positions[1][1] += max; //變化2點的X軸 four_corner_coordinate_positions[2][0] += max; } break; case 1: if (offsetX > 0 && offsetY < 0) { //變化1點的位置 four_corner_coordinate_positions[1][0] += max; four_corner_coordinate_positions[1][1] -= max; //變化0點的Y軸 four_corner_coordinate_positions[0][1] -= max; //變化3點的X軸 four_corner_coordinate_positions[3][0] += max; } else if (offsetX < 0 && offsetY > 0) { //變化1點的位置 four_corner_coordinate_positions[1][0] -= max; four_corner_coordinate_positions[1][1] += max; //變化0點的Y軸 four_corner_coordinate_positions[0][1] += max; //變化3點的X軸 four_corner_coordinate_positions[3][0] -= max; } else if (offsetX < 0 && offsetY < 0) { //變化1點的位置 four_corner_coordinate_positions[1][0] -= max; four_corner_coordinate_positions[1][1] += max; //變化0點的Y軸 four_corner_coordinate_positions[0][1] += max; //變化3點的X軸 four_corner_coordinate_positions[3][0] -= max; } else if (offsetX > 0 && offsetY > 0) { //變化1點的位置 four_corner_coordinate_positions[1][0] += max; four_corner_coordinate_positions[1][1] -= max; //變化0點的Y軸 four_corner_coordinate_positions[0][1] -= max; //變化3點的X軸 four_corner_coordinate_positions[3][0] += max; } break; case 2: if (offsetX > 0 && offsetY < 0) { //變化2點的位置 suoxiao four_corner_coordinate_positions[2][0] += max; four_corner_coordinate_positions[2][1] -= max; //變化0點的X軸 four_corner_coordinate_positions[0][0] += max; //變化3點的Y軸 four_corner_coordinate_positions[3][1] -= max; } else if (offsetX < 0 && offsetY > 0) { //變化2點的位置 kuoda four_corner_coordinate_positions[2][0] -= max; four_corner_coordinate_positions[2][1] += max; //變化0點的X軸 four_corner_coordinate_positions[0][0] -= max; //變化3點的Y軸 four_corner_coordinate_positions[3][1] += max; } else if (offsetX < 0 && offsetY < 0) { //變化2點的位置 kuoda four_corner_coordinate_positions[2][0] -= max; four_corner_coordinate_positions[2][1] += max; //變化0點的X軸 four_corner_coordinate_positions[0][0] -= max; //變化3點的Y軸 four_corner_coordinate_positions[3][1] += max; } else if (offsetX > 0 && offsetY > 0) { //變化2點的位置 suoxiao four_corner_coordinate_positions[2][0] += max; four_corner_coordinate_positions[2][1] -= max; //變化0點的X軸 four_corner_coordinate_positions[0][0] += max; //變化3點的Y軸 four_corner_coordinate_positions[3][1] -= max; } break; case 3: if (offsetX > 0 && offsetY < 0) { //變化3點的位置 kuoda four_corner_coordinate_positions[3][0] += max; four_corner_coordinate_positions[3][1] += max; //變化1點的X軸 four_corner_coordinate_positions[1][0] += max; //變化2點的Y軸 four_corner_coordinate_positions[2][1] += max; } else if (offsetX < 0 && offsetY > 0) { //變化3點的位置 suoxiao four_corner_coordinate_positions[3][0] -= max; four_corner_coordinate_positions[3][1] -= max; //變化1點的X軸 four_corner_coordinate_positions[1][0] -= max; //變化2點的Y軸 four_corner_coordinate_positions[2][1] -= max; } else if (offsetX < 0 && offsetY < 0) { //變化3點的位置 suoxiao four_corner_coordinate_positions[3][0] -= max; four_corner_coordinate_positions[3][1] -= max; //變化1點的X軸 four_corner_coordinate_positions[1][0] -= max; //變化2點的Y軸 four_corner_coordinate_positions[2][1] -= max; } else if (offsetX > 0 && offsetY > 0) { //變化3點的位置 kuoda four_corner_coordinate_positions[3][0] += max; four_corner_coordinate_positions[3][1] += max; //變化1點的X軸 four_corner_coordinate_positions[1][0] += max; //變化2點的Y軸 four_corner_coordinate_positions[2][1] += max; } break; } } /** * 判斷按下的點在圓圈內 * * @param x 按下的X坐標 * @param y 按下的Y坐標 * @return 返回按到的是哪個點, 沒有則返回-1 * 點陣示意: * 0 1 * 2 3 */ private int isInTheCornerCircle(float x, float y) { for (int i = 0; i < four_corner_coordinate_positions.length; i++) { float a = four_corner_coordinate_positions[i][0]; float b = four_corner_coordinate_positions[i][1]; float temp1 = (float) Math.pow((x - a), 2); float temp2 = (float) Math.pow((y - b), 2); if (((float) RECT_CORNER_HEIGHT) >= Math.sqrt(temp1 + temp2)) { return i; } } return -1; } public interface onImageDetailsSizeChangged { void onBorderSizeChangged(int x, int y, int length); } public onImageDetailsSizeChangged onImageDetailsSizeChanggedl; public void setonImageDetailsSizeChangged(onImageDetailsSizeChangged onImageDetailsSizeChangged) { this.onImageDetailsSizeChanggedl = onImageDetailsSizeChangged; } }
以上所述是小編給大家介紹的Android自定義View實現照片裁剪框與照片裁剪功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對本站網站的支持!
本文實例講述了Android編程中的Menu功能菜單。分享給大家供大家參考,具體如下:Android功能菜單的設計,程序裡定義了兩個菜單子項,一個是關於,一個是退出,當點
背景上周發現蘑菇街IM-Android代碼裡面,一些地方代碼編寫不當,存在內存洩漏的問題,在和瘋紫交流的過程中,發現加深了一些理解,所以決定寫一下分析思路,相互學習。內存
前兩天研究了一下NDK開發,然而沒有成功。今天興趣盎然,再試試,不知道會不會成功,我將記錄我在學習過程中遇到的一些困難,以及成功後的效果。我當前的狀態是以及學習了一段時間
本篇是Activity啟動模式篇的基礎篇,介紹Activity四種啟動模式的基本概念、Intent Flag設置啟動模式以及應用場景。在介紹四種啟動模式之前,先介紹一下