Activity右滑退出控件SlidingLayout

来源:互联网 发布:电子报刊手机制作软件 编辑:程序博客网 时间:2024/06/03 13:27

在Android开发中,我们可能会想使用和IOS一样右滑退出界面的效果,在这里,我为大家提供一种快速使用的控件-SlidingLayout下面是使用后的效果

右滑退出效果
SlidingLayout.java

public class SlidingLayout extends FrameLayout {    private static final int SHADOW_WIDTH = 16;    private Activity mActivity;    private Scroller mScroller;    private Drawable mLeftShadow;    private int mShadowWidth;    private int mInterceptDownX;    private int mLastInterceptX;    private int mLastInterceptY;    private int mTouchDownX;    private int mLastTouchX;    private int mLastTouchY;    private boolean isConsumed;    public SlidingLayout(Context context) {        this(context, (AttributeSet)null);    }    public SlidingLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public SlidingLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        this.isConsumed = false;        this.initView(context);    }    private void initView(Context context) {        this.mScroller = new Scroller(context);        this.mLeftShadow = this.getResources().getDrawable(R.drawable.left_shadow);        int density = (int)this.getResources().getDisplayMetrics().density;        this.mShadowWidth = 16 * density;    }    public void bindActivity(Activity activity) {        this.mActivity = activity;        ViewGroup decorView = (ViewGroup)this.mActivity.getWindow().getDecorView();        View child = decorView.getChildAt(0);        decorView.removeView(child);        this.addView(child);        decorView.addView(this);    }    public boolean onInterceptTouchEvent(MotionEvent ev) {        boolean intercept = false;        int x = (int)ev.getX();        int y = (int)ev.getY();        switch(ev.getAction()) {            case 0:                intercept = false;                this.mInterceptDownX = x;                this.mLastInterceptX = x;                this.mLastInterceptY = y;                break;            case 1:                intercept = false;                this.mInterceptDownX = this.mLastInterceptX = this.mLastInterceptY = 0;                break;            case 2:                int deltaX = x - this.mLastInterceptX;                int deltaY = y - this.mLastInterceptY;                if(this.mInterceptDownX < this.getWidth() / 10 && Math.abs(deltaX) > Math.abs(deltaY)) {                    intercept = true;                } else {                    intercept = false;                }                this.mLastInterceptX = x;                this.mLastInterceptY = y;        }        return intercept;    }    public boolean onTouchEvent(MotionEvent ev) {        int x = (int)ev.getX();        int y = (int)ev.getY();        switch(ev.getAction()) {            case 0:                this.mTouchDownX = x;                this.mLastTouchX = x;                this.mLastTouchY = y;                break;            case 1:                this.isConsumed = false;                this.mTouchDownX = this.mLastTouchX = this.mLastTouchY = 0;                if(-this.getScrollX() < this.getWidth() / 2) {                    this.scrollBack();                } else {                    this.scrollClose();                }                break;            case 2:                int deltaX = x - this.mLastTouchX;                int deltaY = y - this.mLastTouchY;                if(!this.isConsumed && this.mTouchDownX < this.getWidth() / 10 && Math.abs(deltaX) > Math.abs(deltaY)) {                    this.isConsumed = true;                }                if(this.isConsumed) {                    int rightMovedX = this.mLastTouchX - (int)ev.getX();                    if(this.getScrollX() + rightMovedX >= 0) {                        this.scrollTo(0, 0);                    } else {                        this.scrollBy(rightMovedX, 0);                    }                }                this.mLastTouchX = x;                this.mLastTouchY = y;        }        return true;    }    private void scrollBack() {        int startX = this.getScrollX();        int dx = -this.getScrollX();        this.mScroller.startScroll(startX, 0, dx, 0, 300);        this.invalidate();    }    private void scrollClose() {        int startX = this.getScrollX();        int dx = -this.getScrollX() - this.getWidth();        this.mScroller.startScroll(startX, 0, dx, 0, 300);        this.invalidate();    }    public void computeScroll() {        if(this.mScroller.computeScrollOffset()) {            this.scrollTo(this.mScroller.getCurrX(), 0);            this.postInvalidate();        } else if(-this.getScrollX() >= this.getWidth()) {            this.mActivity.finish();        }    }    protected void dispatchDraw(Canvas canvas) {        super.dispatchDraw(canvas);        this.drawShadow(canvas);    }    private void drawShadow(Canvas canvas) {        this.mLeftShadow.setBounds(0, 0, this.mShadowWidth, this.getHeight());        canvas.save();        canvas.translate((float)(-this.mShadowWidth), 0.0F);        this.mLeftShadow.draw(canvas);        canvas.restore();    }}

然后在使用的时候,放置在BaseActivity上

  @Override    public final void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);************        if (enableSlideClose()) {//右滑退出            SlidingLayout rootView = new SlidingLayout(this);            rootView.bindActivity(this);        }************ }

在BaseActivity上再写一个抽象方法

 public boolean enableSlideClose() {        return true;    }

默认使用右滑退出Activity
我们再使用的过程中,可以在子类中复写enableSlideClose()方法,设置不使用右滑退出
子类extends BaseActivity

  @Override    public boolean enableSlideClose() {        return false;    }

这样以后就可以右滑退出了

我们在使用过程中,可能会出现白色背景或者黑色背景闪现的可能性,这是由于未设置背景透明的原因,在这里,我们需要这样设置

  <!-- Base application theme. -->    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">        <!-- Customize your theme here. -->        <item name="colorPrimary">@color/colorPrimary</item>        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>        <item name="colorAccent">@color/colorAccent</item>    </style>    <!--右滑返回并退出Activity会有一个白色的背景出现,需要设置透明色-->    <style name="AppTheme.Slide" parent="@style/AppTheme">        <item name="android:windowBackground">@android:color/transparent</item>        <item name="android:windowIsTranslucent">true</item>        <item name="android:windowAnimationStyle">@style/AppTheme.Slide.Animation</item>    </style>    <style name="AppTheme.Slide.Animation" parent="@android:style/Animation.Activity">        <item name="android:activityOpenEnterAnimation">@anim/anim_slide_in</item>        <item name="android:activityOpenExitAnimation">@anim/anim_slide_out</item>        <item name="android:activityCloseEnterAnimation">@anim/anim_slide_in</item>        <item name="android:activityCloseExitAnimation">@anim/anim_slide_out</item>    </style>

anim_slide_in.xml

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android">    <translate        android:duration="300"        android:fromXDelta="100%p"        android:toXDelta="0" /></set>

anim_slide_out.xml

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android">    <translate        android:duration="300"        android:fromXDelta="0"        android:toXDelta="100%p" /></set>

在清单文件中这样配置

 <application        android:name=".app.AichebabaApplication"        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/AppTheme.Slide">

android:theme=”@style/AppTheme.Slide”
这样以后,就不会有其他白色背景或者黑色背景一闪而过的情况了。

注意:在设置

 <item name="android:windowIsTranslucent">true</item>

以后,这个Activity的栈中上一个Activity不会调用onRestart()方法,具体可以参考我的另一篇博客使用右滑退出界面时,onRestart()方法失效

原创粉丝点击