Skip to content

Instantly share code, notes, and snippets.

@cesclong
Created March 19, 2021 03:04
Show Gist options
  • Save cesclong/c68890c0e4a6057405c6caf789368c97 to your computer and use it in GitHub Desktop.
Save cesclong/c68890c0e4a6057405c6caf789368c97 to your computer and use it in GitHub Desktop.
滑动返回View
import android.annotation.SuppressLint;
import android.app.Instrumentation;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.support.v4.graphics.ColorUtils;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.FrameLayout;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import mobi.mycrypto.common.util.RxUtil;
public class BackView extends View {
private static final int MAX_WIDTH = 200;
private static final int MAX_HEIGHT = 500;
private static final int MAX_COUNT = 1000;
private boolean mDrawEnable = false;
private PointF mDot1 = new PointF();
private PointF mDot2 = new PointF();
private PointF mDot3 = new PointF();
private PointF mDot4 = new PointF();
private PointF mDot5 = new PointF();
private PointF mArrowDot1 = new PointF();
private PointF mArrowDot2 = new PointF();
private PointF mArrowDot3 = new PointF();
private Path mPath = new Path();
private Path mArrowPath = new Path();
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint mArrowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public BackView(Context context) {
this(context, null);
}
public BackView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BackView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setWillNotDraw(false);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.FILL);
mArrowPaint.setColor(Color.WHITE);
mArrowPaint.setStrokeWidth(4);
mArrowPaint.setStyle(Paint.Style.STROKE);
}
public static void attachWindow(Window window) {
if (window == null) return;
if (window.getDecorView() instanceof FrameLayout) {
FrameLayout rootView = (FrameLayout) window.getDecorView();
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
BackView backView = new BackView(window.getContext());
backView.setLayoutParams(lp);
rootView.addView(backView);
}
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
float mDownX = event.getX();
float mDownY = event.getY();
if (mDownX < 20) {
mDrawEnable = true;
return true;
}
break;
case MotionEvent.ACTION_MOVE:
float mMoveX = event.getX();
float mMoveY = event.getY();
if (mDrawEnable) {
float moveX = mMoveX > MAX_WIDTH ? MAX_WIDTH : mMoveX;
mDot1.set(0, mMoveY - MAX_HEIGHT / 2);
mDot2.set(0, mMoveY - MAX_HEIGHT / 8);
mDot3.set(moveX, mMoveY);
mDot4.set(0, mMoveY + MAX_HEIGHT / 8);
mDot5.set(0, mMoveY + MAX_HEIGHT / 2);
drawBezier();
if (moveX <= MAX_WIDTH / 2) {
mArrowDot1.set(moveX / 6, mMoveY - 10 * 2 * moveX / MAX_WIDTH);
mArrowDot2.set(moveX / 6, mMoveY);
mArrowDot3.set(moveX / 6, mMoveY + 10 * 2 * moveX / MAX_WIDTH);
} else {
mArrowDot1.set(moveX / 6 + 10 * (2 * moveX / MAX_WIDTH - 1), mMoveY - 10);
mArrowDot2.set(moveX / 6, mMoveY);
mArrowDot3.set(moveX / 6 + 10 * (2 * moveX / MAX_WIDTH - 1), mMoveY + 10);
}
drawArrow();
return true;
}
break;
case MotionEvent.ACTION_UP:
if (mDot3.x >= MAX_WIDTH) {
RxUtil.fromRunnable(() -> {
Instrumentation instrumentation = new Instrumentation();
instrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
}).subscribe();
}
mDrawEnable = false;
invalidate();
return true;
case MotionEvent.ACTION_CANCEL:
mDrawEnable = false;
invalidate();
break;
}
return false;
}
private List<List<PointF>> buildDotPosition(float i) {
List<List<PointF>> allDotPosition = new ArrayList<>();
List<PointF> rowPosition;
allDotPosition.add(Arrays.asList(mDot1, mDot2, mDot3, mDot4, mDot5));
for (int j = 0; j < 5; j++) {
List<PointF> jPointFs = allDotPosition.get(j);
rowPosition = new ArrayList<>();
for (int k = 0; k < jPointFs.size(); k++) {
if (k != 0) {
float x = jPointFs.get(k).x;
float y = jPointFs.get(k).y;
float x1 = jPointFs.get(k - 1).x;
float y1 = jPointFs.get(k - 1).y;
float xOffset = Math.abs(x1 - x) * 1.0f * i / 1000;
float yOffset = Math.abs(y1 - y) * 1.0f * i / 1000;
float x2;
float y2;
if (x > x1) {
x2 = x1 + xOffset;
} else {
x2 = x1 - xOffset;
}
if (y > y1) {
y2 = y1 + yOffset;
} else {
y2 = y1 - yOffset;
}
rowPosition.add(new PointF(x2, y2));
}
}
if (rowPosition.size() != 0) {
allDotPosition.add(rowPosition);
}
}
return allDotPosition;
}
private void drawBezier() {
mPaint.setColor(ColorUtils.setAlphaComponent(Color.BLACK, (int) (0xFF * mDot3.x / MAX_WIDTH * 0.8)));
for (int i = 0; i < MAX_COUNT; i++) {
List<List<PointF>> mAllDotPosition = buildDotPosition(i);
List<PointF> pointFs = mAllDotPosition.get(mAllDotPosition.size() - 1);
PointF pointF = pointFs.get(pointFs.size() - 1);
if (i == 0) {
mPath.reset();
mPath.moveTo(pointF.x, pointF.y);
} else {
mPath.lineTo(pointF.x, pointF.y);
}
}
mPath.lineTo(mDot1.x, mDot1.y);
invalidate();
}
private void drawArrow() {
mArrowPaint.setColor(ColorUtils.setAlphaComponent(Color.WHITE, (int) (0xFF * mDot3.x / MAX_WIDTH)));
mArrowPath.reset();
mArrowPath.moveTo(mArrowDot1.x, mArrowDot1.y);
mArrowPath.lineTo(mArrowDot2.x, mArrowDot2.y);
mArrowPath.lineTo(mArrowDot3.x, mArrowDot3.y);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
if (mDrawEnable) {
canvas.drawPath(mPath, mPaint);
canvas.drawPath(mArrowPath, mArrowPaint);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment