Android 滑动分析(一)

1.引言


《android群英传》讲滑动效果这块,分析总结的不错,自己学习完后明显觉得很有提高,因此记录下,加深印象。


在博客开始之前,我先说下坐标系的概念。android中有俩个坐标系。一个是手机屏幕左上角。还有一个是视图坐标系。如下图所示:

这里写图片描述

一个view里面自带一些方法可以获取到自己相对于父容器的坐标,也就是以视图坐标系为坐标系的x,y坐标。下面介绍一些常见的方法:


getTop(): 获取view距离父容器的顶部的距离。

getLeft() :获取view距离父容器的左边的距离

getright() : 获取view到父容器的右边的距离



了解了这些小知识点之后,我们可以动手写一个demo了。主要功能让view跟着我们手的移动而移动。
1.自定义一个view,该view就是一个带有颜色的正方形。这里代码我就不贴了。


2.为view 添加onTouchEventListener方法,监听点击view的动作,主activity的代码如下:

 MyView view;
    RelativeLayout parent;
    int x;
    int y;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        view=(MyView) findViewById(R.id.myview);
        view.setOnTouchListener(this);
        parent=(RelativeLayout)view.getParent();
    }
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Toast.makeText(MainActivity.this, "触摸成功", Toast.LENGTH_SHORT).show();
        switch (event.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                 x= (int) event.getX();
                 y= (int) event.getY();
                 break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:

                break;
        }
        return true;
    }
}

其中x,y是记录按下之后的 坐标。


下面我将介绍3中方式来实现view的拖动:


1.layout方法. 核心思想 就是在滑动的过程中 不断通过layout 来安排view在父容器中的位置。每滑动一下就执行一次,这样总体看起来就是移动,连贯的。 代码如下:

 public boolean onTouch(View v, MotionEvent event) {
        Toast.makeText(MainActivity.this, "触摸成功", Toast.LENGTH_SHORT).show();
        switch (event.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                 x= (int) event.getX();
                 y= (int) event.getY();
                 break;
            case MotionEvent.ACTION_MOVE:
                int l=view.getLeft()+(int)(event.getX()-x);
                int t=view.getTop()+(int)(event.getY()-y);
                view.layout(l,t,l+view.getMeasuredWidth(),t+view.getMeasuredHeight());
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return true;
    }


效果图如下:
这里写图片描述

view最开始的位置是在 左上角这是我移动指挥的图片。

这里我说下注意的问题:
1.首先重写的onTouch方法 必须返回true,返回true 表示当前这次事件被处理了,假如返回false,或者super.onTouch 表示不处理当前事件。也就不会移动了


2.第二个问题就是:我最开始做的时候想 既然我知道 每次移动的x,y 为什么不用 这个x,y直接调用layout来布局,而非要得到view.left view.top呢? 这是因为你无法根据一个点的移动 来描绘出 view的位置。具体你们可以试试看。还有一点就是event.getx(),view.getleft()获取的距离都是px。



2.通过view 自带的offsetLeftAndRight(offset x)和 offsetTopAndBottom(offset y),通过设置偏移量 来控制view 移动。核心代码如下:

 public boolean onTouch(View v, MotionEvent event) {
        Toast.makeText(MainActivity.this, "触摸成功", Toast.LENGTH_SHORT).show();
        switch (event.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                 x= (int) event.getX();
                 y= (int) event.getY();
                 break;
            case MotionEvent.ACTION_MOVE:
                int l=(int)(event.getX()-x);
                int t=(int)(event.getY()-y);
                view.offsetLeftAndRight(l);
                view.offsetTopAndBottom(t);
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return true;
    }



核心方法 就是Move方法里面的:offsetLeftAndRight(offset x) 和offsetTopAndBottom(offset y).



3.通过 Layoutparams 来动态改变Margin值来实现。先通过view获取到LayoutParams的值,然后再设置Margin值,就ok了。具体代码实现如下:

public boolean onTouch(View v, MotionEvent event) {
        Toast.makeText(MainActivity.this, "触摸成功", Toast.LENGTH_SHORT).show();
        switch (event.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                 x= (int) event.getX();
                 y= (int) event.getY();
                 break;
            case MotionEvent.ACTION_MOVE:
                int l=(int)(event.getX()-x)+view.getLeft();
                int t=(int)(event.getY()-y)+view.getTop();
                RelativeLayout.LayoutParams pm= (RelativeLayout.LayoutParams) view.getLayoutParams();
                pm.leftMargin=l;
                pm.topMargin=t;
                view.setLayoutParams(pm);
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return true;
    }


这里写图片描述

实现效果如上图。这几种方式真的很常见,无论是 下拉刷新,还是下拉图片变大,都能见到这几种方法的身影。
下一节 准备写下Scroller类。希望这篇博客能给你带来帮助。希望像我一样菜的人能坚持下去,总有一天我会成为大牛!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值