Android Scroll分析(二)——滑动的几种方法
2016-06-18 16:14
405 查看
1.实现滑动的基本思想是当触摸view的时候,系统记录当前触摸点的坐标,当手指移动的时候,系统记录下移动后触摸点的坐标,从而花去到相对于前一次的偏移量,并且通过偏移量来修改view的坐标,这样不断的重复,从而实现滑动的过程。
2.下面通过一个实例来看看android是如何实现滑动效果的,自定义一个view,实现简单的布局。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <com.best.keke.myscrollviewdemo.MyScrollView android:id="@+id/myscrollview" android:layout_width="130dp" android:layout_height="130dp" android:background="#0000ff"/> </LinearLayout>
3.layout方法
我们知道在view进行绘制的时候回调用onLayout()方法来设置显示的位置,同样可以通过修改view的left,top,right,bottom四个属性来控制view的坐标。在每次回调onTouchEvent()的时候,我们都获取下触摸点的坐标:int x = (int) event.getX(); int y = (int) event.getY();
接着在MotionEvent.ACTION_DOWN中记录触摸点的坐标:
case MotionEvent.ACTION_DOWN: // 按下的坐标点 lastX = x; lastY = y; break;
最后在MotionEvent.ACTION_MOVE()中计算偏移量,并且将偏移量作用到layout()方法中。
case MotionEvent.ACTION_MOVE: // 计算偏移量 int offsetX = x - lastX; int offsetY = y - lastY; // 在当前的left,top,right,bottom基础上加上偏移量 layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY); break;
这样移动之后,view都会调用layout方法来重新进行布局,从而达到移动view的效果。
4. offsetTopAndBottom()和 offsetLeftAndRight()方法
该方法提供了相当于向上或者是向下的移动偏移量// 同时对上下进行偏移 offsetTopAndBottom(int offset) // 同时对左右进行偏移 offsetLeftAndRight(int offset)
5.LayoutParams
LayoutParams保存了一个view的布局参数,通过改变LayoutParams来动态的修改一个布局 位置信息,从而达到改变view位置的效果。我们哈可以使用getLayoutParams()来获取到一个view的LayoutParams。当然计算偏移量的方法与在layout方法中计算offset也是一样的,当获取到偏移量之后,就 可以通过setLayoutParams()来改LayoutParams。代码如下:
RelativeLayout.LayoutParams mLayoutParams = (RelativeLayout.LayoutParams) getLayoutParams(); mLayoutParams.leftMargin = getleft() + offsetX; mLayoutParams.topMargin = getTop() + offsetY; setLayoutParams(mLayoutParams);
这里需需要注意的是。通过getLayoutParams()获取到的LayoutParams时,需要根据view在父布局中的类型来设置不同的类型,此处将view放在了RelativeLayout中,那么就要使用RelativeLayout.LayoutParams。类似的在LinearLayout类型中也是一样的。当然获取LayoutParams的前提是必须要先有一个父布局。否则无法获取到LayoutParams。
在改变LayoutParams来改变view的位置时,通常改变的是view的Margin属性,所以除了使用布局的LayoutParams之外,还可以使用
ViewGroup.MarginLayoutParams mLayoutParams = ( ViewGroup.MarginLayoutParams) getLayoutParams(); mLayoutParams.leftMargin = getleft() + offsetX; mLayoutParams.topMargin = getTop() + offsetY; setLayoutParams(mLayoutParams);
这样使用viewgroup的好处就是我们不需要考虑父布局的类型。
5.scrollTo和scrollBy
二者的区别是scrollTo(x,y)表示的是移动到一个具体的坐标点(x,y),而scrollBy(x,y)表示的是移动的增量为dx何dy.与前面的几种方式类似,在获取偏移量后使用scrollBy来移动view.
int offsetX = x - lastX; int offsetY = y - lastY; scrollBy(offsetX, offsetY);
但是当我么拖动view的时候,发现view并没有移动,移动的不是我们想要的。scrollTo和scrollBy方法移动的是view的content,即让view的内容移动,如果在viewgroup中使用scrollTo和scrollBy,那么移动的将是所有的子view.但是如果在view中使用,移动的将是view的内容,如textview,移动的将是文本信息,imageview中移动的将是drawable对象。综上所述,我们就应该在viewgroup中使用scrollBy方法,移动它的子view.
((View)getParent()).scrollBy(offsetX, offsetY);
但是当拖动view的时候,我们会发现view在乱动,并不是按照我们跟随触摸点进行的移动。这里需要了解一个知识点:我们可以吧手机屏幕当做是一个中空的盖板,盖板下面是一个巨大的画布,也就是我们要显示的视图,当把盖板盖在画布上的某一处时,透过中间空的矩形,我们就看见了手机屏幕上显示的视图,而画布上其他的视图被盖板挡住了就看不见。如下图所示:
如图:中间的矩形相当于手机的屏幕,即可视区域,后面的大矩形相当于是画布,代表的是所有的视图。只有中间的视图是可见的,其他的区域都是不可见的,可见区域的button坐标为(30,15)。
下面使用scrollBy()方法,将盖板子啊水平方向上向X轴正方向平移30,在竖直方向上向Y轴正方向平移15,平移后的视图如右侧所示。
我们可以发现,虽然设置了scrollBy(30,15),偏移量都是在X,Y轴的正方向的正数,但是在屏幕的可视区域内,Button却向X,Y轴的负方向上移动了。
通过以上的分析,我们可以发现,如果将scrollBy中的参数dx和dy设置为正数,那么画布中的内容就将向坐标轴路的负方向移动,如果将scrollBy中的参数dx和dy设置为负数,那么画布中的内容就将向坐标轴路的正方向移动。所以要实现跟随手指移动而滑动的效果,就必须将偏移量改成负值。
((View)getParent()).scrollBy(offsetX, offsetY);
相关文章推荐
- ionic通讯录点击滑动效果的实现以及$ionicscrolldelegate使用分析
- android 如何解决scrollTo无法执行
- Android中滑屏初探 ---- scrollTo 以及 scrollBy方法使用说明
- Android中滑屏实现----手把手教你如何实现触摸滑屏以及Scroller类详解
- Android scrollTo()与scrollBy()的区别
- scrollTo和scrollBy
- android 设置listview滚动条的位置,颜色和宽度
- ScrollTo:实现平滑滚动到页面指定位置
- ScrollTo:实现平滑滚动到页面指定位置
- ScrollView滚动到指定位置
- Android中scroll的原理
- 当listview滑过headview时动态禁止ViewPager滑动方法
- Android自定义ViewPager(一)——自定义Scroller模拟动画过程
- window.scrollTo
- scrollTop 滚动动画
- RecyclerView学习(三)----高仿知乎的侧滑删除
- 站在源码的角度全解Scroller工作机制(三)
- 站在源码的角度全解Scroller工作机制(二)
- Weex Android SDK源码分析之Module(modal)
- canvas的save,restore方法的使用理解