效果
整个内容区域分为上下两部分,当将上部分内容拉到底部时,再拉动会将下面一部分内容拉出来,并且在松手时根据拉动的距离判断是回弹还是拉出来。在下部分时同样,拉动到顶部后继续下拉会将上部分拉出来。思路
思路一
可以将上部分写成带有上拉功能的控件,根据拉动的距离将下部分在垂直方向上进行移动,从而达到模拟上拉的效果。同样,将下部分写成具有下拉功能的控件,也根据拉动的距离将上部分在垂直方向上移动。
这种思路需要处理上下拉控件,并且在拉动过程中得设置回调,在回弹过程中一样得设置回调,这样才能达到两者同时滚动的效果。同时,上下部分在垂直方向上的移动需要一个单独的类进行协调。并且根据下部分控件的变化,需要不断地自定义带有下拉功能的控件。
思路二
利用CoordinatorLayout与Behavior,只需要自定义上拉加载下部分的Behavior与下拉加载上部分的Behavior即可。
示例
上拉加载的Behavior。注:上部分使用的是NestedScrollView,support v4中的。它类似于ScrollView,但可以与CoordinatorLayout一起使用。如下:public class FooterBehavior extends CoordinatorLayout.Behavior {
private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator();
public FooterBehavior() {
}
public FooterBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
return target.getId() == R.id.anchor && isBottom((NestedScrollView) target) && (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0 ;
//判断正在垂直滑动的控件是不是自己想要的,并且正处于底部
}
private boolean isUploaded = false;
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
if (dy > 0) {//上滑
} else {//下滑
if (sum > 0) {//已经上滑了一部分,此时又进行下滑。因此,需要将此时的下滑给屏蔽掉
isUploaded = true;
consumed[1] = dy;//禁止target的自身滑动。此时不会回调onNestedScroll方法,因此需要自己处理垂直位移
sum += dy;
ViewCompat.setTranslationY(child, -sum);