主要是利用ViewDragHelper这个类来实现控件的拖动。 这个效果就是两个VIEW叠在一起,向下拉第一个VIEW,就会显示出第二个,第二个VIEW显示完后,就不能再向下拉动。第一个VIEW通常来讲是个LISTVIEW,所以还要处理好事件发事纷发。
这里依然是写一个自定义的VIEWGROUP,我们继承自 FrameLayout.
1.重点是ViewDragHelper:
可以看到这里写了ViewDragHelper的三个回调方法:
tryCaptrueView 就表示哪个控件可以被拖动
clampViewPositionVertical 表示可以被竖直通动!! 返回值就是拖动的高 度
onViewReleased 表示松手后,被拖动控件的处理。 这里的处理是,根据松手滑动的位置,来置顶或者显示。
当然,这个drag事件,肯定还是需要在onTouch 中传进去的:
2.我们要控制LISTVIEW滑动的距离 ,就是说,你不能无限可以下拉啊,你下拉最多就是内部VIEW的高 度,这样才能无鏠连接嘛,所以,必须要晓得高度嘛:
肯定是在onMeasure执行后,才能获得这个高度嘛!
当然,在XML初始化时,我们也要作一些操作,这里也贴出来:
3.好了,其实以上代码,已经足够可以垂直拖动LISTVIEW,但LISTVIEW自己也有分发事件,固必须在某些时候,我们自定义的VIEWGROUP要拦截LISTVIEW的事件! 比如,当LISTVIEW滚动到其顶部时,就要拦截事件交给VIEWGROUP来处理。
这里的关键是判断了向下滚动,并且滚动到了LISTVIEW的顶部!!! 这里canChildScrollUp 返回false时,就是指的滑到了顶部。
此方法就是从源码中挖出来的!判断是否了顶!这里复制下来,以后好用。
/**
* @return Whether it is possible for the child view of this layout to
* scroll up. Override this if the child view is a custom view.
* 判断View是否滚动到了最顶部,还能不能向上滚
*/
public boolean canChildScrollUp() {
if (android.os.Build.VERSION.SDK_INT <14) {
if (listView instanceof AbsListView) {
final AbsListView absListView = (AbsListView)listView;
return absListView.getChildCount() >0
&& (absListView.getFirstVisiblePosition() >0 || absListView.getChildAt(0)
.getTop() < absListView.getPaddingTop());
}else {
return ViewCompat.canScrollVertically(listView, -1) ||listView.getScrollY() >0;
}
}else {
return ViewCompat.canScrollVertically(listView, -1);
}
}
4.好了,还有一个要点,当VIEW拖动到某地,然后放手,需求要求VIEW会回置顶或者全显示!
注意,这里调用了一个 settleCaptureViewAt 方法来让VIEW移到对应位置,但是,如果只是这样写,是无效的! 必须:
这里会回 调,然后不断 invalidate 才行。
网友评论