您的位置:首页 > 移动开发 > Android开发

Android——自定义View随手自由移动

2017-11-29 12:09 281 查看
参考《Android开发艺术探索》

最终效果



分析

我们实现一个跟手自由移动的效果。自定义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; }
}


感谢阅读,下次再见。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: