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
类,可调用addShieldView
或addHorizontalShieldView
方法解决事件冲突。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。