美文网首页
仿饿了么动画

仿饿了么动画

作者: 连续三届村草 | 来源:发表于2017-02-07 14:30 被阅读208次

    仿饿了么动画

    最近项目Release完毕,闲暇之余给公司内部的小卖部app升下级(一个人撸完了design+code),添加了一个商城功能,因为每天都用饿了么点外卖,比较喜欢饿了么点餐落入购物车的动画,所以说自己实现了一个,做一点微小的笔记。

    整个界面相关元素有RecyclerView + FloatActionButton,动画是点击item出现一个图标以抛物线落入购物车。

    整体的思路是:

    1. 点击itemView获取到相关location[]、height、width、position参数
    2. 在View层中拿到的参数初始化动画View、ViewGroup
    3. 初始化动画、开始动画

    Step1: RecyclerView.Adapter类

       /**
         * 在RecyclerView.Adapter中的itemView添加点击事件,用于获取这个itemView在窗口(Window)中的位置信息(location[])。
         * 这里传递的参数还包括itemView的宽高和position,用于更细致的调整动画的初始位置和更新相关数据。
         * 这里发送点击事件没有使用接口而是用了RxBus调用startAddToCartAnim(),效果和平时使用的接口一致。
         */
    
    holder.itemView.setOnClickListener(v -> {
                int height = holder.itemView.getHeight();
                int width = holder.itemView.getWidth();
                int[] startLocation = new int[2];
                holder.itemView.getLocationInWindow(startLocation);
                String name = list.get(holder.getLayoutPosition()).getName();
                RxBus.getInstance().send(new F01_01_ShopFragment.OnRecyclerItemClickEvent(startLocation, height, width, holder.getLayoutPosition(), name));
            });
    

    Step2: Activity/Fragment类

        private void startAddToCartAnim(int[] startLocation, int height, int width) {
            //初始化startLocation、endLocation坐标
            int[] endLocation = new int[2];
            orderFloatingactionbutton.getLocationInWindow(endLocation);
    
            //初始化动画以及parentLayout的参数
            ImageView animView = new ImageView(getContext());
            animView.setImageResource(R.drawable.ic_card_giftcard_red_400_36dp);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            params.leftMargin = startLocation[0] + width / 2;
            params.topMargin = startLocation[1];
            //获取parentLayout以及添加动画view到parentLayout
            getAnimLayout().addView(animView, params);
    
            //设定动画类型(使用简单的TranslateAnimation,通过不同的Interpolator来达到抛物线效果)
            TranslateAnimation animationX = new TranslateAnimation(0, endLocation[0] - startLocation[0] - width / 2, 0, 0);
            animationX.setInterpolator(new LinearInterpolator());
            animationX.setFillAfter(true);
            TranslateAnimation animationY = new TranslateAnimation(0, 0, 0, endLocation[1] - startLocation[1]);
            animationY.setInterpolator(new AccelerateInterpolator());
            animationY.setFillAfter(true);
            AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0.5f);
            AnimationSet set = new AnimationSet(false);
            set.addAnimation(animationX);
            set.addAnimation(animationY);
            set.addAnimation(alphaAnimation);
            set.setDuration(500);
            //执行动画
            animView.startAnimation(set);
    
            set.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
    
                }
    
                @Override
                public void onAnimationEnd(Animation animation) {
                    animView.setVisibility(View.GONE);
                }
    
                @Override
                public void onAnimationRepeat(Animation animation) {
    
                }
            });
    
        }
        
        /**
         * 获取点击动画所在的parentLayout(因为动画的坐标用的getLocationInWindow获取,所以这里也以DecorView的区域为parentLayout)
         * 这里的animLayout和animView的实例不能复用
         */
    
        private ViewGroup getAnimLayout() {
            ViewGroup rootView = (ViewGroup) getActivity().getWindow().getDecorView();
            LinearLayout animLayout = new LinearLayout(getContext());
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.MATCH_PARENT);
            animLayout.setLayoutParams(lp);
            animLayout.setId(Integer.MAX_VALUE - 1);
            animLayout.setBackgroundResource(android.R.color.transparent);
            rootView.addView(animLayout);
            return animLayout;
        }
    
    • 补充:
      这里以item中间为坐标开始动画,以最精简的代码实现了基本动画,开发者可以以此为基础实现更复杂更精细的动画。
      比如:还可以根据location[]、height、width调整动画位置或是重写OnTouchListener根据触摸位置设定开始动画。

    相关文章

      网友评论

          本文标题:仿饿了么动画

          本文链接:https://www.haomeiwen.com/subject/fozpittx.html