关闭

Activity侧滑退出

标签: app
185人阅读 评论(0) 收藏 举报
分类:

  最近看到几个APP上都有侧滑退出activity的功能,自己就尝试也写了一个。下面先看下代码。
  

public class ScrollHelper {

    private ValueAnimator valueAnimator;
    private ViewGroup rootView;
    private ViewGroup content;
    private ViewGroup contentParent;
    private int screenWidth;
    private float downX;
    private float downY;
    private Context mContext;
    private boolean isMove =  false;

    public ScrollHelper(final Activity mActivity){
        //这个是关键,将activity的背景设置为透明,滑动的时候才能露出下层界面。
        mActivity.setTheme(android.R.style.Theme_Translucent_NoTitleBar);
        mContext = mActivity;
        rootView = (ViewGroup) mActivity.findViewById(android.R.id.content);
        screenWidth = mActivity.getResources().getDisplayMetrics().widthPixels;
        //利用属性动画来使activity划出屏幕或者恢复原状。
        valueAnimator = new ValueAnimator();
        valueAnimator.setDuration(300);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int tempOffsetX = (int) animation.getAnimatedValue();
                content.setTranslationX(tempOffsetX);

                if(tempOffsetX>=screenWidth){
                    mActivity.finish();
                }
            }
        });
    }

    //这个方法要在activity中的dispatchTouchEvent中调用
    public boolean dispatchTouchEvent(MotionEvent ev) {

        if(rootView!=null){
            content = (ViewGroup) rootView.getChildAt(0);
        }

        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:

                downX = ev.getX();
                downY = ev.getY();

                break;
            case MotionEvent.ACTION_MOVE:
                float nowX = ev.getX();
                float nowY = ev.getY();
                float diffX = Math.abs(nowX-downX);
                float diffY = Math.abs(nowY-downY);
                if((diffX>diffY)&&(downX<dp2px(50))){
                    content.setTranslationX(ev.getX());
                    isMove = true;
                }

                break;
            case MotionEvent.ACTION_UP:
                //设置当滑动超过屏幕宽度的1/3时,将view划出屏幕。
                if(ev.getX()>screenWidth/3){
                    valueAnimator.setIntValues((int)ev.getX(),screenWidth);
                }else{
                    //不到1/3则恢复原状。
                    valueAnimator.setIntValues((int)ev.getX(),0);
                }
                if(isMove){
                    valueAnimator.start();
                    isMove = false;
                }
                break;
        }
        return true;
    }

    public int dp2px(float dpVal){
        return (int)(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal,
               mContext.getResources().getDisplayMetrics()));
    }
}

  大致说下思路。这个类是一个侧滑退出的助手类,在构造方法中传入需要用侧滑退出功能的activity对象。接着将该activity的theme设置为Theme_Translucent_NoTitleBar,这部是将activity的背景设置为透明,以便滑动的时候能看到下层的界面。然后创建一个属性动画,目的是为了处理界面在UP事件后是复原还是退出,具体逻辑在添加的动画数值监听器中处理,annimateValue达到或者大于屏幕宽度时,退出Activty.
  接下来说下dispatchTouchEvent这个方法。这个方法要在activity的dispatchTouchEvent方法中执行,并将事件作为参数传递进来。在方法开始先通过之前的rootView拿到第一个子view,接下来的移动操作都是针对这个view来进行。在ACTION_DOWN事件中,记录下按下去的xy坐标。在ACTION_MOVE事件中,再用两个变量来记录当前的xy坐标。然后通过X方向和Y方向的坐标差的绝对值来判断左右滑动还是上下滑动,还有就是down事件中的坐标x必须在左边缘的某个数值范围内(这里我设定的是50),才判断是view可滑动,然后将isMove标志位设置为true,调用view的setTranslationX方法来进行移动。最后在UP事件中做判断,如果此时的X坐标大于屏幕的宽的某个比例(此处我设定的是1/3),就将动画的终点值设置为屏幕的宽(划出屏幕),否则设置为0(恢复原状).接下来要注意的是一定要在isMove这个标记位为true在执行动画的start操作,否则单纯的点击事件也会触发动画效果。
  以上就是这个侧滑的退出的代码以及大致思路。但这个没有应用的实际场景之中,可能会存在一定的问题,目前有可能存在的问题就是事件的冲突问题,等到以后实际用到的时候再加以完善。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1709次
    • 积分:48
    • 等级:
    • 排名:千里之外
    • 原创:3篇
    • 转载:0篇
    • 译文:0篇
    • 评论:3条
    文章分类
    文章存档
    最新评论