(点击上方公众号,可快速关注)
来源:伯乐在线专栏作者 - joe
链接:http://android.jobbole.com/85137/
点击 → 了解如何加入专栏作者
接上文
拖拽背景渐变效果
说到背景的渐变效果,那么肯定就是要讲相关的回调了!Callbacks用来处理对应的回调,提供了三个方法:onSheetNarrowed(),onSheetExpanded(),onSheetPositionChanged(),分别对应的时候关闭了,展开了,和改变了三种情况。
在onSheetPositionChanged(int sheetTop, float currentX, int dy, boolean userInteracted)的方法中,有四个参数,分别是当前的top值,当前touch的x值,竖直方向的改变值,以及是否是由开到关或者由关到开的情况。
public static abstract class Callbacks {
public void onSheetNarrowed() {
}
public void onSheetExpanded() {
}
public void onSheetPositionChanged(int sheetTop, float currentX, int dy, boolean userInteracted) {
}
}
public void registerCallback(Callbacks callback) {
if (callbacks == null) {
callbacks = new CopyOnWriteArrayList();
}
callbacks.add(callback);
}
public void unregisterCallback(Callbacks callback) {
if (callbacks != null && !callbacks.isEmpty()) {
callbacks.remove(callback);
}
}
在具体是实现中是这样的:
mBoottom.registerCallback(new CurveLayout.Callbacks() {
private int dy;
@Override
public void onSheetExpanded() {
Log.e(TAG, "onSheetExpanded: ");
mCurveView.onDispatchUp();
mCurveView.setTranslationY(0);
mCurveView.setVisibility(View.GONE);
mTab.setTranslationY(-mCurveView.getHeight());
mTab.setVisibility(View.VISIBLE);
mCurveView.setScaleX(1.f);
mCurveView.setScaleY(1.f);
mViewPager.setScrollable(true);
dy = 0;
}
@Override
public void onSheetNarrowed() {
Log.e(TAG, "onSheetNarrowed: ");
mCurveView.onDispatchUp();
mCurveView.setTranslationY(0);
mCurveView.setScaleX(1.f);
mCurveView.setScaleY(1.f);
mTab.setVisibility(View.GONE);
mViewPager.setScrollable(false);
mCurveView.setVisibility(View.VISIBLE);
dy = 0;
}
@Override
public void onSheetPositionChanged(int sheetTop, float currentX, int ddy, boolean reverse) {
if (mCurveViewHeight == 0) {
mCurveViewHeight = mCurveView.getHeight();
mBoottom.setDismissOffset(mCurveViewHeight);
}
this.dy += ddy;
float fraction = 1 - sheetTop * 1.0f / mCurveViewHeight;
if (!reverse) {
if (fraction >= 0 && !mBoottom.isExpanded()) {//向上拉
mTab.setVisibility(View.VISIBLE);
mBoottom.setExpandTopOffset(mTab.getHeight());
mCurveView.setTranslationY(dy * 0.2f);
mTab.setTranslationY(-fraction * (mCurveView.getHeight() + mTab.getHeight()));
} else if (fraction
可以看到,在onSheetPositionChanged()的方法中,首先是进行了一些值的初始化,然后根据reverse来判断,如果不是由开到关或者由关到开的状态改变,那么就开始背景的移动或者背景的放大及画出对应的弧形。另外在onSheetNarrowed()或者onSheetExpanded()中就是对View做的一些初始化或者重置操作!
绘制下拉的弧度
当是下拉的时候,需要绘制出弧形,这里使用到了CurveView以及它的onDispatch()方法!
@Override
protected void onDraw(Canvas canvas) {
path.reset();
path.moveTo(0, getMeasuredHeight());
path.quadTo(currentX, currentY + getMeasuredHeight(), getWidth(), getMeasuredHeight());
canvas.drawPath(path, paint);
}
public void onDispatch(float dx, float dy) {
currentY = dy > MAX_DRAG ? MAX_DRAG : dy;
currentX = dx;
if (dy > 0) {
invalidate();
}
}
其实很简单,就是使用当前的X值的坐标和dy的值来进行drawPath()的操作。当然这里有一个上限的限制。
到这里,实现拖拽展开及关闭的逻辑就实现完成了,总结起来就是使用ViewDragHelper来辅助实现拖拽功能,在松手的时候调用ViewOffsetHelper来实现展开或者关闭的渐变动画效果,期间调用Callbacks回调对应的状态(展开了、关闭了、位置变化了)。
圆球绘制逻辑改动
之前的第一篇文章中介绍的圆球拉伸绘制时采用的是drawArc()和drawPath结合的方法,所以看着总觉得有点儿怪,然后查了相关的资料,这里使用了新的方式,请看图:
网上拷的
意思就是一个圆形,可以理解为是采用了drawPath()画了四段弧。每段弧就是使用path.cubicTo()绘制的贝塞尔曲线。
根据网上的资料,这里的m的值就是半径R*0.551915024494f。在竖直方向拖拽的过程中,其实就是改变这12个点的坐标,从而绘制出想要的弧形。
项目下载:https://github.com/lovejjfg/UCPullRefresh
喜欢就请点个Start呗。。
参考资料
1、Plaid项目
2、三次贝塞尔曲线练习之弹性的圆
—- Edit By Joe —-
专栏作者简介( 点击 → 加入专栏作者 )
joe:90后程序猿。。
打赏支持作者写出更多好文章,谢谢!
关注「安卓开发精选」
看更多精选安卓技术文章
↓↓↓