android中实现view可以滑动的六种方法
在android开发中,经常会遇到一个view需要它能够支持滑动的需求。今天就来总结实现其滑动的六种方法。其实每一种方法的
思路都是一样的,即:监听手势触摸的坐标来实现view坐标的变化,从而实现view的滑动效果。
一、通过Layout方法来实现滑动
如果你将滑动后的目标位置的坐标传递给Layout,这样子就会把view的位置给重新布置了一下,在视觉上就是view的一个滑动的效果。
这就是利用Layout方法实现滑动的核心思路。我们来看一下代码:
新建项目,然后自定义一个view,代码如下:
package com.example.testdragview; import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View; public class DragView extends View{ private int lastX;
private int lastY; public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
} public DragView(Context context, AttributeSet attrs) {
super(context, attrs);
} public DragView(Context context) {
super(context);
} public boolean onTouchEvent(MotionEvent event) { // Log.d("付勇焜----->","TouchEvent");
// Log.d("付勇焜----->",super.onTouchEvent(event)+""); //获取到手指处的横坐标和纵坐标
int x = (int) event.getX();
int y = (int) event.getY(); switch(event.getAction())
{
case MotionEvent.ACTION_DOWN: lastX = x;
lastY = y; break; case MotionEvent.ACTION_MOVE: //计算移动的距离
int offX = x - lastX;
int offY = y - lastY;
//调用layout方法来重新放置它的位置
layout(getLeft()+offX, getTop()+offY,
getRight()+offX , getBottom()+offY); break;
} return true;
}
}
核心代码就是onTouchEvent方法了。代码很简单,无非就是记录手指的上次坐标与下次坐标,然后将前后移动的增量传递给layout方法而已。
值得注意的是,onTouchEvent的返回值为true,表示我们要成功消化掉这个触摸事件。
然后再修改activity_main.xml的代码,将这个view装到布局里,如下:
<LinearLayout 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.testdragview.DragView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#FF0000" /> </LinearLayout>
现在来运行程序。效果如下:

