Android 側(cè)邊滑動關(guān)閉Activity的示例代碼
0.效果圖

1.設(shè)置Activity樣式屬性
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
</style>
2.自定義側(cè)邊陰影視圖
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類,可調(diào)用addShieldView或addHorizontalShieldView方法解決事件沖突。
5.項目源碼
https://gitee.com/yugu/slide-demo
總結(jié)
到此這篇關(guān)于Android 側(cè)邊滑動關(guān)閉Activity的文章就介紹到這了,更多相關(guān)Android 側(cè)邊滑動關(guān)閉Activity內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android應(yīng)用開發(fā)中CardView的初步使用指南
這篇文章主要介紹了Android應(yīng)用開發(fā)中CardView的初步使用指南,CardView主要處理一些卡片型的視圖布局,需要的朋友可以參考下2016-02-02
Android自定義控件實現(xiàn)icon+文字的多種效果
這篇文章主要為大家詳細(xì)介紹了Android自定義控件實現(xiàn)icon+文字的多種效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01
Android studio 2020中的Android SDK 下載教程
這篇文章主要介紹了Android studio 2020中的Android SDK 下載教程,本文圖文并茂給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03
Android實現(xiàn)按鈕點擊事件的三種方法總結(jié)
Button是程序用于和用戶進(jìn)行交互的一個重要控件。既然有Button,那肯定有onClick方法,下面就教大家三種實現(xiàn)點擊事件的方法,感興趣的可以了解一下2022-04-04
Android新特性頁面之ViewPager拖拽到最后一頁再拖拽打開其他Activity(三種方法)
這篇文章主要介紹了Android新特性頁面之ViewPager拖拽到最后一頁再拖拽打開其他Activity的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-08-08
Android屏幕旋轉(zhuǎn) 處理Activity與AsyncTask的最佳解決方案
運行時變更就是設(shè)備在運行時發(fā)生變化(例如屏幕旋轉(zhuǎn)、鍵盤可用性及語言)。發(fā)生這些變化,Android會重啟Activity,這時就需要保存activity的狀態(tài)及與activity相關(guān)的任務(wù),以便恢復(fù)activity的狀態(tài)。為此,google提供了三種解決方案,本文將對這三種方案進(jìn)行逐一介紹。2016-12-12
Grow heap (frag case) 堆內(nèi)存過大的深入解析
本篇文章是對Grow heap (frag case) 堆內(nèi)存過大的問題進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
Android Socket接口實現(xiàn)即時通訊實例代碼
這篇文章主要介紹了Android Socket接口實現(xiàn)即時通訊實例代碼的相關(guān)資料,這里對通訊知識進(jìn)行了詳細(xì)介紹,并用Socket 接口實現(xiàn)通訊實例,需要的朋友可以參考下2016-12-12

