导读
- View的6种基本的滑动方式
- scrollTo/scrollBy 实现侧滑菜单
- ViewDragHelper 实现侧滑菜单
- Demo下载
View的6种基本的滑动方式:
1.layout()
众所周知,view在绘制的时候会调用layout()方法来确定view的最终位置。因此我们同样也可以通过修改View的left、top、right、bottom这四种属性来控制View的坐标位置,从而达到View的滑动效果。
2.offsetLeftAndRight()与offsetTopAndBottom()
offsetLeftAndRight()方法,改变view在x轴的坐标位置,使view在x轴方向上发生偏移。参数为view在x轴产生的偏移量。
offsetTopAndBottom()方法,改变view在y轴的坐标位置,使view在y轴方向上发生偏移。参数为view在y轴产生的偏移量。
这两种方法和layout()原理相似,只是使用起来较为方便 。
3.LayoutParams
LayoutParams主要保存了一个View的布局参数,因此我们可以通过LayoutParams来改变View的布局的参数从而达到了改变View的位置的效果。
因为父控件是LinearLayout,所以我们用了LinearLayout.LayoutParams,如果父控件是RelativeLayout则要使用RelativeLayout.LayoutParams。除了使用布局的LayoutParams外,我们还可以用ViewGroup.MarginLayoutParams。
4.动画
动画可以讲的比较多,后面写到view属性动画时在谈。
- scrollTo与scrollBy
scollTo(x,y)表示移动到一个具体的坐标点,而scollBy(dx,dy)则表示移动的增量为dx、dy,scrollBy最后也是调用scollTo。要注意的是,它们改变的都是view内容的位置而非view本身,且二者都是瞬时完成的,用户体验较差,这里我们可以使用scroller来实现有过度效果的滑动。
- scroller
如何使用Scroller,我们先来看看官方API:
可以看到,这里主要通过调用startScroll方法开始滚动,我们看看它的源码:
我们发现,在startScroll()里面并没有开始滚动,而是设置了一堆变量的初始值,那么到底是什么让View开始滚动的?我们应该把目标集中在startScroll()的下一句invalidate();身上。我们可以这样理解:首先在startScroll()设置好了一堆初始值,之后调用了invalidate();让View重新绘制,这里又有一个很重要的点,在draw()中会调用computeScroll()这个方法!
要让view发生位移,我们就应该重写computeScroll()方法:
若滑动没有结束,则scroller.computeScrollOffset()方法返回true,若结束了则返回false。
scroller.getCurrX()和scroller.getCurrY()分别计算出该时间点view的滑动距离,由于scrollTo改变的是view内容的位置而非view本身,所以调用getParent的scrollTo方法来使自身的位置发生改变。
scrollTo/scrollBy实现侧滑菜单:
布局思路 ①:
如图,我的思路是自定义一个viewgroup继承LinearLayout(不一定是LinearLayout)。重写它的onLayout方法,使主布局和侧滑布局如图放置:
然后要做的就是监听滑动事件了,首先先判断用户操作是水平滑动还是竖直滑动,这里只允许水平滑动:
重写onTouchEvent方法:
ACTION_DOWN记录了用户按下时的x轴坐标。ACTION_MOVE做了两件事:1、计算用户滑动距离offsetX和view已经滑动的总距离scrollX。2、根据scrollX大小控制侧滑菜单显示位置。ACTION_UP用于判断用户手指离开时,若滑动距离大于某数值(一般为侧滑菜单宽度的一半,这里偷懒写死为150),将侧滑菜单完全展示出来,反之则隐藏侧滑菜单。这样用户体验更强。
ViewDragHelper 实现侧滑菜单:
布局思路 ② :
和第一种思路不同,这次利用的是帧布局的特性。先将主布局的内容遮在菜单项上边,利用ViewDragHelper移动红色框(主内容),露出菜单项的内容。
那么,ViewDragHelper如何使用呢?我们还是先看API:
根据ViewDragHelper.create()方法创建ViewDragHelper对象:
tryCaptureView方法返回一个boolean值,用来控制当前哪个view可以移动(可多个)。
clampViewPositionHorizontal方法返回一个int值,用来控制水平方向的位移距离。
触发ViewDragHelper.Callback方法需要在onTouchEvent中调用ViewDragHelper.processTouchEvent方法:
这样简单三步,轻松实现简单侧滑。
最后最后,附上Demo地址:
Demo下载