Created
March 19, 2021 03:04
-
-
Save cesclong/c68890c0e4a6057405c6caf789368c97 to your computer and use it in GitHub Desktop.
滑动返回View
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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