Android 侧边滑动关闭Activity的示例代码

时间:2022-07-26
本文章向大家介绍Android 侧边滑动关闭Activity的示例代码,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

0.效果图

1.设置Activity样式属性

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar" 
    <item name="android:windowIsTranslucent" true</item 
</style 

2.自定义侧边阴影视图

class SlideBackView extends View {

    private Paint mBgPaint, mShadowPaint;
    private RectF mBgRectF, mShadowRectF;
    private float mRatio;
    private float mShadowSize;

    public SlideBackView(Context context) {
      super(context);
      mBgPaint = new Paint();
      mBgPaint.setAntiAlias(true);
      mBgPaint.setColor(0xff000000);
      mShadowPaint = new Paint();
      mShadowPaint.setAntiAlias(true);
      mShadowPaint.setStyle(Paint.Style.FILL);
      mShadowSize = dp2px(15);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
      mBgRectF = new RectF();
      mBgRectF.top = 0;
      mBgRectF.left = 0;
      mBgRectF.bottom = MeasureSpec.getSize(heightMeasureSpec);

      mShadowRectF = new RectF();
      mShadowRectF.top = 0;
      mShadowRectF.bottom = MeasureSpec.getSize(heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      super.onDraw(canvas);
      int width = getMeasuredWidth();
      float right = mRatio * width;
      mBgRectF.right = right;
      mBgPaint.setAlpha((int) (128 * (1 - mRatio)));
      canvas.drawRect(mBgRectF, mBgPaint);
      mShadowRectF.left = right - mShadowSize;
      mShadowRectF.right = right;
      mShadowPaint.setShader(new LinearGradient(mShadowRectF.left, 0, mShadowRectF.right, 0, 0x00000000, 0x26000000, Shader.TileMode.CLAMP));
      canvas.drawRect(mShadowRectF, mShadowPaint);
    }

    public void setDistance(float ratio) {
      mRatio = ratio;
      invalidate();
    }

    private float dp2px(float dpValue) {
      float density = getResources().getDisplayMetrics().density;
      return dpValue * density + 0.5F;
    }
  }

3.定义可滑动的Activity父类

public class SlideBaseActivity extends AppCompatActivity implements ValueAnimator.AnimatorUpdateListener {
private boolean isAnimate, isSlide, isHandle;
private float moveNum;
private float lastX, lastY;
private int lastPointerCount;
private float mAnimatedValue;
private ValueAnimator mValueAnimator;
private SlideBackView mSlideBackView;
private float mTouchSlop;
private List<ShieldView  shieldViews = new ArrayList< ();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
super.onCreate(savedInstanceState);
initAnimator();
initSlideBackView();
mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mAnimatedValue = (float) animation.getAnimatedValue();
moveView(mAnimatedValue);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (!isAnimate) {
float x = event.getRawX();
float y = event.getRawY();
if (event.getPointerCount() != lastPointerCount) {
lastPointerCount = event.getPointerCount();
lastX = x;
lastY = y;
}
float offsetX, offsetY;
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
offsetX = x - lastX;
offsetY = y - lastY;
if (!isHandle) {
float absX = Math.abs(offsetX);
float absY = Math.abs(offsetY);
if (absX   mTouchSlop) {
if (absX * 0.5f   absY) {
isSlide = true;
checkSlide((int) x, (int) y);
} else {
isSlide = false;
}
isHandle = true;
}
} else if (isSlide) {
moveNum += offsetX;
if (moveNum < 0) {
moveNum = 0;
}
moveView(moveNum);
lastX = event.getX();
}
break;
case MotionEvent.ACTION_UP:
if (isHandle) {
isSlide = false;
isHandle = false;
isAnimate = true;
int width = getWindow().getDecorView().getMeasuredWidth();
if (moveNum < width / 3f) {
mValueAnimator.setFloatValues(moveNum, 0);
} else {
mValueAnimator.setFloatValues(moveNum, width);
}
mValueAnimator.start();
moveNum = 0;
lastPointerCount = 0;
}
}
}
return isSlide || super.dispatchTouchEvent(event);
}
/**
* 添加禁用滑动的子布局
*/
public void addShieldView(View view) {
shieldViews.add(new ShieldView(false, view));
}
/**
* 添加水平禁用滑动的子布局
*/
public void addHorizontalShieldView(View view) {
shieldViews.add(new ShieldView(true, view));
}
/**
* 移除禁用滑动的子布局
*/
public void removeShieldView(View view) {
for (ShieldView v : shieldViews) {
if (v.view != null && v.view.equals(view)) {
shieldViews.remove(v);
break;
}
}
}
/**
* 清空禁用滑动的子布局
*/
public void clearShieldView() {
shieldViews.clear();
}
private void initAnimator() {
mValueAnimator = new ValueAnimator();
mValueAnimator.setDuration(300);
mValueAnimator.addUpdateListener(this);
mValueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
isAnimate = false;
if (mAnimatedValue == getWindow().getDecorView().getMeasuredWidth()) {
SlideBaseActivity.super.finish();
overridePendingTransition(0, 0);
}
}
});
}
private void initSlideBackView() {
mSlideBackView = new SlideBackView(this);
ViewGroup decorView = (ViewGroup) getWindow().getDecorView();
decorView.addView(mSlideBackView);
}
private void moveView(float moveX) {
ViewGroup decorView = (ViewGroup) getWindow().getDecorView();
mSlideBackView.setDistance(moveX / decorView.getMeasuredWidth());
int count = decorView.getChildCount();
for (int i = 0; i < count; i++) {
View view = decorView.getChildAt(i);
if (view != mSlideBackView) {
view.setX(moveX);
}
}
}
private void checkSlide(int x, int y) {
for (ShieldView v : shieldViews) {
Rect rect = new Rect();
v.view.getGlobalVisibleRect(rect);
if (rect.contains(x, y) && (!(lastX < x && !v.view.canScrollHorizontally(-1)) || (!v.isHorizontal))) {
isSlide = false;
}
}
}
class ShieldView {
boolean isHorizontal;
View view;
public ShieldView(boolean isHorizontal, View view) {
this.isHorizontal = isHorizontal;
this.view = view;
}
}
}

4.使用

继承SlideBaseActivity类,可调用addShieldViewaddHorizontalShieldView方法解决事件冲突。

5.项目源码

https://gitee.com/yugu/slide-demo

总结

到此这篇关于Android 侧边滑动关闭Activity的文章就介绍到这了,更多相关Android 侧边滑动关闭Activity内容请搜索ZaLou.Cn以前的文章或继续浏览下面的相关文章希望大家以后多多支持ZaLou.Cn!