2024年最新Android-_巧_仿蚂蚁森林水滴动效,2024年最新美团点评社招面试流程

推荐学习资料

  • Android进阶学习全套手册

  • Android对标阿里P7学习视频

  • BAT TMD大厂Android高频面试题

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

###需求

APP需要做一个类似蚂蚁森林的功能模块,动效和蚂蚁森林接近,水滴最多6滴,根据经验来说这种交互肯定用RN、H5亦或游戏引擎来做最佳,但是没办法产品提了我们也得做。

**需求:**APP需要做一个类似蚂蚁森林的功能模块,动效和蚂蚁森林接近,水滴最多6滴,根据经验来说这种交互肯定用RN、H5亦或游戏引擎来做最佳,但是没办法产品提了我们也得做。

###老规矩还是先上GIF

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

也许看到这个图,你就不想再继续看下去了,心想这个动画很简单啊,不就是创建循环创建view,再给每个view的动画,每个view的开始运动的方向随机,再给一个加速器就搞定了嘛,如果你也是这样想那就该把这个文章看完了

###分析:

  • 首先创建水滴动画、缩放伴随透明度变化
  • 消失时缩放伴随移动
  • 水滴展示中是一直上下浮动的
  • 每个水滴上下浮动的方向不定
  • 每个水滴运动的速度时而快时而慢(这点也许你看不出,所以我再把抖动的范围加大再来一个GIF)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

首先我们肯定不能用每个view对应一个动画来处理,因为如果我是100低水滴,那岂不是要100个动画,这不得卡死呀,所以肯定是一个动画来完成,开始我第一想到的也是用ValueAnimator来做,但是一个ValueAnimator怎么去控制每个view的运动方向呢,有可能你会说每个view在初始化的时候给一个反向,确实可以解决运动方向不同的问题,但是怎么解决view运动的快慢不一样,并且时而快时而慢呢,并且每个view的运动规律根本不一样,最后我选择了handler来处理。

/*

  • 处理思路:
  • ->将森林水滴作为一个总体而不是单个的view,自定义一个ViewGroup容器
    
  • ->循环创建view
    
  • ->为view随机设置位置(在一些固定的集合中随机选取,尽量保证水滴不重合)
    
  • ->为view设置一个初始的运动方向(注:由于每个view的运动方向不同,所以我选择将方向绑定到view的tag中)
    
  • ->为view设置一个初始的速度(同理:将初始速度绑定到view的tag中)
    
  • ->添加view到容器中,并缩放伴随透明度显示
    
  • ->开启handler达到view上下位移动画(注意点:这里我们需要定一个临界值来改变view的速度,到达view时而快时而慢的目的)
    
  • ->点击view后,缩放、透明度伴随位移移除水滴
    
  • ->界面销毁时停止调用handler避免内存泄漏,空指针等异常
    
  • */

###正题

下面的讲解我将会贴出重要部分的代码,也就是思路关键点,完整代码还是请clone项目。

  • 首先创建view

创建view代码块:

/**

  • 添加水滴view
    */
    private void addWaterView(List waters) {
    for (int i = 0; i < waters.size(); i++) {
    final Water water = waters.get(i);
    View view = mInflater.inflate(mChildViewRes, this, false);
    TextView tvWater = view.findViewById(R.id.tv_water);
    view.setTag(water);
    tvWater.setText(String.valueOf(water.getNumber()) + “g”);
    view.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
    handViewClick(view);
    }
    });
    //随机设置view动画的方向
    view.setTag(R.string.isUp, mRandom.nextBoolean());
    setChildViewLocation(view);
    mViews.add(view);
    addShowViewAnimation(view);
    }
    }

解释

创建view最重要的两件事情:
1、给view一个随机的方向并且保存到view的tag里
//随机设置view动画的方向
view.setTag(R.string.isUp, mRandom.nextBoolean());
2、随机设置view的位置(我这里并非完全随机,而是给了一些值,然后随机选择这些值)、这里用了一个新的集合保存已经选择到的数,下次选择的时候排除这些值,因为最好水滴不要完全重合嘛。
/但是其实这不是我最终的方法,先往下看吧,还有彩蛋/
/**

  • 获取x轴或是y轴上的随机值
  • @return
    */
    private double getX_YRandom(List choseRandoms,List saveRandoms) {
    float random = 0;
    while (random == 0 || saveRandoms.contains(random)) {
    random = choseRandoms.get(mRandom.nextInt(choseRandoms.size()));
    }

saveRandoms.add(random);
return random;
}

  • 动画显示view:

