詹子聪 5 лет назад
Родитель
Сommit
9f628f711a

+ 15 - 0
app/src/main/java/com/miekir/ocr/base/IScalable.java

@@ -0,0 +1,15 @@
+package com.miekir.ocr.base;
+
+/**
+ * Copyright (C), 2019-2020, Miekir
+ *
+ * @author Miekir
+ * @date 2020/10/14 10:09
+ * Description:
+ */
+public interface IScalable {
+    void setAnimateWidth(int width, int height, int left, int top, int right, int bottom);
+    void setAnimateHeight(int width, int height, int left, int top, int right, int bottom);
+
+    void stopTranslateAnimation();
+}

+ 58 - 0
app/src/main/java/com/miekir/ocr/tool/AnimateManager.java

@@ -0,0 +1,58 @@
+package com.miekir.ocr.tool;
+
+import com.miekir.ocr.base.IScalable;
+
+/**
+ * Copyright (C), 2019-2020, Miekir
+ *
+ * @author Miekir
+ * @date 2020/10/14 10:04
+ * Description:
+ */
+public class AnimateManager {
+    private static volatile AnimateManager instance;
+
+    private AnimateManager() {
+    }
+
+    private IScalable scalable;
+
+    public void register(IScalable scalable) {
+        this.scalable = scalable;
+    }
+
+    public void unRegister() {
+        this.scalable = null;
+    }
+
+    public static AnimateManager getInstance() {
+        if (instance == null) {
+            init();
+        }
+        return instance;
+    }
+
+    private static synchronized void init() {
+        if (instance == null) {
+            instance = new AnimateManager();
+        }
+    }
+
+    public void setWidth(int width, int height, int left, int top, int right, int bottom) {
+        if (scalable != null) {
+            scalable.setAnimateWidth(width, height, left, top, right, bottom);
+        }
+    }
+
+    public void setHeight(int width, int height, int left, int top, int right, int bottom) {
+        if (scalable != null) {
+            scalable.setAnimateHeight(width, height, left, top, right, bottom);
+        }
+    }
+
+    public void stopAnimation() {
+        if (scalable != null) {
+            scalable.stopTranslateAnimation();
+        }
+    }
+}

+ 17 - 2
app/src/main/java/com/miekir/ocr/widget/CropView.java

@@ -14,9 +14,11 @@ import android.util.DisplayMetrics;
 import android.util.TypedValue;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewTreeObserver;
 import android.view.WindowManager;
 
 import com.miekir.ocr.R;
