导航菜单

页面标题

页面副标题

BodyTech v7.6.4 - SignatureView.java 源代码

正在查看: BodyTech v7.6.4 应用的 SignatureView.java JAVA 源代码文件

本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。


package com.mindbodyonline.android.views;

import android.R;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.ColorInt;
import androidx.annotation.FloatRange;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import com.mindbodyonline.android.util.TaskCallback;
import java.util.LinkedList;
import java.util.Locale;

public class SignatureView extends View {
    public static final int BEZIER = 3;
    private static final float DEFAULT_MAX_STROKE_WIDTH = 9.0f;
    private static final float DEFAULT_MAX_VELOCITY = 7.0f;
    private static final float DEFAULT_MIN_STROKE_WIDTH = 3.0f;
    private static final float DEFAULT_SMOOTHING_RATIO = 0.75f;
    private static final float DEFAULT_VELOCITY_FILTER_WEIGHT = 0.8f;
    public static final int LINE = 2;
    public static final int NONE = 0;
    public static final int POINT = 1;
    private Bitmap.Config bitmapConfig;
    private Bitmap canvasBitmap;
    private final Point[] collectedPoints;
    private Point connectingPoint;
    private Point control1;
    private Point control2;
    private int currentPointStatus;
    private final RectF dirtyRect;
    private Canvas drawCanvas;
    private final Point emptyPoint;
    private LinkedList<Point> freeList;
    private float halfStrokeWidth;
    private float lastTouchX;
    private float lastTouchY;
    private float lastVelocity;
    private float lastWidth;
    private float maxStrokeWidth;
    private float maxVelocity;
    private float minStrokeWidth;
    private Paint signaturePaint;
    private boolean signatureStarted;
    private TaskCallback<MotionEvent> signatureStartedCallback;
    private float smoothingRatio;
    private float velocityFilter;

    public static class Point {
        float a;
        float b;
        long c;

        public Point() {
        }

        public Point(float f, float f2, long j) {
            this.a = f;
            this.b = f2;
            this.c = j;
        }

        public static Point d(Point point, Point point2, Point point3) {
            return point3.e((point.a + point2.a) / 2.0f, (point.b + point2.b) / 2.0f, Math.max(point.c, point2.c));
        }

        public Point e(float f, float f2, long j) {
            this.a = f;
            this.b = f2;
            this.c = j;
            return this;
        }

        public Point f(Point point) {
            this.a = point.a;
            this.b = point.b;
            this.c = point.c;
            return this;
        }

        public float c(Point point) {
            float f = this.a - point.a;
            float f2 = this.b - point.b;
            return (float) Math.sqrt((f * f) + (f2 * f2));
        }

        public float g(Point point) {
            return c(point) / (this.c - point.c);
        }

        @NonNull
        public String toString() {
            return String.format(Locale.US, "Point{ x=%f, y=%f, time=%d'}", Float.valueOf(this.a), Float.valueOf(this.b), Long.valueOf(this.c));
        }
    }

    public SignatureView(Context context) {
        super(context);
        this.dirtyRect = new RectF();
        this.collectedPoints = new Point[3];
        this.emptyPoint = new Point(0.0f, 0.0f, 0L);
        this.minStrokeWidth = DEFAULT_MIN_STROKE_WIDTH;
        this.maxStrokeWidth = DEFAULT_MAX_STROKE_WIDTH;
        this.halfStrokeWidth = 4.5f;
        this.maxVelocity = DEFAULT_MAX_VELOCITY;
        this.velocityFilter = DEFAULT_VELOCITY_FILTER_WEIGHT;
        this.smoothingRatio = DEFAULT_SMOOTHING_RATIO;
        this.bitmapConfig = Bitmap.Config.ARGB_8888;
        init(null);
    }

    private void addFreePoints(Point... pointArr) {
        if (pointArr != null) {
            for (Point point : pointArr) {
                if (point != null && !this.freeList.contains(point)) {
                    this.freeList.add(point);
                }
            }
        }
    }

