承接上一篇,如果你没有读过前四章方法,可以点击下面的链接:

http://www.cnblogs.com/fuly550871915/p/4985053.html

下面开始讲第五中方法。

五、利用Scroller类实现滑动

(1)基础知识总结

为了便于下面的阅读代码,先来总结一下关于Scroller类的基础知识。利用Scroller类实现滑动,需要三个步骤:

步骤一:
初始化Scroller对象,即mScroller = new Scroller(context)
步骤二:
重写computeScroll()方法,实现模拟滑动。可以复制下面的末模板代码:
public void computeScroll() {
super.computeScroll(); if(mScroller.computeScrollOffset())
{
((View)getParent()).scrollTo(mScroller.getCurrX(),
mScroller.getCurrY());
} invalidate();//必须要调用
}
步骤三:
开启模拟过程,在合适的地方(一般都在move中)startScroll方法。它有两个重载方法如下:
startScroll(int startX,int startY, int dx,int dy,int duration)
startScroll(int startX,int startY,int dx,int dy)
方法中的参数无需多解释了,就是起始坐标与偏移量,还有完成偏移的时间而已。

需要说明的是:(1)computeScrollOffset方法用来判断是否完成了整个滑动,返回为true,则说明没有完成,否则则完成滑动。

(2)getCurrY以及getCurrX获得的是当前的滑动坐标。

(3)最后必须要用invalidate方法来刷新。因为computeScroll方法不会自动调用,是在draw方法中被调用的。所以

必须使用invalidate刷新,就会调用draw方法,自然就会调用computeScroll方法了。这样子就会实现循环调用。

(4)在startScroll中,偏移量跟使用scrollBy方法中的偏移量用法是一样的,即也必须填写你实际想要移动距离的相

反数。也就是你实际想让它偏移一个正值,这里就填写它相应的负值,如果想偏移一个负值,这里就填写相应的

正值!

(2)代码实践

有些东西还是需要在真正的代码中才能说的明白的。我们接着上一篇文章的代码继续编写。为了看清Scroller类是如何实现滑动的,我们

再次修改DragView的代码。这次修改的有些多。贴完整的代码出来。如下:

 package com.example.testdragview;

 import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Scroller; public class DragView extends View{ private int lastX;
private int lastY;
private Scroller mScroller; public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); mScroller = new Scroller(context);
20 } public DragView(Context context, AttributeSet attrs) {
super(context, attrs);
mScroller = new Scroller(context);
} public DragView(Context context) {
super(context);
mScroller = new Scroller(context);
} 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 viewGroup = (View) getParent();
56
57 //开启滑动
58 mScroller.startScroll(viewGroup.getScrollX(),
59 viewGroup.getScrollY(), -offX, -offY);
60
break; case MotionEvent.ACTION_UP: break;
}
return true;
} public void computeScroll() {
73 super.computeScroll();
74
75 if(mScroller.computeScrollOffset())
76 {
77 ((View)getParent()).scrollTo(mScroller.getCurrX(),
78 mScroller.getCurrY());
79 }
80
81 invalidate();//必须要调用
82 }
}

红色部分就是修改的核心代码了。需要说明的是,在开启滑动的代码中,即第58行,使用的是在父视图中使用getScrollX和getScrollY获取

所滑动到的点的坐标。而getScollX和getScrollY正是从computeScroll中的scrollTo方法中传递过来的。通过阅读源码你可以很清晰的看到这个

过程。我贴两张源码图吧,如下:

                               

上图中观察mScrollX的传递过程,确实如上面我所说的。

而且在开启滑动的代码中,注意我们将偏移量可是都设定为负值了哦!(正如我上面所讲的设定为相反数即可)。

好了,关于代码的解释,就讲这么多,其他的都很好理解了。现在就运行程序,效果如下:

值得注意的是,我们的的DragView(即红色的块块)并不是即时跟随鼠标的滑动,在真机上这个效果将会更加突出!!其实这就是

Scrollerl类的滑动特点!即手指到达某一位置后,view会随后再平滑的到达这个位置,也就是说并不是view和手指一起到达指定位置的。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

因此,一般并不利用Scroller类实现滑动,因为它不是即时的。但却经常用它来实现手指抬起后,view回到初始位置!

来修改下DragView看看怎么实现这个效果。代码如下:

 package com.example.testdragview;

 import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Scroller; public class DragView extends View{ private int lastX;
private int lastY;
private Scroller mScroller; public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); mScroller = new Scroller(context);
} public DragView(Context context, AttributeSet attrs) {
super(context, attrs);
mScroller = new Scroller(context);
} public DragView(Context context) {
super(context);
mScroller = new Scroller(context);
} 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; case MotionEvent.ACTION_UP: View viewGroup = (View) getParent();
62
63 //开启滑动,让其回到原点
64 mScroller.startScroll(viewGroup.getScrollX(),
65 viewGroup.getScrollY(),
66 -viewGroup.getScrollX() ,-viewGroup.getScrollY() );
67
break;
}
return true;
} public void computeScroll() {
super.computeScroll(); if(mScroller.computeScrollOffset())
{
((View)getParent()).scrollTo(mScroller.getCurrX(),
mScroller.getCurrY());
} invalidate();//必须要调用
}
}

