activity实现滑动效果

可滑动的activity

  • 可滑动的activity原理,就是将activity的theme设置为透明,之后滑动view的parent即可
  • 效果图

  • 主题透明

    android:theme="@android:style/Theme.Translucent.NoTitleBar"

  • 之后自定义一个SwipLayout 继承FrameLayout

    `public class SwipLayout extends FrameLayout {
    
    private View parent;
    
    public SwipLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    
        }
    
    
    public SwipLayout(Context context, AttributeSet attrs) {
        this(context, attrs,0);
        // TODO Auto-generated constructor stub
    }
    
    public SwipLayout(Context context) {
        this(context,null);
    
    }`
    
  • 之后我们拿到swiplayout的parent。因为我们使用scrollto,因此应该对父容器进行滚动

     `public void onWindowFocusChanged(boolean      hasWindowFocus) {
        // 在界面可以和用户交互的时候 并且第一次的时候 才进行初始化
        super.onWindowFocusChanged(hasWindowFocus);
        if(hasWindowFocus&&isFirst){
        isFirst=false;
        init();
        //拿到父容器  当window可见的时候
        }
        }
    
        private void init() {
        parent = (View) getParent();
        }
    

    `

  • 之后对相关事件进行拦截

        `public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            curX = (int) ev.getRawX();
            x=curX;
            break;
        case MotionEvent.ACTION_MOVE:
            int touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
            if(ev.getRawX()-curX>touchSlop)
            {   
    //              Log.e("", "actionMove");
                //小于触摸的范围就可以
                    if(ev.getRawX()<100)
                    return true;//拦截
                }
                break;
            }
            return super.onInterceptTouchEvent(ev);
        }`
    
  • 一定要使用屏幕坐标,否则会造成卡顿,因为我们在拿view的坐标的时候,view的位置也在改变
  • 在onTouchEvent中处理,拦截的事件即可

    `public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            x = (int) event.getRawX();//  要拿到屏幕的坐标
            break;
        case MotionEvent.ACTION_MOVE:
            int min=(int) (event.getRawX()-x);
    
            if(parent.getScrollX()<=0&&parent.getScrollX()>=-parent.getWidth())
            {parent.scrollTo(Math.min(Math.max(parent.getScrollX()-min, -parent.getWidth()), 0), 0);
            x=(int) event.getRawX();
            //一定获得屏幕的坐标  不要 相对坐标 否则会造成闪动
            return true;
            }
    
            break;
        case MotionEvent.ACTION_UP:
            if(parent.getScrollX()<-parent.getWidth()/2){
                //关闭
                colse();
            }else if(parent.getScrollX()>-parent.getWidth()/2){
                //打开
                open();
            }
            break;
    
    
        }
        return super.onTouchEvent(event);
    }`
    
  • 之后我们自定义了动画,完成关闭和开启

    `class ScrollAnimation extends Animation{
    private int end;
    private int lenght;
    private int start;
    public ScrollAnimation(int end) {
        this.end = end;
        lenght=end-parent.getScrollX();
        setDuration(Math.abs(lenght)/2);
        start=parent.getScrollX();
    }
    @Override
    protected void applyTransformation(float interpolatedTime,
            Transformation t) {
        // 0--100 1s
        //interpolatedTime 比例  0f-1f
        super.applyTransformation(interpolatedTime, t);
        int path=   (int) (interpolatedTime*lenght);
        int currentX=start+path;
        if(currentX>0)currentX=0;
        if(currentX<-parent.getWidth())currentX=-parent.getWidth();
        parent.scrollTo(currentX, 0);
    }
    
    }`
    
  • activity滑出右侧时候,接口回调

    `public interface onSwipCloseListener{
    public void onSwipClose();
    }
    public void setOnSwipCloseListener(onSwipCloseListener closeListener){
        this.swipCloseListener=closeListener;
    }`
    
  • swiplayout一定是顶层布局才生效
  • 总结,滑动的activity本质就是修改contentView的父容器 也就是修改id为content的FragmentLayout的子view
  • 源码如下

    `package com.example.swiplayout;
    
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.drawable.BitmapDrawable;
    import android.provider.ContactsContract.CommonDataKinds.Event;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewConfiguration;
    import android.view.ViewGroup;
    import android.view.ViewParent;
    import android.view.ViewPropertyAnimator;
    import android.view.WindowManager;
    import android.widget.FrameLayout;
    import android.view.View.OnTouchListener;
    import android.view.animation.Animation;
    import android.view.animation.Animation.AnimationListener;
    import android.view.animation.Transformation;
    
    public class SwipLayout extends FrameLayout {
    
    private View parent;
    
    public SwipLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    
        }
    
    
    public SwipLayout(Context context, AttributeSet attrs) {
        this(context, attrs,0);
        // TODO Auto-generated constructor stub
    }
    
    public SwipLayout(Context context) {
        this(context,null);
    
    }
    private void init() {
        parent = (View) getParent();
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            x = (int) event.getRawX();//  要拿到屏幕的坐标
            break;
        case MotionEvent.ACTION_MOVE:
            int min=(int) (event.getRawX()-x);
    
            if(parent.getScrollX()<=0&&parent.getScrollX()>=-parent.getWidth())
            {parent.scrollTo(Math.min(Math.max(parent.getScrollX()-min, -parent.getWidth()), 0), 0);
            x=(int) event.getRawX();
            //一定获得屏幕的坐标  不要 相对坐标 否则会造成闪动
            return true;
            }
    
        break;
    case MotionEvent.ACTION_UP:
        if(parent.getScrollX()<-parent.getWidth()/2){
            //关闭
            colse();
        }else if(parent.getScrollX()>-parent.getWidth()/2){
            //打开
            open();
        }
        break;
    
    
    }
    return super.onTouchEvent(event);
    }
    
    private void colse() {
        ScrollAnimation closeAnimation=new ScrollAnimation(-parent.getWidth());
        parent.startAnimation(closeAnimation);
        closeAnimation.setAnimationListener(new AnimationListenerAdapter(){
            @Override
            public void onAnimationEnd(Animation animation) {
                // TODO Auto-generated method stub
                super.onAnimationEnd(animation);
                if(swipCloseListener!=null){
                    swipCloseListener.onSwipClose();
                }
            }
        });
    }
    
    private void open() {
        ScrollAnimation open=new ScrollAnimation(0);
        parent.startAnimation(open);
    }
    
    boolean isFirst=true;
    private int x;
    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        // 在界面可以和用户交互的时候 并且第一次的时候 才进行初始化
        super.onWindowFocusChanged(hasWindowFocus);
        if(hasWindowFocus&&isFirst){
            isFirst=false;
            init();
            //拿到父容器  当window可见的时候
        }
    }
    class ScrollAnimation extends Animation{
        private int end;
        private int lenght;
        private int start;
        public ScrollAnimation(int end) {
            this.end = end;
            lenght=end-parent.getScrollX();
            setDuration(Math.abs(lenght)/2);
            start=parent.getScrollX();
        }
        @Override
        protected void applyTransformation(float interpolatedTime,
                Transformation t) {
            // 0--100 1s
            //interpolatedTime 比例  0f-1f
            super.applyTransformation(interpolatedTime, t);
            int path=   (int) (interpolatedTime*lenght);
            int currentX=start+path;
            if(currentX>0)currentX=0;
            if(currentX<-parent.getWidth())currentX=-parent.getWidth();
            parent.scrollTo(currentX, 0);
        }
    
    }
    private onSwipCloseListener swipCloseListener;
    private int curX;
    public interface onSwipCloseListener{
        public void onSwipClose();
    }
    public void setOnSwipCloseListener(onSwipCloseListener closeListener){
        this.swipCloseListener=closeListener;
    }
        //实现了一个animation适配器
        class AnimationListenerAdapter implements AnimationListener{
    
            @Override
            public void onAnimationStart(Animation animation) {
                // TODO Auto-generated method stub
    
            }
    
            @Override
            public void onAnimationEnd(Animation animation) {
                // TODO Auto-generated method stub
    
            }
    
            @Override
            public void onAnimationRepeat(Animation animation) {
                // TODO Auto-generated method stub
    
            }
    
        }
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                curX = (int) ev.getRawX();
                x=curX;
                break;
            case MotionEvent.ACTION_MOVE:
                int touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
                if(ev.getRawX()-curX>touchSlop)
                {   
    //              Log.e("", "actionMove");
                //小于触摸的范围就可以
                    if(ev.getRawX()<100)
                    return true;//拦截
                }
                break;
            }
            return super.onInterceptTouchEvent(ev);
        }
    
    
    
    }
    

    `

发布了33 篇原创文章 · 获赞 21 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/u013356254/article/details/50983473