    private void addPoint(Point point) {
        if (getLastPoint().c >= point.c) {
            return;
        }
        updateWithPoint(point);
        int i = this.currentPointStatus;
        if (i == 2) {
            Point[] pointArr = this.collectedPoints;
            float min = Math.min(Math.max(pointArr[0].g(pointArr[1]), 0.0f), this.maxVelocity);
            this.lastVelocity = min;
            this.lastWidth = strokeWidth(min);
            return;
        }
        if (i != 3) {
            return;
        }
        Point point2 = this.connectingPoint;
        if (point2 == null) {
            point2 = this.collectedPoints[0];
        }
        Point point3 = point2;
        Point[] pointArr2 = this.collectedPoints;
        Point point4 = pointArr2[2];
        calculateControlPoints(point3, pointArr2[1], point4);
        Point d = Point.d(this.control2, point4, getFreePoint());
        float min2 = Math.min(Math.max(d.g(point3), 0.0f), this.maxVelocity);
        float f = this.velocityFilter;
        float f2 = ((1.0f - f) * min2) + (f * this.lastVelocity);
        float strokeWidth = strokeWidth(f2);
        checkCanvas();
        drawBezier(this.drawCanvas, this.signaturePaint, this.lastWidth, strokeWidth, point3, this.control1, this.control2, d);
        this.connectingPoint = getFreePoint().f(d);
        addFreePoints(this.control1, this.control2);
        this.lastVelocity = f2;
        this.lastWidth = strokeWidth;
    }

    private void calculateControlPoints(Point point, Point point2, Point point3) {
        Point freePoint = getFreePoint();
        float f = this.smoothingRatio;
        this.control1 = freePoint.e(((1.0f - f) * point.a) + (point2.a * f), ((1.0f - f) * point.b) + (f * point2.b), Math.max(point.c, point2.c));
        Point freePoint2 = getFreePoint();
        float f2 = this.smoothingRatio;
        this.control2 = freePoint2.e(((1.0f - f2) * point3.a) + (point2.a * f2), ((1.0f - f2) * point3.b) + (f2 * point2.b), Math.max(point2.c, point3.c));
    }

    private void checkCanvas() {
        if (this.canvasBitmap == null) {
            this.canvasBitmap = Bitmap.createBitmap(getWidth(), getHeight(), this.bitmapConfig);
            this.drawCanvas = new Canvas(this.canvasBitmap);
        }
    }

    private void clearPoints() {
        Point[] pointArr = this.collectedPoints;
        addFreePoints(this.control1, this.control2, this.connectingPoint, pointArr[0], pointArr[1], pointArr[2]);
        this.lastTouchX = 0.0f;
        this.lastTouchY = 0.0f;
        this.lastVelocity = 0.0f;
        this.lastWidth = 0.0f;
        this.signaturePaint.setStrokeWidth(this.minStrokeWidth);
        this.currentPointStatus = 0;
    }

    private void drawBezier(Canvas canvas, Paint paint, float f, float f2, Point point, Point point2, Point point3, Point point4) {
        float f3 = f2 - this.lastWidth;
        for (float f4 = 0.0f; f4 < 1.0f; f4 += 0.01f) {
            float f5 = f4 * f4;
            float f6 = f5 * f4;
            float f7 = 1.0f - f4;
            float f10 = f7 * f7;
            float f11 = f10 * f7;
            float f12 = point.a * f11;
            float f13 = f10 * DEFAULT_MIN_STROKE_WIDTH * f4;
            float f14 = f12 + (point2.a * f13);
            float f15 = f7 * DEFAULT_MIN_STROKE_WIDTH * f5;
            float f16 = f14 + (point3.a * f15) + (point4.a * f6);
            float f17 = (f11 * point.b) + (f13 * point2.b) + (f15 * point3.b) + (f6 * point4.b);
            paint.setStrokeWidth(f + (f4 * f3));
            canvas.drawPoint(f16, f17, paint);
        }
    }

    private void drawLine(Canvas canvas, Paint paint, Point point, Point point2) {
        canvas.drawLine(point.a, point.b, point2.a, point2.b, paint);
    }

    private void drawPoint(Canvas canvas, Paint paint, Point point) {
        paint.setStrokeWidth(this.maxStrokeWidth);
        canvas.drawPoint(point.a, point.b, paint);
    }

    private void expandDirtyRect(float f, float f2) {
        RectF rectF = this.dirtyRect;
        if (f < rectF.left) {
            rectF.left = f;
        } else if (f > rectF.right) {
            rectF.right = f;
        }
        if (f2 < rectF.top) {
            rectF.top = f2;
        } else if (f2 > rectF.bottom) {
            rectF.bottom = f2;
        }
    }

    private Point getFreePoint() {
        return this.freeList.size() > 0 ? this.freeList.pop() : new Point();
    }