红色部分依旧是修改的核心代码。这里主要就是将实现的滑动效果替换成了用scrollBy来实现即时滑动,然后在手指抬起的up方法中,利用

Scoller类将view放回原来位置!运行一下,看看效果,如下:

如上图所示,只要鼠标一抬起,红色块块就会立刻回到原来位置!怎么样不错吧。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

好了,关于这个Scroller类的使用,就讲到这里。上面的代码基本都可以当做是模板代码了,需要的时候过来看看复制一下吧。

未完待续.....(最后一种方法)

android中实现view可以滑动的六种方法续篇(一)的更多相关文章

  1. android中实现view可以滑动的六种方法续篇(二)

    承接上一篇,上一篇中讲解了实现滑动的第五种方法,如果你还没读过,可点击下面链接: http://www.cnblogs.com/fuly550871915/p/4985482.html 这篇文章现在来 ...

  2. android中实现view可以滑动的六种方法

    在android开发中,经常会遇到一个view需要它能够支持滑动的需求.今天就来总结实现其滑动的六种方法.其实每一种方法的 思路都是一样的,即:监听手势触摸的坐标来实现view坐标的变化,从而实现vi ...

  3. Android View体系(二)实现View滑动的六种方法

    1.View的滑动简介 View的滑动是Android实现自定义控件的基础,同时在开发中我们也难免会遇到View的滑动的处理.其实不管是那种滑动的方式基本思想都是类似的:当触摸事件传到View时,系统 ...

  4. 详解实现Android中实现View滑动的几种方式

    注: 本文提到的所有三种滑动方式的完整demo:ScrollDemo 1. 关于View我们需要知道的 (1)什么是View? Android中的View类是所有UI控件的基类(Base class) ...

  5. Android 中的View与ViewGroup

    Android重点知识--View和ViewGroup与自定义控件 作者:丁明祥 邮箱:2780087178@qq.com 一.基础 ViewGroup 参考资料: Android 手把手教您自定义V ...

  6. android中的坐标系以及获取坐标的方法

    android中有两种坐标系,分别称之为Android坐标系和视图坐标系.而对应的也有一些相关的方法可以获取坐标系中的 坐标值.只有搞清楚这些区别,才能在实现的时候不至于出错或者得不到你想要的效果. ...

  7. MVC中视图View向控制器传值的方法

    MVC中视图View向控制器传值的方法步骤如下: 1.index页面: 页面中只需要一个触发事件的按钮

  8. android中Bitmap的放大和缩小的方法

    android中Bitmap的放大和缩小的方法 时间 2013-06-20 19:02:34  CSDN博客原文  http://blog.csdn.net/ada168855/article/det ...

  9. Android 自己定义View须要重写ondraw()等方法

    Android  自己定义View须要重写ondraw()等方法.这篇博客给大家说说自己定义View的写法,须要我们继承View,然后重写一些 方法,方法多多,看你须要什么方法 首先写一个自己定义的V ...

随机推荐

  1. iOS- NSDateFormatter (自定义时间格式)

    一. NSDateFormatter解释 1. 日期(NSDate)是NSString类的格式(stringWithFormat),也可以改变输出,如果需要输出年代信息等则需要进行转换,等等. 2.  ...

  2. python 在sublime 中的配置

    首先可以先装package control 方法——按ctrl+`,然后在命令行里复制粘贴以下代码, import urllib2,os;pf='Package Control.sublime-pac ...

  3. SQL Server 存储(2/8):理解数据记录结构

    在SQL Server :理解数据页结构我们提到每条记录都有7 bytes的系统行开销,那这个7 bytes行开销到底是一个什么样的结构,我们一起来看下. 数据记录存储我们具体的数据,换句话说,它存在 ...

  4. struts2基础——最简单的一个例子

    学习版本:struts-2.3.15.3 一.导入jar包,可以参考 官方项目 blank. 二.添加配置文件:web.xml struts.xml web.xml: <filter> & ...

  5. js跳转页面方法大全

    js跳转页面方法大全<span id="tiao">3</span><a href="javascript:countDown"& ...

  6. Sql server脏读、更新丢失、不可重复读、幻象读问题及解决方案

    1.脏读:一个事务读到另外一个事务还没有提交的数据.解决方法:把事务隔离级别调整到READ COMMITTED,即SET TRAN ISOLATION LEVEL READ COMMITTED.这时我 ...

  7. Redis持久化-数据丢失及解决

    Redis的数据回写机制 Redis的数据回写机制分同步和异步两种, 同步回写即SAVE命令,主进程直接向磁盘回写数据.在数据大的情况下会导致系统假死很长时间,所以一般不是推荐的. 异步回写即BGSA ...

  8. 与众不同 windows phone (44) - 8.0 位置和地图

    [源码下载] 与众不同 windows phone (44) - 8.0 位置和地图 作者:webabcd 介绍与众不同 windows phone 8.0 之 位置和地图 位置(GPS) - Loc ...

  9. Jquery 前端模版

    <div id="div_demo"></div><script id="demo" type="text/x-jque ...

  10. sql 大数据库 插入超时问题解决

    解决的办法:1. 不要使用自动收缩, 自动收缩会定期收容数据文件的空闲空间,则处理需要的时候却要扩大数据文件,这两者相反的处理,是冲突的设置方法:ALTER DATABASE MyDataBase S ...