专栏名称: 安卓开发精选
伯乐在线旗下账号,分享安卓应用相关内容,包括:安卓应用开发、设计和动态等。
目录
相关文章推荐
鸿洋  ·  裁员在家如何保持高效学习 ·  昨天  
鸿洋  ·  PackageManagerService和 ... ·  2 天前  
鸿洋  ·  2024 了, Insets 你不会还不懂吧? ·  4 天前  
鸿洋  ·  鸿蒙版 React Native ... ·  5 天前  
51好读  ›  专栏  ›  安卓开发精选

Android 自定义View UC下拉刷新效果(三)下

安卓开发精选  · 公众号  · android  · 2016-11-19 21:46

正文

(点击上方公众号,可快速关注)


来源:伯乐在线专栏作者 - 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后程序猿。。

打赏支持作者写出更多好文章,谢谢!



 关注「安卓开发精选

看更多精选安卓技术文章
↓↓↓