仿Android百度外卖

[复制链接]
来自: MrlLee 分类: Android精品源码 上传时间: 2016-8-30 11:07:29
Tag:

项目介绍:

改造轮子轮子就不重复造了,github上已经有实现波浪的效果WaveView,WaveView作者的水波浪实现方法是比较优雅的,简单粗暴的,绘制一个波形图,填充到View里,移动波形图。
实现思路,画两条sin函数曲线相叠的波形图,通过Matrix平移,将sin函数的height传给头像view,进行Translation。
  • 1、将轮子的水波浪方向上下颠倒
19170-b810fceaed12321f.png
baiduwaimai.png

因为百度外卖的水波浪下面还有一个scrollview,而当scrollview往上滑动时,内容会被水波浪整个view覆盖,看着不舒服,所以将水波浪方向调整。
[Java] 查看源文件 复制代码
       wavePaint.setColor(mBehindWaveColor);[/font]        for (int beginX = 0; beginX < endX; beginX++) {
            double wx = beginX * mDefaultAngularFrequency;
            float beginY = (float) (mDefaultWaterLevel + mDefaultAmplitude * Math.sin(wx));
            canvas.drawLine(beginX, beginY, beginX, -1, wavePaint);
            waveY[beginX] = beginY;
        }

        wavePaint.setColor(mFrontWaveColor);
        final int wave2Shift = (int) (mDefaultWaveLength / 4);
        for (int beginX = 0; beginX < endX; beginX++) {
            canvas.drawLine(beginX, waveY[(beginX + wave2Shift) % endX], beginX, -1, wavePaint);
        }
  • 2、在HeaderWaveView中提供get方法返回sin函数的height
[Java] 查看源文件 复制代码
public float getSinHeight() {
        //sin函数的height
        return (float) (getHeight() * mWaterLevelRatio
                + mAmplitudeRatio / DEFAULT_AMPLITUDE_RATIO * mDefaultAmplitude * Math.sin(mWaveShiftRatio * getWidth() * mDefaultAngularFrequency));
    }
动画实现创建HeaderWaveHelper类进行动画管理,动画采用AnimatorSet进行组合。通过设置waterLevelRatio波浪水位、amplitudeRatio波浪振幅、mDefaultFloatViewRotation头像旋转调整角,调整整个效果。
当动画cancel时,不能很鬼畜的直接将振幅调零,start时也同理,应该缓慢过渡。
[Java] 查看源文件 复制代码
public void cancel() {
        if (mAnimatorSet != null && !mHasCancel) {
            mHasCancel = true;
            mHasStart = false;
            mAmplitudeAnim.cancel();
            amplitudeChangeAnim = ObjectAnimator.ofFloat(
                    mHeaderWaveView, "amplitudeRatio", mDefaultAmplitudeRatioT, 0.00001f);
            amplitudeChangeAnim.setDuration(1000);
            amplitudeChangeAnim.start();
            amplitudeChangeAnim.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animator) {

                }
                @Override
                public void onAnimationEnd(Animator animator) {
                    if (mFloatView.getAnimation() != null) {
                        mFloatView.getAnimation().cancel();
                    }
                }

                @Override
                public void onAnimationCancel(Animator animator) {

                }

                @Override
                public void onAnimationRepeat(Animator animator) {

                }
            });
        }
    }
public void start() {
        mHeaderWaveView.setShowWave(true);
        if (mAnimatorSet != null && !mHasStart) {
            mHasStart = true;
            mHasCancel = false;
            if (amplitudeChangeAnim != null) {
                amplitudeChangeAnim = ObjectAnimator.ofFloat(
                        mHeaderWaveView, "amplitudeRatio", 0.00001f, mDefaultAmplitudeRatioF);
                amplitudeChangeAnim.setDuration(1000);
                amplitudeChangeAnim.start();
            }

            if (!mIsFirst) {
                mAnimatorSet.start();
                mIsFirst = true;
            }


        }
    }
三个动画A、B、C组合成一个AnimatorSet,playTogether,其中A、B是循环的,而C需要实现三个阶段,从0到0.5的过渡(单次),0.5-0.8的来回(循环),停止时再由当前循环数值到0(单次)。我的实现思路是,由A、B、C的循环构成AnimatorSet,在停止事件触发后cancel C的动画,然后new一个动画实现C的当前数值到0,开始同理。而整个结束开始过程中AnimatorSet一直运行。老是感觉这种动画实现方法不优雅,不知道有没有其他更好的实现方式。
还有一个小细节,view如果是在onCreat中获取,是无法获得view.getHeight(),采用view.getMeasuredHeight()代替,不理解可以去看看View的绘制机制。
[Java] 查看源文件 复制代码
waveShiftAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                //获取sin函数的height,更新mFloatView
                float value = mHeaderWaveView.getSinHeight() - mFloatView.getMeasuredHeight();
                mFloatView.setRotation(value + mDefaultFloatViewRotation);
                mFloatView.setTranslationY(value);
                mFloatView.invalidate();
            }
        });



相关源码推荐:

我来说两句
所有评论(211)
kk041kk 2016-8-30 11:07:40
好好 学习了 确实不错
回复
manmanyun 2016-8-30 11:13:30
感谢大神~
回复
337828932 2016-8-30 11:15:08
虽不明,但觉厉!
回复
yanghaiju2012 2016-8-30 11:38:11
感谢分享,楼主V5~
回复
葫芦_eRDJw 2016-8-30 11:40:12
感谢分享,安卓巴士有你更精彩:lol
回复
yukong 2016-8-30 11:40:43
感谢分享,安卓巴士有你更精彩:lol
回复
孙林 2016-8-30 11:42:21
楼主用心了,内容非常精彩。
回复
提取码:  下载次数:132 状态:已购或VIP 售价:10(原价:10)金钱 下载权限:初级码农 
8008 1 132
代码贡献英雄榜
用户名 下载数
联系我们
首页/微信公众账号投稿
帖子代码编辑/版权问题
QQ:435399051,1294855032
如何获得代码达人称号?
如何成为签约作者?
领先的中文移动开发者社区
18620764416
7*24全天服务
意见反馈:1294855032@qq.com

扫一扫关注我们

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粤ICP备15117877号 )