涉及关键类
SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
SystemUI/src/com/android/systemui/navigationbar/
ges
tural/BackPanelController.kt
修改如下:
一,覆盖系统的默认手势效果
SystemUI/src/com/android/systemui/navigationbar/ges
tural/BackPanelController.kt
Kotlin
//start add code
private var slideBackView: SlideBackView? = null
//end add code
override fun setLayoutParams(layoutParams: WindowManager.LayoutParams) {
this.layoutParams = layoutParams
//start add code
slideBackView = SlideBackView(context, miShadeController)
windowManager.addView(slideBackView, layoutParams)
//end add code
}
Kotlin
override fun onMotionEvent(event: MotionEvent) {
//start add code
if (slideBackView?.onTouchEventList(event) == true) return
//end add code
。。。。
}
二、实现手势动画效果
SlideBackView.java 手势动画效果
java
package com.android.systemui.navigationbar.gestural;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.ActivityTaskManager;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.Arrays;
import java.util.List;
public class SlideBackView extends View {
private static final int UN = -1;
private static final int LEFT = 0;
private static final int RIGHT = 1;
private static final int MAX_WIDTH = 60;
private static final int THRESHOLD = 50;
private float startX = 0f;
private float downX = 0f;
private float moveX = 0f;
private float moveY = 0f;
private float upX = 0f;
private float distanceX = 0f;
private float speed = 0.5f;
private int showType = UN;
Path cubicPath;
Paint wavePaint;
private ValueAnimator valueAnimator;
private Path arrowPath;
private Paint arrowPaint;
private static final int ARROW_SIZE = 8;
private static final int SLIDE_HEIGHT = 400;
private MiShadeController controller;
public SlideBackView(Context context, MiShadeController controller) {
this(context, null,controller);
}
public SlideBackView(Context context, AttributeSet attrs, MiShadeController controller) {
super(context, attrs);
this.controller=controller;
init();
}
private void init() {
cubicPath = new Path();
arrowPath = new Path();
wavePaint = new Paint();
wavePaint.setColor(0x11000000);
wavePaint.setAntiAlias(true); // 启用抗锯齿
arrowPaint = new Paint();
arrowPaint.setColor(Color.WHITE);
arrowPaint.setStyle(Paint.Style.STROKE);
arrowPaint.setAntiAlias(true); // 启用抗锯齿
arrowPaint.setStrokeWidth(2);
valueAnimator = ObjectAnimator.ofFloat(1, 0);
valueAnimator.setDuration(500);
valueAnimator.addUpdateListener(animation -> {
distanceX = distanceX * (Float) animation.getAnimatedValue();
postInvalidate();
});
}
private boolean isReachThreshold() {
return startX < THRESHOLD || startX > getMeasuredWidth() - THRESHOLD;
}
private void initSlideDirection() {
if (startX < THRESHOLD) {
showType = LEFT;
} else if (startX > getMeasuredWidth() - THRESHOLD) {
showType = RIGHT;
} else {
showType = UN;
}
}
private boolean isHideBackView = false;
public boolean onTouchEventList(MotionEvent event){
if (valueAnimator.isRunning()) return false;
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
startX = downX = event.getX();
if (!isReachThreshold()) {
showType = UN;
return false;
}
initSlideDirection();
} else if (action == MotionEvent.ACTION_MOVE) {
if (!isReachThreshold()) {
showType = UN;
return false;
}
moveX = event.getX();
moveY = event.getY();
distanceX = moveX - downX;
postInvalidate();
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
if (!isReachThreshold()) {
showType = UN;
return false;
}
upX = event.getX();
distanceX = upX - downX;
handUpEvent();
}
return false;
}
private void handUpEvent() {
if (valueAnimator.isRunning()) {
valueAnimator.cancel();
}
valueAnimator.start();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (showType == UN) return;
// draw wave
cubicPath.reset();
int currentY = (int) Math.min(Math.max(SLIDE_HEIGHT/2f,moveY),getHeight()-SLIDE_HEIGHT/2f);
// 凸起上部Y
int topY = (int) (currentY - SLIDE_HEIGHT/2F);
// 凸起下部Y
int bottomY = (int) (currentY + SLIDE_HEIGHT/2F);
// 凸起底部X
int footX = showType == LEFT ? 0 : getWidth();
// 凸起顶部X
int peekX;
if (showType == LEFT) {
peekX = (int) (footX + Math.min(distanceX * speed, MAX_WIDTH));
} else {
peekX = (int) (footX - Math.min(Math.abs(distanceX) * speed, MAX_WIDTH));
}
int x1 = footX;
int y1 = (int) (topY + SLIDE_HEIGHT*0.2F);
int x2 = peekX;
int y2 = (int) (topY + SLIDE_HEIGHT*0.3F);
int x4 = peekX;
int y4 = (int) (bottomY - SLIDE_HEIGHT*0.3F);
int x5 = footX;
int y5 = (int) (bottomY - SLIDE_HEIGHT*0.2F);
cubicPath.moveTo(footX, topY);
cubicPath.cubicTo(x1, y1, x2, y2, peekX, currentY);
cubicPath.cubicTo(x4, y4, x5, y5, footX, bottomY);
cubicPath.close();
wavePaint.setAlpha((int) (Math.abs(distanceX) / MAX_WIDTH * 64));
canvas.drawPath(cubicPath, wavePaint);
arrowPath.reset();
if (showType == LEFT) {
float centerX = Math.min(distanceX * speed, MAX_WIDTH)/2F - 10;
arrowPath.moveTo(centerX+ARROW_SIZE , currentY - ARROW_SIZE);
arrowPath.lineTo(centerX, currentY);
arrowPath.lineTo(centerX+ ARROW_SIZE , currentY + ARROW_SIZE);
} else {
float centerX = peekX+Math.min(Math.abs(distanceX) * speed, MAX_WIDTH)/2F + 6;
arrowPath.moveTo(centerX + ARROW_SIZE, currentY - ARROW_SIZE);
arrowPath.lineTo(centerX, currentY);
arrowPath.lineTo(centerX + ARROW_SIZE, currentY + ARROW_SIZE);
}
canvas.drawPath(arrowPath, arrowPaint);
}
}
是不是很简单,但是很多兄弟看了很多文章 找了很多资料却始终找不到具体的修改位置,看我的一篇就够了 觉得我写的好的兄弟帮忙点个赞!!谢谢