/**

  • 添加显示动画

  • @param view
    */
    private void addShowViewAnimation(View view) {
    addView(view);
    view.setAlpha(0);
    view.setScaleX(0);
    view.setScaleY(0);
    view.animate().alpha(1).scaleX(1).scaleY(1).setDuration(ANIMATION_SHOW_VIEW_DURATION).start();
    }

  • 接下来为view设置一个初始的随机加速度(其实也是随机在已有的值中选取,因为速度不能相差太大)

/控制水滴动画的快慢/
private List mSpds = Arrays.asList(0.5f, 0.3f, 0.2f, 0.1f);
/
*

  • 设置所有子view的加速度
    /
    private void setViewsSpd() {
    for (int i = 0; i < mViews.size(); i++) {
    View view = mViews.get(i);
    setSpd(view);
    }
    }
    /
    *

  • 设置View的spd

  • @param view
    */
    private void setSpd(View view) {
    float spd = mSpds.get(mRandom.nextInt(mSpds.size()));
    //将这个随机的位移速度保存到view的tag里,这里两个参数setTag()方法不大了解的可以百度一下
    view.setTag(R.string.spd, spd);
    }

  • 接下来就是开启动画,使用handler设置view的偏移量了,这部分也是很关键的,还包括了处理水滴时而快时而慢的处理

/**

  • 设置偏移
    */
    private void setOffSet() {
    for (int i = 0; i < mViews.size(); i++) {
    View view = mViews.get(i);
    //拿到上次view保存的速度
    float spd = (float) view.getTag(R.string.spd);
    //水滴初始的位置
    float original = (float) view.getTag(R.string.original_y);
    float step = spd;
    boolean isUp = (boolean) view.getTag(R.string.isUp);
    float translationY;
    //根据水滴tag中的上下移动标识移动view
    if (isUp) {
    translationY = view.getY() - step;
    } else {
    translationY = view.getY() + step;
    }
    //对水滴位移范围的控制
    if (translationY - original > CHANGE_RANGE) {
    translationY = original + CHANGE_RANGE;
    view.setTag(R.string.isUp, true);
    } else if (translationY - original < -CHANGE_RANGE) {
    translationY = original - CHANGE_RANGE;
    // 每次当水滴回到初始点时再一次设置水滴的速度,从而达到时而快时而慢
    setSpd(view);
    view.setTag(R.string.isUp, false);
    }
    view.setY(translationY);
    }
    }

  • 接下来水滴点击后的消失动画

/**

  • 动画移除view
  • @param view
    */
    private void animRemoveView(final View view) {
    final float x = view.getX();
    final float y = view.getY();
    //计算直线距离
    float space = getDistance(new Point((int) x, (int) y), mDestroyPoint);

ValueAnimator animator = ValueAnimator.ofFloat(x, 0);
//根据距离计算动画执行时间
animator.setDuration((long) (REMOVE_DELAY_MILLIS / mMaxSpace * space));
animator.setInterpolator(new LinearInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
if (isCancelAnimtion) {
return;
}
float value = (float) valueAnimator.getAnimatedValue();
float alpha = value / x;
float translationY = y + (x - value) * (maxY - y) / x;
setViewProperty(view, alpha, translationY, value);
}
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
//结束时从容器移除水滴
removeView(view);
}
});

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上我搜集整理的2019-2021BATJ 面试真题解析,我把大厂面试中常被问到的技术点整理成了PDF,包知识脉络 + 诸多细节。

节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

《960全网最全Android开发笔记》

《379页Android开发面试宝典》

历时半年,我们整理了这份市面上最全面的安卓面试题解析大全
包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

如何使用它?

1.可以通过目录索引直接翻看需要的知识点,查漏补缺。
2.五角星数表示面试问到的频率,代表重要推荐指数

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

腾讯、字节跳动、阿里、百度等BAT大厂 2019-2021面试真题解析

资料太多,全部展示会影响篇幅,暂时就先列举这些部分截图

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

)]

资料太多,全部展示会影响篇幅,暂时就先列举这些部分截图

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 12
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值