最终效果

Android lineChart拖动 android view拖动_动画

分析

我们实现一个跟手自由移动的效果。自定义View,拖动它可以让它在整个屏幕随意移动。
这个View实现起来很简单。我们只需要重写它的 onTouchEvent()方法并处理ACTION_MOVE事件,根据两次滑动之间的距离就可以实现它的滑动了。如下:

首先

打开 Android Studio,新建 ViewTest 项目。
由于我们需要用到动画兼容库nineoldandroids中ViewHelper这个类,所以我们需要导入库

build.gradle

compile 'com.nineoldandroids:library:2.4.0'

然后新建一个Scroll.java 继承 ImageView 并实现三个构造方法。代码如下:

public class Scroll extends ImageView {


    public Scroll(Context context) {
        this(context, null);
    }

    public Scroll(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public Scroll(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

}

并重写onTouchEvent()方法,代码如下

@Override
    public boolean onTouchEvent(MotionEvent event) {

        //获取屏幕的位置 xy值
        int x = (int) event.getRawX();
        int y = (int) event.getRawY();

        switch (event.getAction()){

            case MotionEvent.ACTION_DOWN:

                break;

            case MotionEvent.ACTION_MOVE:

                int deltaX = x - mLastX;
                int deltaY = y - mLastY;

                int translationX = (int) (ViewHelper.getTranslationX(this) + deltaX);
                int translationY = (int) (ViewHelper.getTranslationY(this) + deltaY);

                ViewHelper.setTranslationX(this,translationX);
                ViewHelper.setTranslationY(this,translationY);

                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        //记录View移动的初始值
        mLastX = x;
        mLastY = y;
        return true;
    }

getX/getY——getRawX/getRawY

在这里面我们先来理解getX,getRawX的区别:

getX/getY:返回的是相对于当前View左上角的x 和 y 坐标。
getRawX/getRawY:返回的是相对于手机屏幕左上角的x 和 y 坐标。

getTranslationX

ViewHelper.getTranslationY(this)计算该View的偏移量,初始值为0,向左偏移值为负,向右偏移值为正。

setTranslationX

ViewHelper.setTranslationX (View view, float translationX)这个方法。

view:是要移动的控件
translationX:是要移动的距离。


上述代码:首先我们通过getRawX()方法和getRawY()方法来获取手指当前的坐标,注意不能使用getX()方法和getY()方法,因为个是要全屏滑动的,所以需要获取当前点击事件在屏幕中的坐标而不是相对于View本身的坐标。并且声明两个变量mLastX,mLastY,来记录view初始的位置,然后通过 两点的坐标计算出两次滑动的之间的位移,有了这个位移就可以移动当前的View,移动方法采用的是动画兼容库nineoldandroids中的ViewHelper类所提供的setTranslationX 和 setTranslationY方法。其中translationX、translationY是View左上角相对于父布局的偏移量。

引用

引用自定义View

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.example.pc.day11.Scroll
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher"/>
</RelativeLayout>

最后

附上完整代码:

package com.example.pc.day11;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView;

import com.nineoldandroids.view.ViewHelper;

/**
 * Created by PC on 2017/11/29.
 */
public class Scroll extends ImageView {

    int mLastX;
    int mLastY;

    public Scroll(Context context) {
        this(context,null);
    }

    public Scroll(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public Scroll(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }




    @Override
    public boolean onTouchEvent(MotionEvent event) {

        //获取屏幕的位置 xy值
        int x = (int) event.getRawX();
        int y = (int) event.getRawY();

        switch (event.getAction()){

            case MotionEvent.ACTION_DOWN:

                break;

            case MotionEvent.ACTION_MOVE:

                int deltaX = x - mLastX;
                int deltaY = y - mLastY;

                int translationX = (int) (ViewHelper.getTranslationX(this) + deltaX);
                int translationY = (int) (ViewHelper.getTranslationY(this) + deltaY);

                ViewHelper.setTranslationX(this,translationX);
                ViewHelper.setTranslationY(this,translationY);

                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        //记录View移动的初始值
        mLastX = x;
        mLastY = y;
        return true;
    }
}

感谢阅读,下次再见。