    private Point getLastPoint() {
        int i = this.currentPointStatus;
        return i == 0 ? this.emptyPoint : this.collectedPoints[i - 1];
    }

    private void resetDirtyRect(float f, float f2) {
        this.dirtyRect.left = Math.min(this.lastTouchX, f);
        this.dirtyRect.right = Math.max(this.lastTouchX, f);
        this.dirtyRect.top = Math.min(this.lastTouchY, f2);
        this.dirtyRect.bottom = Math.max(this.lastTouchY, f2);
    }

    private float strokeWidth(float f) {
        float f2 = this.maxStrokeWidth;
        return f2 - ((f2 - this.minStrokeWidth) * Math.min(f / this.maxVelocity, 1.0f));
    }

    private void updateWithPoint(Point point) {
        int i = this.currentPointStatus;
        if (i == 0) {
            this.collectedPoints[0] = getFreePoint().f(point);
            this.currentPointStatus = 1;
            return;
        }
        if (i == 1) {
            this.collectedPoints[1] = getFreePoint().f(point);
            this.currentPointStatus = 2;
            return;
        }
        if (i == 2) {
            this.collectedPoints[2] = getFreePoint().f(point);
            this.currentPointStatus = 3;
        } else {
            if (i != 3) {
                return;
            }
            Point[] pointArr = this.collectedPoints;
            pointArr[0].f(pointArr[1]);
            Point[] pointArr2 = this.collectedPoints;
            pointArr2[1].f(pointArr2[2]);
            this.collectedPoints[2].f(point);
            addFreePoints(point);
        }
    }

    public void clearSignature() {
        this.signatureStarted = false;
        this.drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
        clearPoints();
        invalidate();
    }

    public Bitmap.Config getBitmapConfig() {
        return this.bitmapConfig;
    }

    public float getMaxStrokeWidth() {
        return this.maxStrokeWidth;
    }

    public float getMaxVelocity() {
        return this.maxVelocity;
    }

    public float getMinStrokeWidth() {
        return this.minStrokeWidth;
    }

    public float getSmoothingRatio() {
        return this.smoothingRatio;
    }

    public float getVelocityFilter() {
        return this.velocityFilter;
    }

    public boolean hasSignature() {
        return this.signatureStarted;
    }

    public void init(AttributeSet attributeSet) {
        int color = ContextCompat.getColor(getContext(), R.color.black);
        if (attributeSet != null) {
            TypedArray obtainStyledAttributes = getContext().getTheme().obtainStyledAttributes(attributeSet, f.S, 0, 0);
            try {
                color = obtainStyledAttributes.getColor(f.T, color);
            } finally {
                obtainStyledAttributes.recycle();
            }
        }
        Paint paint = new Paint();
        this.signaturePaint = paint;
        paint.setAntiAlias(true);
        this.signaturePaint.setStyle(Paint.Style.STROKE);
        this.signaturePaint.setStrokeJoin(Paint.Join.ROUND);
        this.signaturePaint.setStrokeWidth(this.minStrokeWidth);
        this.signaturePaint.setColor(color);
        this.freeList = new LinkedList<>();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(this.canvasBitmap, 0.0f, 0.0f, this.signaturePaint);
    }

    @Override
    protected void onSizeChanged(int i, int i2, int i3, int i4) {
        super.onSizeChanged(i, i2, i3, i4);
        this.canvasBitmap = Bitmap.createBitmap(i, i2, this.bitmapConfig);
        this.drawCanvas = new Canvas(this.canvasBitmap);
    }

