可滑动的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();}@Overrideprotected 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();}@Overridepublic 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;@Overridepublic 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);    }}

    `

更多相关文章

  1. Android(安卓)RecyclerView使用 及 滑动时加载图片优化方案
  2. android view事件分发机制
  3. Android(安卓)开发 设置banner圆角,滑动时,图片圆角失效
  4. UI控件--自定义SeekBar样式
  5. Android实现图片左右滑动效果
  6. Android(安卓)拦截Home键的常用方法
  7. Android(安卓)OpenGL 文本显示 LabelMaker
  8. 暂时只会这种导航,实时显示自己的位置,,求其他更好的方法,或api
  9. android开发之修改ListView默认滑动条样式

随机推荐

  1. PHP trait 特性在 Laravel 中的使用个人
  2. PHP获取服务器端的相关信息
  3. IIS 8.5 伪静态去掉index.php thinkphp 3
  4. 如何使用Ajax或Jquery填充文本框中的值?
  5. PHP在PC端实现微信扫码支付模式二
  6. WS-Trust没有使用PHP进行身份验证
  7. 如果使用Select2 YII2选择第一个字段,请在
  8. 求助~~~php5.2.6装不上!
  9. 关于静态方法不能调用类中的非静态属性的
  10. 我无法以正确的方式放置最后一个div。而L