android手势操作&&实现滑动切换activity

一、给view设置手势操作有2种方式:
1、自定义view并实现其ontouchevent,然后定制自己的监听手势
2、通过GestureDetector和touchlistener配合使用

主要介绍第二种方法:
GestureDetector是android提供的手势操作类
用法:GestureDetector g = new GestureDetector(Context contenxt,GestureListener gestureListener);
GestureListener 是GestureDetector 内部封装的一个接口,里面封装了一些手势操作方法。新建类实现该接口并将该对象传入GestureDetector构造方法。

 class MygestureListener implements GestureDetector.OnGestureListener{
        @Override
        public boolean onDown(MotionEvent motionEvent) {
            return false;
        }

        @Override
        public void onShowPress(MotionEvent motionEvent) {

        }

        @Override
        public boolean onSingleTapUp(MotionEvent motionEvent) {
            return false;
        }

        @Override
        public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
            return false;
        }

        @Override
        public void onLongPress(MotionEvent motionEvent) {

        }

        /**
         *
         * @param motionEvent 第一个action_down手势
         * @param motionEvent1 最后一个action_move手势
         * @param v x轴上的移动速度   像素/s
         * @param v1 y轴上的移动速度  像素/s
         * @return
         */
        @Override
        public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {

            return false;
        }
    }

然后我们给需要设置手势操作的view配置上GestureDetector

比如 view.setOnTouchListener(new onTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
if (g!=null){
return mGestureDetector.onTouchEvent(event);
}
return false;
}
});

就是给view的touch监听返回值设置为手势监听,这样对view的手势操作就会调用GestureListener中的方法。

二、实现跟随手指滑动的activity:
实现原理也是通过对手势的监听,然后根据手指滑动的距离进行activity切换,上面的GestureDetector不行,他不能时时的监听当前的坐标位置。
所以实现方法:实现activity的onTouchEvent方法。然后在里面监听手指移动的位置然后移动activity的decorview。
为什么要移动decorview?首先一个屏幕识图组成部分是由两个方面组成的:xml识图+actionbar,这2个识图都会被添加到decorview中,所以要想实现移动识图的效果就是去移动decorview。
DecorView dv = getWindow().getDecorView();
获取屏幕宽高:
// 获得手机屏幕的宽度和高度,单位像素
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;
然后在onTouchEvent方法中:

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN){// 当按下时
            // 获得按下时的X坐标
            downX = event.getX();

        }else if(event.getAction() == MotionEvent.ACTION_MOVE){// 当手指滑动时
            // 获得滑过的距离
            float moveDistanceX = event.getX() - downX;
            if(moveDistanceX > 0){// 如果是向右滑动
                decorView.setX(moveDistanceX); // 设置界面的X到滑动到的位置
            }

        }else if(event.getAction() == MotionEvent.ACTION_UP){// 当抬起手指时
            // 获得滑过的距离
            float moveDistanceX = event.getX() - downX;
            if(moveDistanceX > screenWidth / 2){
                 // 如果滑动的距离超过了手机屏幕的一半, 结束当前Activity
                finish();
            }else{ // 如果滑动距离没有超过一半
                // 恢复初始状态
                decorView.setX(0);
            }
        }
        return super.onTouchEvent(event);
    }

但是这样写的效果是识图可以移动,但是前一个activity并没有再后一个activity滑动时显示出来,所以要给activity设置透明背景:

<style name="window_no_background" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:colorBackgroundCacheHint">@null</item>
        <item name="android:windowIsTranslucent">true</item>
    </style>

这样activity就可以跟随手指滑动了,但是还有一个问题就是效果比较生硬。所以要给decorview移动设置属性动画:

从大于屏幕1/2的地方到屏幕的宽度:

/**
     * 从当前位置一直往右滑动到消失。
     * 这里使用了属性动画。
     */
    private void continueMove(float moveDistanceX){
        // 从当前位置移动到右侧。
        ValueAnimator anim = ValueAnimator.ofFloat(moveDistanceX, screenWidth);
        anim.setDuration(1000); // 一秒的时间结束, 为了简单这里固定为1秒
        anim.start();

        anim.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // 位移
                float x = (float) (animation.getAnimatedValue());
                decorView.setX(x); 
            }
        });

        // 动画结束时结束当前Activity
        anim.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationEnd(Animator animation) {
                finish();
            }

        });
    }

从小于屏幕1/2的地方到0:

 /**
     * Activity被滑动到中途时,滑回去~
     */
    private void rebackToLeft(float moveDistanceX){
        ObjectAnimator.ofFloat(decorView, "X", moveDistanceX, 0).setDuration(300).start();  
    }
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值