效果还可以吧。可以自由的滑动了。
其实上面我们用getX()和getY()获得的是在视图坐标系中的值。其实我们也可以使用绝对坐标,即使用getRawX()和getRawY()获得的值
来实现这个滑动效果。修改DragView中的onTouchEvent中的代码,如下所示:
public boolean onTouchEvent(MotionEvent event) {
//获取到手指处的横坐标和纵坐标
int x = (int) event.getRawX();
int y = (int) event.getRawY();
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
lastX = x;
lastY = y;
break;
case MotionEvent.ACTION_MOVE:
//计算移动的距离
int offX = x - lastX;
int offY = y - lastY;
//调用layout方法来重新放置它的位置
layout(getLeft()+offX, getTop()+offY,
getRight()+offX , getBottom()+offY);
lastX = x;
lastY = y;
break;
}
return true;
}
一定注意,此时不同的是,在move过程中,我们要及时改变lastX,与lastY的值来获取正确的之前坐标(因为是在Android坐标系嘛,用的是绝对距离)。
此时再次运行程序,效果跟上图一样。
二、offsetLeftAndRight()和offsetTopAndBottom()方法来实现
其实这两个方法分别是对左右移动和上下移动的封装,传入的就是偏移量。此时将DragView中的onTouchEvent代码简单替换即可,如下:
public boolean onTouchEvent(MotionEvent event) {
//获取到手指处的横坐标和纵坐标
int x = (int) event.getX();
int y = (int) event.getY();
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
lastX = x;
lastY = y;
break;
case MotionEvent.ACTION_MOVE:
//计算移动的距离
int offX = x - lastX;
int offY = y - lastY;
offsetLeftAndRight(offX);
23 offsetTopAndBottom(offY);
break;
}
return true;
}
红色部分就是关键代码了,运行一下程序,跟上面的效果是一样的,不再贴图。
三、使用LayoutParams来实现
依旧修改DragView的onTouchEvent代码,如下:
public boolean onTouchEvent(MotionEvent event) {
//获取到手指处的横坐标和纵坐标
int x = (int) event.getX();
int y = (int) event.getY();
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
lastX = x;
lastY = y;
break;
case MotionEvent.ACTION_MOVE:
//计算移动的距离
int offX = x - lastX;
int offY = y - lastY;
22 ViewGroup.MarginLayoutParams mlp =
23 (MarginLayoutParams) getLayoutParams();
24
25 mlp.leftMargin = getLeft()+offX;
26 mlp.topMargin = getTop()+offY;
27
28 setLayoutParams(mlp);
29
break;
}
return true;
}
红色部分依旧是关键代码。注意这里我们一般通过改变view的Margin属性来改变其位置的。
运行程序,结果依旧,不再贴图。
四、通过scrollTo和scrollBy方法
在一个view中,系统也提供了scrollTo和scrollBy方法来移动view。很好理解,sceollTo(x,y)传入的应该是移动的终点坐标,而scrollBy(dx,dy)传入的是
移动的增量。这两个方法要在view所在的viewGroup中使用!但是一定要注意:通过scrollBy传入的值应该是你需要的那个增量的相反数!这样子才能达到你想
要的效果!!切记切记
依旧是hi修改DragView的onTouchEvent代码,如下:
public boolean onTouchEvent(MotionEvent event) {
//获取到手指处的横坐标和纵坐标
int x = (int) event.getX();
int y = (int) event.getY();
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
lastX = x;
lastY = y;
break;
case MotionEvent.ACTION_MOVE:
//计算移动的距离
int offX = x - lastX;
int offY = y - lastY;
((View) getParent()).scrollBy(-offX,- offY);
break;
}
return true;
}
红色部分为修改的核心代码,运行一下,效果依旧,不再贴图。
限于篇幅,请保存好这些代码,在下一篇文章中仍旧在此基础上编写。未完待续....
点击下面链接,查看滑动的第五种方法:
http://www.cnblogs.com/fuly550871915/p/4985482.html
android中实现view可以滑动的六种方法的更多相关文章
- android中实现view可以滑动的六种方法续篇(二)
承接上一篇,上一篇中讲解了实现滑动的第五种方法,如果你还没读过,可点击下面链接: http://www.cnblogs.com/fuly550871915/p/4985482.html 这篇文章现在来 ...
- android中实现view可以滑动的六种方法续篇(一)
承接上一篇,如果你没有读过前四章方法,可以点击下面的链接: http://www.cnblogs.com/fuly550871915/p/4985053.html 下面开始讲第五中方法. 五.利用Sc ...
- Android View体系(二)实现View滑动的六种方法
1.View的滑动简介 View的滑动是Android实现自定义控件的基础,同时在开发中我们也难免会遇到View的滑动的处理.其实不管是那种滑动的方式基本思想都是类似的:当触摸事件传到View时,系统 ...
- 详解实现Android中实现View滑动的几种方式
注: 本文提到的所有三种滑动方式的完整demo:ScrollDemo 1. 关于View我们需要知道的 (1)什么是View? Android中的View类是所有UI控件的基类(Base class) ...
- Android 中的View与ViewGroup
Android重点知识--View和ViewGroup与自定义控件 作者:丁明祥 邮箱:2780087178@qq.com 一.基础 ViewGroup 参考资料: Android 手把手教您自定义V ...
- android中的坐标系以及获取坐标的方法
android中有两种坐标系,分别称之为Android坐标系和视图坐标系.而对应的也有一些相关的方法可以获取坐标系中的 坐标值.只有搞清楚这些区别,才能在实现的时候不至于出错或者得不到你想要的效果. ...
- MVC中视图View向控制器传值的方法
MVC中视图View向控制器传值的方法步骤如下: 1.index页面: 页面中只需要一个触发事件的按钮
- android中Bitmap的放大和缩小的方法
android中Bitmap的放大和缩小的方法 时间 2013-06-20 19:02:34 CSDN博客原文 http://blog.csdn.net/ada168855/article/det ...
- Android 自己定义View须要重写ondraw()等方法
Android 自己定义View须要重写ondraw()等方法.这篇博客给大家说说自己定义View的写法,须要我们继承View,然后重写一些 方法,方法多多,看你须要什么方法 首先写一个自己定义的V ...
随机推荐
- Configuring Service Broker for Asynchronous Processing
Configuring Service Broker for Asynchronous Processing --create a database and enable the database f ...
- 【转】sql server开启全文索引方法
利用系统存储过程创建全文索引的具体步骤: 1) 启动数据库的全文处理功能 (sp_fulltext_database) 2) 建立全文目录 (sp_fulltext_catalog) 3) 在全文目录 ...
- CentOS6.5菜鸟之旅:安装VirtualBox4.3
一.下载VirtualBox的RHEL软件库配置文件 cd /etc/yum.repos.d wget http://download.virtualbox.org/virtualbox/rpm/rh ...
- IOS开发UI基础文本属性Attributes
文本属性Attributes 1.NSKernAttributeName: @10 调整字句 kerning 字句调整 2.NSFontAttributeName : [UIFont systemFo ...
- 软件测试之黑盒测试:打着手电寻找bug
功能测试,简单的理解就是黑盒测试,就是检测黑盒子,找到里面存在的缺陷. 功能测试新人学习计划: 1. 对于产品的学习---站在客户的角度学习产品.看待问题 测试人员不是简单地按照开发人员的设计文档去撰 ...
- Sql Server来龙去脉系列之四 数据库和文件
在讨论数据库之前我们先要明白一个问题:什么是数据库? 数据库是若干对象的集合,这些对象用来控制和维护数据.一个经典的数据库实例仅仅包含少量的数据库,但用户一般也不会在一个实例上创建太多 ...
- 用Qt写软件系列二:QCookieViewer(浏览器Cookie查看器)
预备 继上篇<浏览器缓存查看器QCacheViewer>之后,本篇开始QCookieViewer的编写.Cookie技术作为网站收集用户隐私信息.分析用户偏好的一种手段,广泛应用于各大网站 ...
- MongoDB之数据分布式存储
在MongoDB的世界,做数据分布式存储显得非常简单.只要按照前面介绍的 集群搭建 完成就完全具备了数据分布式存储的要求. 在这里分清几个概念:去前面的文章可以找到介绍 1. 复制集 功能是实现数 ...
- 【CODEVS 3287】【NOIP2013】火车运输
http://codevs.cn/problem/3287/ 题目描述 国有 座城市,编号从 到 ,城市之间有 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 辆货车在运输货物, 司机们想 ...
- PHP redis Api 中文文档
phpredis是php的一个扩展,效率是相当高有链表排序功能,对创建内存级的模块业务关系 很有用;以下是redis官方提供的命令使用技巧: 下载地址如下: https://github.com/ow ...