+import com.miekir.ocr.tool.AnimateManager;
 
 public class CropView extends View {
     public static final int SCAN_TYPE_POSTAL = 0;
@@ -80,7 +82,14 @@ public class CropView extends View {
         super(context, attrs, defStyleAttr);
 
         // 获取到宽高之后再初始化
-        post(() -> setScanArea(SCAN_TYPE_ALL));
+        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+                getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                setScanArea(SCAN_TYPE_ALL); //height is ready
+            }
+        });
+        //post(() -> );
     }
 
     /**
@@ -144,7 +153,6 @@ public class CropView extends View {
 
 
         // 起始位置
-
         init();
     }
 
@@ -323,6 +331,7 @@ public class CropView extends View {
     public boolean onTouchEvent(MotionEvent event) {
         switch (event.getAction()) {
             case MotionEvent.ACTION_DOWN:
+                AnimateManager.getInstance().stopAnimation();
                 if (changeLocationlistener != null) {
                     changeLocationlistener.locationChange("change self");
                 } else {
@@ -364,6 +373,12 @@ public class CropView extends View {
             case MotionEvent.ACTION_UP:
                 mPaintLine.setColor(Color.WHITE);
                 postInvalidate();
+
+                if (coverWidth > coverHeight) {
+                    AnimateManager.getInstance().setWidth(coverWidth, coverHeight, sX, sY, eX, eY);
+                } else {
+                    AnimateManager.getInstance().setHeight(coverWidth, coverHeight, sX, sY, eX, eY);
+                }
                 break;
             default:
                 break;

+ 151 - 0
app/src/main/java/com/miekir/ocr/widget/ScalableImageView.java

@@ -0,0 +1,151 @@
+package com.miekir.ocr.widget;
+
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.util.AttributeSet;
+import android.view.animation.Animation;
+import android.view.animation.TranslateAnimation;
+import android.widget.FrameLayout;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.AppCompatImageView;
+
+import com.miekir.ocr.R;
+import com.miekir.ocr.base.IScalable;
+import com.miekir.ocr.tool.AnimateManager;
+
+import static android.view.animation.Animation.INFINITE;
+
+/**
+ * Copyright (C), 2019-2020, Miekir
+ *
+ * @author Miekir
+ * @date 2020/10/14 9:33
+ * Description: 按比例缩放的ImageView
+ */
+public class ScalableImageView extends AppCompatImageView implements IScalable {
+    private int mVerticalRawWidth;
+    private int mVerticalRawHeight;
+    private Bitmap mVerticalBitmap;
+
+    private int mHorizontalRawWidth;
+    private int mHorizontalRawHeight;
+    private Bitmap mHorizontalBitmap;
+
+    public ScalableImageView(@NonNull Context context) {
+        this(context, null);
+    }
+
+    public ScalableImageView(@NonNull Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public ScalableImageView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+
+        post(() -> {
+            BitmapFactory.Options verticalOptions = new BitmapFactory.Options();
+            // verticalOptions.inJustDecodeBounds = true;
+            mVerticalBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.move_vertical, verticalOptions);
+            mVerticalRawWidth =  verticalOptions.outWidth;
+            mVerticalRawHeight = verticalOptions.outHeight;
+
+            BitmapFactory.Options horizontalOptions = new BitmapFactory.Options();
+            // verticalOptions.inJustDecodeBounds = true;
+            mHorizontalBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.move_horizontal, horizontalOptions);
+            mHorizontalRawWidth =  horizontalOptions.outWidth;
+            mHorizontalRawHeight = horizontalOptions.outHeight;
+
+            setImageBitmap(mVerticalBitmap);
+            AnimateManager.getInstance().register(this);
+        });
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        AnimateManager.getInstance().unRegister();
+    }
+
+    private int width;
+    private int height;
+    @Override
+    public void setAnimateWidth(int w, int h, int left, int top, int right, int bottom) {
+        if (mVerticalRawWidth == 0) {
+            return;
+        }
+
+        setImageBitmap(mHorizontalBitmap);
+
+        width = (h * mHorizontalRawWidth)/ mHorizontalRawHeight;
+        this.height = h;
+        setMinimumWidth(width);
+        setMaxWidth(width);
+        setMinimumHeight(height);
+        setMaxHeight(height);
+//        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams();
+//        params.width = width;
+//        params.height = h;
+
+        startHorizontalAnimation(left, right-width, top);
+    }
+
+    @Override
+    public void setAnimateHeight(int w, int h, int left, int top, int right, int bottom) {
+        if (mVerticalRawWidth == 0) {
+            return;
+        }
+
+        setImageBitmap(mVerticalBitmap);
+
+        this.width = w;
+        height = (w * mVerticalRawHeight)/ mVerticalRawWidth;
+        setMinimumWidth(width);
+        setMaxWidth(width);
+        setMinimumHeight(height);
+        setMaxHeight(height);
+//        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams();
+//        params.width = w;
+//        params.height = height;
+
+        startVerticalAnimation(top, bottom-height, left);
+    }
+
+    private Animation animation;
+    private void startHorizontalAnimation(int startX, int endX, int y) {
+        setVisibility(VISIBLE);
+
+        if (animation != null) {
+            animation.cancel();
+        }
+        animation = new TranslateAnimation(startX, endX, y, y);
+        animation.setRepeatMode(INFINITE);
+        animation.setRepeatCount(INFINITE);
+        animation.setDuration(2000);
+        startAnimation(animation);
+    }
+
+    private void startVerticalAnimation(int startY, int endY, int x) {
+        setVisibility(VISIBLE);
+
+        if (animation != null) {
+            animation.cancel();
+        }
+        animation = new TranslateAnimation(x, x, startY, endY);
+        animation.setRepeatMode(INFINITE);
+        animation.setRepeatCount(INFINITE);
+        animation.setDuration(2000);
+        startAnimation(animation);
+    }
+
+    @Override
+    public void stopTranslateAnimation() {
+        setVisibility(INVISIBLE);
+        if (animation != null) {
+            animation.cancel();
+        }
+    }
+}

+ 16 - 6
app/src/main/res/layout/activity_camera.xml

@@ -49,13 +49,23 @@
             android:layout_height="match_parent"
             android:orientation="vertical">
 
+            <FrameLayout
+                android:layout_width="wrap_content"
+                android:layout_height="0dp"
+                android:layout_weight="4">
+                <!--灰色遮罩-->
+                <com.miekir.ocr.widget.CropView
+                    android:id="@+id/pcv_scan"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"/>
 
-             <!--灰色遮罩-->
-             <com.miekir.ocr.widget.CropView
-                 android:id="@+id/pcv_scan"
-                 android:layout_width="match_parent"
-                 android:layout_height="0dp"
-                 android:layout_weight="4"/>
+                <com.miekir.ocr.widget.ScalableImageView
+                    android:id="@+id/iv_animation"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:visibility="invisible"
+                    android:scaleType="fitXY"/>
+            </FrameLayout>
 
             <View
                 android:layout_width="match_parent"

BIN
app/src/main/res/mipmap-xhdpi/move_horizontal.png


BIN
app/src/main/res/mipmap-xhdpi/move_vertical.png