• View的滑动


    一、View的位置参数(都是相对于父容器的位置)

    1.View的位置由左上角点、右下角点来确定的。分别对应(左上的X—getLeft,左上的Y—getTop,右下的X—getRight,右下的Y—getBottom)。

    2.View的偏移量(translation):表示左上角相对于父容器的偏移量(当前位置与移动后的位置之差叫做偏移量),默认为0。(进过测试只能通过setTranslation改变Translation,补间动画animation.xml无效)通过getTransaltion获取X,Y

    3.View的getX(),getY()(都是左上角的点):X = left + translationX;就是左上角的X坐标加上X的偏移量,Y = top + translationY;(就是左上角Y的坐标,加上Y的偏移量)

    4.View的getScaleX(),getScaleY():View的内容的左上角的坐标。(向左滑动为正,向右滑动为负)

    解释:

    二、介绍VelocityTracker、GestureDetector、Scroller

    1.VelocityTrancker

    作用:速度追踪,用于追踪手指在滑动过程中的速度(包括水平和竖直方向速度)

    使用:①、将event事件添加至Velocity对象中   ②、设置时间:指一段时间划过的像素数  ③、获取X,Y方向滑过的像素数(从左向右为正,从上向下为正)

    实例:

    public class MainActivity extends AppCompatActivity {
        private static final String TAG = "MainActivity";
    
        private VelocityTracker mVelocityTracker = null;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //获取Velocity
            mVelocityTracker = VelocityTracker.obtain();
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            //将事件对象由该对象掌管
            mVelocityTracker.addMovement(event);
            switch (event.getAction()){
                case MotionEvent.ACTION_MOVE:
                    //设置时间间隔:速度指的是一段时间内手指划过的像素数
                    mVelocityTracker.computeCurrentVelocity(1000);
                    //打印速度
                    Log.d(TAG,"1秒内滑动X像素数"+mVelocityTracker.getXVelocity()+"  Y像素数"+mVelocityTracker.getYVelocity());
                    break;
                default:
                    break;
            }
            return super.onTouchEvent(event);
        }
    }
    MainActivity

    注意:当调用getXVelocity()方法的时候,就会返回平均速度。(假设我设置1喵,就是说不是等一秒过后才会,返回getXVelocioty(),而是当你调用getXVelocity()利用数学计算出每秒的速度)。

    2.GestureDetector

    作用:辅助检测用户的单击、滑动、长按、双击等行为(跟onTouchEvent好想没有区别)

    使用:①:实现onGestureDetecotr()接口   ②:创建GestureDetector对象   ③:将onTouchEvent的event事件给detector()对象

    实例:(每个接口的方法的作用都写在上面)

    //创建GestureDetector
    public class GestureTest extends Activity  {
        GestureDetector detector = null;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //第一步:用匿名类实现接口,供创建GestureDetector时候使用。
            GestureDetector.OnGestureListener gestureListener = new GestureDetector.OnGestureListener() {
                @Override
                public boolean onDown(MotionEvent e) {
                    //在屏幕按下时触发
                    return false;
                }
    
                @Override
                public void onShowPress(MotionEvent e) {
                    //在屏幕按下、未移动和松开时候触发
                }
    
                @Override
                public boolean onSingleTapUp(MotionEvent e) {
                    //在屏幕按下时触发
                    return false;
                }
    
                @Override
                public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                    //在屏幕滑动的时候触发
                    return false;
                }
    
                @Override
                public void onLongPress(MotionEvent e) {
                    //在屏幕长按的时候触发
                }
    
                @Override
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                    //Touch了滑动一点距离后,拿起手时触发。velocityX表示“拖过”动作在横向的速度,velocityY表示“拖过”动作在纵向时的速度
                    return false;
                }
            };
            //第二步:构造方法public GestureDetector(Context context,GestureDetector.OnGestureListener listener)
            detector = new GestureDetector(this,gestureListener);
    
            //解决长按屏幕后无法拖动的现象
            detector.setIsLongpressEnabled(false);
    
            //监听双击行为
            detector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
                //严格单击行为。和onSingleTapUp的区别。触发了onSingleTapConfirmed后不能再紧跟另一个单击行为
                @Override
                public boolean onSingleTapConfirmed(MotionEvent e) {
                    return false;
                }
                //双击,由两次连续的单击组成,不能和onSingleTapConfirmed共存
                @Override
                public boolean onDoubleTap(MotionEvent e) {
                    return false;
                }
                //发生双击行为,双击期间,DOWN、MOVE、UP都会触发此回调
                @Override
                public boolean onDoubleTapEvent(MotionEvent e) {
                    return false;
                }
            });
        }
    
        //第三步:重写Activity的onTouchEvent()方法,并将点击事件给GestureDetector处理
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            return detector.onTouchEvent(event);
        }
    }
    GestureTestActivity

    3.Scroller
    作用:实现View的弹性滑动

    使用:下一节详细讲解View的滑动

    三、View的滑动

    非弹性滑动

    1.使用scrollTo/scrollBy

    作用:使View的内容的滑动

    使用:①、View自带scrollTo/scrollBy方法 ②、scrollTo/scrollBy区别:scrollTo是相对于父控件位置的滑动。scrollBy是相对于上一scroll位置的滑动

      private Button btn;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            btn = (Button)findViewById(R.id.main_textView);
            btn.scrollTo(30,30);
            btn.scrollBy(50,50);
        }
    MainActivity

    注:根据源码其实scrollBy(int x,int y)调用scrollTo(int x,int y);(源码分析详见Android开发艺术探索P130)

    2.使用动画(AnimationDrawable  除开 属性动画)

    详见Drawable类及XMLDrawable的使用  :(只是View视图上的改变,并不改变View的点击位置  但是属性动画可以)

    弹性滑动:Scroller来实现有过度效果

    第一种:Scroller

    1.作用:实现滑动效果。(View内容的滑动)

    2.使用流程:创建Scroller对象,之后设定scroller的初始值,并进行重绘,在重绘之前需要重写computeScroll()方法,因为重绘的时候系统会自动调用该方法,在computeScroll()方法中,我们利用computeScrollOffset()方法获取当前应该移动的距离,并用scrollTo()进行移动。

      private Scroller mScroller;
        public TestLinearLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
            //创建Scroller
            mScroller = new Scroller(context);
        }
    
        //滑动到指定位置,参数为滑动的终点
        private void smoothScrollTo(int destX,int destY){
            //获取当前内容的左上角X坐标
            int scrollX = getScrollX();
            Log.d("TestView", scrollX + "-scroll," + destX + "-destX");
            //获取滑动的距离
            int deltaX = scrollX - destX;
            //该方法初始话scroller对象的参数
            mScroller.startScroll(scrollX, 0, deltaX, 0, 1000);
            //重绘,能够调用computeScroll()方法
            invalidate();
        }
        
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            //当按下时调用该方法
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    smoothScrollTo((int)event.getRawX(),0);
                    break;
            }
            return super.onTouchEvent(event);
        }
    
        //当重绘时候调用该方法
        @Override
        public void computeScroll() {
            super.computeScroll();
            //根据时间流逝(重绘需要时间)的百分比计算scrollX和scrollY
            if (mScroller.computeScrollOffset()){
                //获取当前的scrollX和scrollY
                scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
                //执行重绘
                postInvalidate();
            }
        }
    TestLinearLayout

    第二种:利用Handler来定时移动 (不展开了)

    第三种:使用空View改变View的布局  (真正能改变View在layout中的位置)

    使用空View改变该View的布局参数
    使用:建立空视图(Button1)在View(Button)的左边

    在MainActivity中
    MarginLayoutParams params = (MarginLayoutParams)mButton1.getLayoutParams();
    params.width + = 100;
    params.height += 100;
    mButton1.setLayoutParams(params);

    (这就能够使Button向右移)

  • 相关阅读:
    知识点:定义input type=file 样式的方法(转)
    笔记:认识 head 标签 待 更新中……
    检讨:关于上班迟到那么‘ 一两分钟 ’的事儿
    js--局部变量
    数十万互联网从业者的共同关注!
    js--javascript中字符串常用操作总结、JS字符串操作大全
    JavaScript中浏览器兼容问题
    js--性能优化(转)
    js-知识点
    让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法--(转)
  • 原文地址:https://www.cnblogs.com/rookiechen/p/5387980.html
Copyright © 2020-2023  润新知