android仿百度外卖波浪_仿百度外卖水波纹

套路一:

无图无真相

这里要感谢两位大神的博客 参照很多

下面的4个小球完全参照 Android仿百度贴吧客户端Loading小球 实现 有意向的同学可以点击过去看看

#######套路二:

分析

顶部有水波纹不断的浮动

头像跟着水波纹的浮动而浮动

解决

于是马上看源码

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

canvas.setDrawFilter(mDrawFilter);

mAbovePath.reset();

mBelowWavePath.reset();

φ-=0.1f;

float y,y2;

double ω = 2*Math.PI / getWidth();

mAbovePath.moveTo(getLeft(),getBottom());

mBelowWavePath.moveTo(getLeft(),getBottom());

for (float x = 0; x <= getWidth(); x += 20) {

/**

* y=Asin(ωx+φ)+k

* A—振幅越大,波形在y轴上最大与最小值的差值越大

* ω—角速度, 控制正弦周期(单位角度内震动的次数)

* φ—初相,反映在坐标系上则为图像的左右移动。这里通过不断改变φ,达到波浪移动效果

* k—偏距,反映在坐标系上则为图像的上移或下移。

*/

y = (float) (8 * Math.cos(ω * x + φ) +8);

y2 = (float) (8 * Math.sin(ω * x + φ));

mAbovePath.lineTo(x, y);

mBelowWavePath.lineTo(x, y2);

//回调 把y坐标的值传出去(在activity里面接收让小机器人随波浪一起摇摆)

mWaveAnimationListener.OnWaveAnimation(y);

}

mAbovePath.lineTo(getRight(),getBottom());

mBelowWavePath.lineTo(getRight(),getBottom());

canvas.drawPath(mAbovePath,mAboveWavePaint);

canvas.drawPath(mBelowWavePath,mBelowWavePaint);

postInvalidateDelayed(20);

}

What?ω φ 这些是什么意思啊 奈何这个大神内功太深厚 这一招一式打出来实在是参悟不透啊 估计再看下去会走火入魔,赶紧离开。

但是心有不甘,于是静坐冥想1小时。。。。

1.水波纹 不就是贝塞尔曲线嘛 用path.quadTo()能解决 再借鉴下Android仿百度贴吧客户端Loading小球中的周期函数思想 让水波纹不断的浮动起来

2.图片随水波纹的浮动而浮动 图片在x轴是固定不变得 只是在y轴有上下的波动 只要能获取贝塞尔曲线中 path经过与图片x轴重合的y轴的坐标点就ok 刚好Android中有PathMeasure类结合Path 可以做到

想好这些 就开始撸码

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

Path fulPath = getActionFulPath(currentPercent);

canvas.drawPath(fulPath,fulPaint);

Path idmPath=getActionDimPath(currentPercent);

canvas.drawPath(idmPath,dimPaint);

}

private Path getActionDimPath(float percent) {

int quadWidth = width / 4;

int quadHeight = height/3;

Path path=new Path();

int x=-width;

x+=percent*width;

path.moveTo(x,height/2);

//第一段

path.rQuadTo(quadWidth,-quadHeight,quadWidth*2,0);

path.rQuadTo(quadWidth,quadHeight,quadWidth*2,0);

//第二段

path.rQuadTo(quadWidth,-quadHeight,quadWidth*2,0);

path.rQuadTo(quadWidth,quadHeight,quadWidth*2,0);

//闭合

path.lineTo(x+width*2,height);

path.lineTo(x,height);

path.close();

//关联一个path

measure.setPath(path,true);

//获取path到view中心的长度

float length = Math.abs(x)+ (width / 2);

//获取该path该位置时的坐标值

measure.getPosTan(length,pos,null);

//将y坐标的值通过接口传递出去

onWaveAnimationListener.onWaveAnimation(pos[1]+currentPercent);

return path;

}

注意这里是使用的path.rQuadTo() 是相对上次结束坐标来进行二次贝塞尔曲线的 不是相对于原点

上面的path差不多是这样的(ps:实在不会用AI绘图 若侵权了立马删除)

声明传递数据的接口

public void setOnWaveAnimationListener(OnWaveAnimationListener listener){

onWaveAnimationListener =listener;

}

//接口

public interface OnWaveAnimationListener{

void onWaveAnimation(float y);

}

仔细看效果图 有2个贝塞尔曲线 所以这个贝塞尔曲线与上面那个是相反的

public Path getActionFulPath(float percent) {

int quadWidth = width / 4;

int quadHeight = height/3;

Path path=new Path();

int x=-width;

x+=percent*width;

path.moveTo(x,height/2);

path.rQuadTo(quadWidth,quadHeight,quadWidth*2,0);

path.rQuadTo(quadWidth,-quadHeight,quadWidth*2,0);

path.rQuadTo(quadWidth,quadHeight,quadWidth*2,0);

path.rQuadTo(quadWidth,-quadHeight,quadWidth*2,0);

path.lineTo(x+width*2,height);

path.lineTo(x,height);

path.close();

return path;

}

在初始化的时候 启动属性动画 让水波纹浮动起来

private void init() {

fulPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

fulPaint.setColor(Color.parseColor("#fafafa"));

fulPaint.setStyle(Paint.Style.FILL);

dimPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

dimPaint.setColor(Color.parseColor("#fafafa"));

dimPaint.setAlpha(80);

dimPaint.setStyle(Paint.Style.FILL);

//画布抗锯齿

//mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);

measure = new PathMeasure();

ValueAnimator animator=ValueAnimator.ofFloat(0,1);

animator.setDuration(3000);

animator.setInterpolator(new LinearInterpolator());

animator.setRepeatCount(ValueAnimator.INFINITE);

animator.setRepeatMode(ValueAnimator.RESTART);

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

//不断改变currentPercent的值 让水波纹不断的浮动起来

currentPercent=animation.getAnimatedFraction();

invalidate();

}

});

animator.start();

}

最后布局文件

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context="com.example.sharemodule.LoadingActivity">

android:layout_width="match_parent"

android:layout_height="200dp"

android:background="#29a3fe">

android:id="@+id/waveView"

android:layout_width="match_parent"

android:layout_height="15dp"

android:layout_gravity="bottom" />

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:layout_marginTop="10dp"

android:text="百度外卖"

android:textColor="@android:color/white"

android:textSize="18sp"

android:textStyle="bold" />

android:id="@+id/image"

android:layout_width="50dp"

android:layout_height="50dp"

android:layout_gravity="bottom|center_horizontal"

android:scaleType="centerCrop" />

Activity中实现

public class LoadingActivity extends AppCompatActivity {

private static final String TAG= LoadingView.class.getSimpleName();

@BindView(R.id.image)

ImageView imageView;

@BindView(R.id.waveView)

BaiduTopView waveView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_loading);

ButterKnife.bind(this);

Glide.with(this).load(R.drawable.head_gif).asGif().into(imageView);

}

@Override

protected void onResume() {

super.onResume();

final FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) imageView.getLayoutParams();

waveView.setOnWaveAnimationListener(new BaiduTopView.OnWaveAnimationListener() {

@Override

public void onWaveAnimation(float y) {

Log.e(TAG,"坐标:"+y);

layoutParams.bottomMargin= (int)y;

imageView.setLayoutParams(layoutParams);

}

});

}

}

哎 先去找AI画图教程学习下 不然还有诸多不方便 如果有什么疑问的地方请随时留言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值