View的滑动实现之一(使用layout实现)

滑动一个View,本质上就是移动一个View的位置,它的实现与动画的实现非常相似,通过不断的改变View的位置来实现这一效果。所以,如果要实现这一效果,必定要监听用户的触摸事件。在前面我们已经深入分析了触摸事件的传递和分发机制。今天在这里同样还需要使用到MotionEvent。

在实现滑动之前,我们先来熟悉一下Android中的坐标系。

在Android中,将屏幕的左上角的顶点作为Android坐标系的原点,从这个点向右是X轴正方向,从这个点向下是Y轴正方向。如图,


另外不得不提的是,在触控事件中使用的getRawX()和getRawY()方法获取的坐标是Android坐标系中的坐标。使用getX()和getY()方法获得的是视图坐标系的坐标,下面用一张简单的图解释什么叫视图坐标系。


好了,基础的知识介绍完了,现在说明一下实现View滑动的思想,当触摸View时,记录下当前触摸的坐标,当手指移动时,记录下移动后的触摸点的坐标,从而获得相对于上一次记录的坐标点的偏移量,并通过偏移量来修改View的坐标,从而实现了View的滑动过程。


首先,很容易想到的,也是在View的绘制过程中,非常重要的一个步骤--View的布局(OnLayout),通过给View重新布局从而实现滑动的效果。

下面来看一下具体的实现:

1.通过基本的layout方法,就向上面我们提到的,在View进行绘制时,会调用OnLayout()方法来设置显示的位置,同时可以修改View的left,top,right,bottom四个属性来控制View的坐标。

先上代码:

@Override
public boolean onTouchEvent(MotionEvent event) {
    /**时时获取坐标值**/
    int rawX =(int)(event.getRawX());
    int rawY=(int)(event.getRawY());
    switch (event.getAction()){
        case MotionEvent.ACTION_DOWN:
            /**记录按下时的坐标点**/
            lastX=rawX;
            lastY=rawY;
            break;
        case MotionEvent.ACTION_MOVE:
            //计算偏移量
            int offsetX=rawX-lastX;
            int offsetY=rawY-lastY;
            //使用layout重新布局
            layout(getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom()+offsetY);
            lastX=rawX;
            lastY=rawY;
            break;
    }
    return super.onTouchEvent(event);
}
上面使用的是Android坐标系来进行对比的。每次移动后,View都会调用Layout方法来对自己重新布局,从而达到View的移动效果。


2.offsetLeftAndRight与offsetTopAndBottom()

这个方法相当于系统提供的一个对左右,上下移动的API的封装,该方法和上面layout方法的实现原理相,但是使用简单。

//同时对leftright进行偏移
offsetLeftAndRight(offsetX);
//同时对topbottom进行偏移
offsetTopAndBottom(offsetY);


3.LayoutParams

LayoutParams保存了一个View的布局参数,所以可以在程序中通过改变LayoutParams来动态修改一个布局的位置参数,从而实现改变View位置的效果。

实现过程如下,在程序中通过getLayoutParams()来获取要移动的View的LayoutParams,然后获取到偏移量之后,在通过setLayoutParams来改变其LayoutParams。

代码如下:

LinearLayout.LayoutParams layoutParams= (LinearLayout.LayoutParams) getLayoutParams();
layoutParams.leftMargin=getLeft()+offsetX;
layoutParams.topMargin=getTop()+offsetY;
setLayoutParams(layoutParams);

相信大家也都注意到了,上面的代码不是固定的,而是会因为父布局的类型不同而设置不同的类型,为了代码的灵活度,这里推荐使用ViewGroup.MarginLayoutParams来实现上面的代码,因为不需要考虑父布局的类型,当然它们的本质都是一样的。


后面的文章将会给大家讲解一下其他的View滑动实现方法,ScrollTo,ScrollBy,属性动画等方式。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值