    @Override
    @SuppressLint({"ClickableViewAccessibility"})
    public boolean onTouchEvent(MotionEvent motionEvent) {
        TaskCallback<MotionEvent> taskCallback;
        float x = motionEvent.getX();
        float y = motionEvent.getY();
        int action = motionEvent.getAction();
        if (action == 0) {
            getParent().requestDisallowInterceptTouchEvent(true);
            addPoint(getFreePoint().e(x, y, motionEvent.getEventTime()));
            this.lastTouchX = x;
            this.lastTouchY = y;
            resetDirtyRect(x, y);
            return true;
        }
        if (action != 1) {
            if (action == 2) {
                if (!this.signatureStarted && (taskCallback = this.signatureStartedCallback) != null) {
                    taskCallback.a(motionEvent);
                    this.signatureStarted = true;
                }
                int historySize = motionEvent.getHistorySize();
                for (int i = 0; i < historySize; i++) {
                    float historicalX = motionEvent.getHistoricalX(i);
                    float historicalY = motionEvent.getHistoricalY(i);
                    expandDirtyRect(historicalX, historicalY);
                    addPoint(getFreePoint().e(historicalX, historicalY, motionEvent.getHistoricalEventTime(i)));
                }
                addPoint(getFreePoint().e(x, y, motionEvent.getEventTime()));
                RectF rectF = this.dirtyRect;
                float f = rectF.left;
                float f2 = this.halfStrokeWidth;
                invalidate((int) (f - f2), (int) (rectF.top - f2), (int) (rectF.right + f2), (int) (rectF.bottom + f2));
                this.lastTouchX = x;
                this.lastTouchY = y;
                return true;
            }
            if (action != 3) {
                return false;
            }
        }
        getParent().requestDisallowInterceptTouchEvent(false);
        expandDirtyRect(x, y);
        addPoint(getFreePoint().e(x, y, motionEvent.getEventTime()));
        if (this.currentPointStatus == 2) {
            checkCanvas();
            drawPoint(this.drawCanvas, this.signaturePaint, this.collectedPoints[1]);
        }
        clearPoints();
        RectF rectF2 = this.dirtyRect;
        float f3 = rectF2.left;
        float f22 = this.halfStrokeWidth;
        invalidate((int) (f3 - f22), (int) (rectF2.top - f22), (int) (rectF2.right + f22), (int) (rectF2.bottom + f22));
        this.lastTouchX = x;
        this.lastTouchY = y;
        return true;
    }

    public void setBitmapConfig(Bitmap.Config config) {
        this.bitmapConfig = config;
    }

    public void setForegroundColor(@ColorInt int i) {
        this.signaturePaint.setColor(i);
        invalidate();
    }

    public void setMaxStrokeWidth(@FloatRange(from = 0.0d) float f) {
        this.maxStrokeWidth = f;
        this.halfStrokeWidth = f / 2.0f;
    }

    public void setMaxVelocity(@FloatRange(from = 0.0d) float f) {
        this.maxVelocity = f;
    }

    public void setMinStrokeWidth(@FloatRange(from = 0.0d) float f) {
        this.minStrokeWidth = f;
    }

    public void setSignatureStartedCallback(TaskCallback<MotionEvent> taskCallback) {
        this.signatureStartedCallback = taskCallback;
    }

    public void setSmoothingRatio(@FloatRange(from = 0.0d, to = 1.0d) float f) {
        this.smoothingRatio = f;
    }

    public void setVelocityFilter(@FloatRange(from = 0.0d, to = 1.0d) float f) {
        this.velocityFilter = f;
    }

    public SignatureView(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        this.dirtyRect = new RectF();
        this.collectedPoints = new Point[3];
        this.emptyPoint = new Point(0.0f, 0.0f, 0L);
        this.minStrokeWidth = DEFAULT_MIN_STROKE_WIDTH;
        this.maxStrokeWidth = DEFAULT_MAX_STROKE_WIDTH;
        this.halfStrokeWidth = 4.5f;
        this.maxVelocity = DEFAULT_MAX_VELOCITY;
        this.velocityFilter = DEFAULT_VELOCITY_FILTER_WEIGHT;
        this.smoothingRatio = DEFAULT_SMOOTHING_RATIO;
        this.bitmapConfig = Bitmap.Config.ARGB_8888;
        init(attributeSet);
    }

    public SignatureView(Context context, AttributeSet attributeSet, int i) {
        super(context, attributeSet, i);
        this.dirtyRect = new RectF();
        this.collectedPoints = new Point[3];
        this.emptyPoint = new Point(0.0f, 0.0f, 0L);
        this.minStrokeWidth = DEFAULT_MIN_STROKE_WIDTH;
        this.maxStrokeWidth = DEFAULT_MAX_STROKE_WIDTH;
        this.halfStrokeWidth = 4.5f;
        this.maxVelocity = DEFAULT_MAX_VELOCITY;
        this.velocityFilter = DEFAULT_VELOCITY_FILTER_WEIGHT;
        this.smoothingRatio = DEFAULT_SMOOTHING_RATIO;
        this.bitmapConfig = Bitmap.Config.ARGB_8888;
        init(attributeSet);
    }
}