Back to project page Common-Library.
The source code is released under:
Apache License
If you think the Android project Common-Library listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.morgan.library.widget; /*from w w w .j a v a 2 s . c om*/ import java.io.File; import android.annotation.SuppressLint; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Point; import android.graphics.Rect; import android.os.Build; import android.view.Display; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import com.morgan.library.R; import com.morgan.library.utils.AppUtils; import com.morgan.library.utils.Logger; import com.morgan.library.utils.SDCardUtils; /** * * ???????View * * @author yeguozhong@yeah.net * */ @SuppressLint("ViewConstructor") public class ScreenShotView extends View implements OnTouchListener { private Paint mGrayPaint; private Rect topRect; private Rect rightRect; private Rect bottomRect; private Rect leftRect; private int screenWidth; private int screeenHeight; private OnScreenShotListener mListener; private Activity mContext; // ????????? private int top, right, bottom, left; // ????????????????????? private int tmpLeft, tmpTop, tmpRight, tmpBottom; private int innerWidth, innerHeight; // ?????????????? private int downX, downY, moveX, moveY; private final static int TOUCH_SELECT = 1; // ???? private final static int TOUCH_MOVE = 2; // ???? private int touchFlag = TOUCH_SELECT; private boolean isInMoveSelection; // ?????????? private boolean isInTopPullArea; // ??????? private boolean isInRightPullArea; // ????????? private boolean isInBottomPullArea; private boolean isInLeftPullArea; private int innnerClickCount = 0; // ??????????????? private int outterClickCount = 0; // ?????????????? private long timeInterval; // ?????? private long firstClickTime; // ????????? private long secondClickTime; // ????????? private long TouchDownTime; // ?????? private long TouchUpTime; // ???????? private final static long VALID_CLICK_INTERVAL = 500; // ??down,up??500??????????? private final static long VALID_DOUBLE_CLICK_INTERNAL = 1000;// ????????????? private final static int VALID_PULL_DISTANCE = 30; // ?????????? private boolean isTimeToTip = false; public final static String TEMP_SHARE_FILE_NAME = SDCardUtils .getSDCardPath() + File.pathSeparator + "temp.jpg"; private static Bitmap bmDoubleClickTip; /** * ????????? */ public interface OnScreenShotListener { public void onComplete(Bitmap bm); } public ScreenShotView(Activity context, OnScreenShotListener listener) { super(context); mListener = listener; mContext = context; Point p = getDisplaySize(context.getWindowManager().getDefaultDisplay()); screenWidth = p.x; screeenHeight = p.y; mGrayPaint = new Paint(); mGrayPaint.setARGB(100, 0, 0, 0); topRect = new Rect(); rightRect = new Rect(); bottomRect = new Rect(); leftRect = new Rect(); topRect.set(0, 0, screenWidth, screeenHeight); setOnTouchListener(this); if (bmDoubleClickTip == null) { bmDoubleClickTip = BitmapFactory.decodeStream(getResources() .openRawResource(R.drawable.double_click)); } AppUtils.ToastMessage(mContext, "?????????!"); } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawRect(topRect, mGrayPaint); canvas.drawRect(rightRect, mGrayPaint); canvas.drawRect(bottomRect, mGrayPaint); canvas.drawRect(leftRect, mGrayPaint); if (isTimeToTip) { // ???????????? innerWidth = right - left; innerHeight = bottom - top; int bmWidth = bmDoubleClickTip.getWidth(); int bmHeight = bmDoubleClickTip.getHeight(); int x = (int) (left + (innerWidth - bmWidth) * 0.5); int y = (int) (top + (innerHeight - bmHeight) * 0.5); canvas.drawBitmap(bmDoubleClickTip, x, y, null); isTimeToTip = false; } } @Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: isTimeToTip = false; downX = (int) event.getX(); downY = (int) event.getY(); isInMoveSelection = isInSeletion(downX, downY); isInTopPullArea = isInTopPullArea(downX, downY); isInRightPullArea = isInRightPullArea(downX, downY); isInBottomPullArea = isInBottomPullArea(downX, downY); isInLeftPullArea = isInLeftPullArea(downX, downY); TouchDownTime = System.currentTimeMillis(); break; case MotionEvent.ACTION_MOVE: isTimeToTip = false; moveX = (int) event.getX(); moveY = (int) event.getY(); if (touchFlag == TOUCH_SELECT) { tmpLeft = left = getMin(downX, moveX); tmpTop = top = getMin(downY, moveY); tmpRight = right = getMax(downX, moveX); tmpBottom = bottom = getMax(downY, moveY); isInMoveSelection = false; } else if (touchFlag == TOUCH_MOVE && isInMoveSelection) { int xDistance = moveX - downX; int yDistance = moveY - downY; decideCoordinate(xDistance, yDistance); } else if (touchFlag == TOUCH_MOVE && isInTopPullArea) { int yDistance = downY - moveY; int extremeY = (bottom - 2 * VALID_PULL_DISTANCE); top = (tmpTop - yDistance) < extremeY ? (tmpTop - yDistance) : extremeY; } else if (touchFlag == TOUCH_MOVE && isInRightPullArea) { int xDistance = moveX - downX; int extremeX = (left + 2 * VALID_PULL_DISTANCE); right = (tmpRight + xDistance) > extremeX ? (tmpRight + xDistance) : extremeX; } else if (touchFlag == TOUCH_MOVE && isInBottomPullArea) { int yDistance = downY - moveY; int extremeY = (top + 2 * VALID_PULL_DISTANCE); bottom = (tmpBottom - yDistance) > extremeY ? (tmpBottom - yDistance) : extremeY; } else if (touchFlag == TOUCH_MOVE && isInLeftPullArea) { int xDistance = downX - moveX; int extremeX = (right - 2 * VALID_PULL_DISTANCE); left = (tmpLeft - xDistance) < extremeX ? (tmpLeft - xDistance) : extremeX; } setInnerBorder(left, top, right, bottom); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: if (touchFlag == TOUCH_SELECT) { touchFlag = TOUCH_MOVE; } else if (touchFlag == TOUCH_MOVE) { tmpLeft = left; tmpTop = top; tmpRight = right; tmpBottom = bottom; } if (isShouldShowTip() && isTimeToTip == false) { isTimeToTip = true; invalidate(); } TouchUpTime = System.currentTimeMillis(); timeInterval = TouchUpTime - TouchDownTime; // ????????????????????????????? if (timeInterval < VALID_CLICK_INTERVAL && isInMoveSelection) { innnerClickCount = innnerClickCount + 1; if (innnerClickCount == 1) { firstClickTime = System.currentTimeMillis(); } else if (innnerClickCount == 2) { secondClickTime = System.currentTimeMillis(); if ((secondClickTime - firstClickTime) < VALID_DOUBLE_CLICK_INTERNAL) { isTimeToTip = false; mListener.onComplete(getCutImage()); dismiss(); } innnerClickCount = 0; } } else if (timeInterval < VALID_CLICK_INTERVAL && !isInMoveSelection) { outterClickCount = outterClickCount + 1; if (outterClickCount == 1) { firstClickTime = System.currentTimeMillis(); } else if (outterClickCount == 2) { secondClickTime = System.currentTimeMillis(); if ((secondClickTime - firstClickTime) < VALID_DOUBLE_CLICK_INTERNAL) { isTimeToTip = false; dismiss(); } outterClickCount = 0; } } break; default: break; } return true; } private int getMin(int x, int y) { return x > y ? y : x; } private int getMax(int x, int y) { return x > y ? x : y; } /** * ?????????? * * @return */ private boolean isInLeftPullArea(int x, int y) { if (((left - VALID_PULL_DISTANCE) <= x && x < (left + VALID_PULL_DISTANCE)) && ((top + VALID_PULL_DISTANCE) < y && y < (bottom - VALID_PULL_DISTANCE))) { return true; } return false; } /** * ???????????? * * @return */ private boolean isInRightPullArea(int x, int y) { if (((right - VALID_PULL_DISTANCE) <= x && x < (right + VALID_PULL_DISTANCE)) && ((top + VALID_PULL_DISTANCE) < y && y < (bottom - VALID_PULL_DISTANCE))) { return true; } return false; } /** * ?????????? * * @return */ private boolean isInTopPullArea(int x, int y) { if (((left + VALID_PULL_DISTANCE) <= x && x < (right - VALID_PULL_DISTANCE)) && ((top - VALID_PULL_DISTANCE) < y && y < (top + VALID_PULL_DISTANCE))) { return true; } return false; } /** * ?????????? * * @return */ private boolean isInBottomPullArea(int x, int y) { if (((left + VALID_PULL_DISTANCE) <= x && x < (right - VALID_PULL_DISTANCE)) && ((bottom - VALID_PULL_DISTANCE) < y && y < (bottom + VALID_PULL_DISTANCE))) { return true; } return false; } /** * ??????????????? * * @param x * @param y * @return */ private boolean isInSeletion(int x, int y) { if ((left != 0 || right != 0 || top != 0 || bottom != 0) && ((left + VALID_PULL_DISTANCE) <= x && x <= (right - VALID_PULL_DISTANCE)) && ((top + VALID_PULL_DISTANCE) <= y && y <= (bottom - VALID_PULL_DISTANCE))) { return true; } return false; } /** * ?????????????? * * @return */ private boolean isShouldShowTip() { if ((right - left) > 100 && (bottom - top) > 100) { return true; } return false; } /** * ??????????? * * @param xDistance * @param yDistance */ private void decideCoordinate(int xDistance, int yDistance) { innerWidth = right - left; innerHeight = bottom - top; // ?????????? if ((tmpLeft + xDistance) < 0) { right = innerWidth; left = 0; } else if ((tmpRight + xDistance) > screenWidth) { left = screenWidth - innerWidth; right = screenWidth; } else { left = tmpLeft + xDistance; right = tmpRight + xDistance; } // ???????? if ((tmpTop + yDistance) < 0) { bottom = innerHeight; top = 0; } else if ((tmpBottom + yDistance) > screeenHeight) { top = screeenHeight - innerHeight; bottom = screeenHeight; } else { top = tmpTop + yDistance; bottom = tmpBottom + yDistance; } } /** * ?? ????????? */ private void setInnerBorder(int left, int top, int right, int bottom) { Logger.i("com.example", "left:" + left + ",top:" + top + ",right:" + right + ",bottom:" + bottom); topRect.set(0, 0, screenWidth, top); rightRect.set(right, top, screenWidth, bottom); bottomRect.set(0, bottom, screenWidth, screeenHeight); leftRect.set(0, top, left, bottom); this.invalidate(); } /** * ??????????View. */ private Bitmap getCutImage() { View view = mContext.getWindow().getDecorView(); Bitmap bmp = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bmp); view.draw(canvas); return imageCrop(bmp); } /** * ????? */ private Bitmap imageCrop(Bitmap bitmap) { int x = left < 0 ? 0 : left; int y = top + getStatusHeight(); int width = right - left; int height = bottom - top; if ((width + x) > bitmap.getWidth()) { width = bitmap.getWidth() - x; } if ((y + height) > bitmap.getHeight()) { height = bitmap.getHeight() - y; } return Bitmap.createBitmap(bitmap, x, y, width, height, null, false); } /** * ?????????? * * @return */ private int getStatusHeight() { Rect frame = new Rect(); mContext.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); return frame.top; } /** * ???view */ public void dismiss() { mGrayPaint.setARGB(0, 0, 0, 0); setOnTouchListener(null); invalidate(); } /** * ?????????????? * * @param display * @return */ @SuppressWarnings("deprecation") @SuppressLint("NewApi") private static Point getDisplaySize(final Display display) { final Point point = new Point(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { display.getSize(point); } else { point.x = display.getWidth(); point.y = display.getHeight(); } return point; } }