Android开发Android知识Android技术知识

仿酷狗添加音乐动画

2018-02-01  本文已影响0人  _独爱夜色

前言

又到年底了,有好工作的开心过年,像我这样的准备换工作的萌新只有忧虑中过年,因为已经裸辞,好在今年还存了点钱过年回来找工作还是可以苟一段时间的。所以闲下来便随便写写东西,打发时间同时也可以增加点简历的丰富度。先看效果图吧

效果图

2018-02-01_10_51_25.gif

实现原理

实现原理很简单就是添加一个View的属性动画,动画效果用贝塞尔二阶曲线实现
贝塞尔曲线公式如下


Bézier .jpg

所以只需要套入公式便可以使用。
属性动画中有两个重点,有一个是setInterpolator(),还有一个是setEvaluator()。前者是控制速率,也就是先快后慢还是匀速还是什么等等,而后者则是控制如何变化,比如直线还是曲线。很明显我们此功能要用后者的方法。使用方式如下

 valueAnimator.setEvaluator(new TypeEvaluator<Point>() {
            @Override
            public Point evaluate(float t, Point startValue, Point endValue) {
                Point controllPoint = new Point(endX, startY);//贝塞尔曲线控制点
                int x = (int) ((1 - t) * (1 - t) * startValue.x + 2 * t * (1 - t) * controllPoint.x + t * t * endValue.x);//根据公式算出X
                int y = (int) ((1 - t) * (1 - t) * startValue.y + 2 * t * (1 - t) * controllPoint.y + t * t * endValue.y);//根据公式算出Y
                return new Point(x, y);
            }
        });

接下来是给当前View赋值

  valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Point point = (Point) animation.getAnimatedValue();
                setX(point.x);
                setY(point.y);
                setRotation(point.x * 2);
            }
        });

这样便完成了一个动画
但在ListView使用中发现存在很多问题
首先是如果在Item的布局中添加此View那么View的显示范围只有Item的高度,也就是说超过高度后就看不见了,很明显这不是我们要的效果,所以必须将此View添加到ListView的上层布局中

 KuGouView kuGouView = new KuGouView(context);
 kuGouView.setImageResource(R.mipmap.add);
 viewGroup.addView(kuGouView);//ViewGroup为ListView的父布局

到此本以为大功告成,结果没想到又出了问题


2018-02-01_11_13_47.gif

点击位置和动画位置不同。这个问题为纠结了半天,最后感觉应该是获取View位置的方法的问。

  int location[] = new int[2];
  v.getLocationInWindow(location);

看了这个方法我就像是否与Title,Actionbar有关,仔细看下发现偏移的位置和Title高度差不多。于是网上各种搜索终于搜到一篇
https://www.cnblogs.com/wjtaigwh/p/6689684.html
其中意思是

所以getLocationInWindow方法获取的是状态栏+contentView的大小,而不是我们以为的contentView的大小,知道了这里我们基本上就知道怎么解决这个问题了,只需要减去这个高度就可以了,我们可以直接减去mRecyclerView的Y坐标即可
我这里的写法是

  int distance[] = new int[2];
  listView.getLocationInWindow(distance);
  kuGouView.startAnimation(location[0], location[1] - distance[1], rlt.getMeasuredWidth() / 2, play[1]);

PS:其实我遇到的问题这里面都有,而且比我写的详细的多,本人只是大概的写一下自己的方式,如果想了解更多可以去这个地址看,感谢这位大神。

最后GitHub就不给了就一个View页面的问题 给个代码吧

package com.ren.framework.kugoulistview.widget;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ViewTreeObserver;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;

/**
 * Created by Ren on 2018/1/31.
 * TODO
 */

public class KuGouView extends ImageView {


    public KuGouView(Context context) {
        super(context);
        init();
    }

    public KuGouView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public KuGouView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
    }

    public void startAnimation(int endX, int endY) {
        startAnimation((int) getX(), (int) getY(), endX, endY);
    }

    public void startAnimation(int startX, final int startY, final int endX, int endY) {
        ValueAnimator valueAnimator = new ValueAnimator();
        valueAnimator.setObjectValues(new Point(startX, startY), new Point(endX, endY));
        valueAnimator.setDuration(600);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.setEvaluator(new TypeEvaluator<Point>() {
            @Override
            public Point evaluate(float t, Point startValue, Point endValue) {
                Point controllPoint = new Point(endX, startY);//贝塞尔曲线控制点
                int x = (int) ((1 - t) * (1 - t) * startValue.x + 2 * t * (1 - t) * controllPoint.x + t * t * endValue.x);//根据公式算出X
                int y = (int) ((1 - t) * (1 - t) * startValue.y + 2 * t * (1 - t) * controllPoint.y + t * t * endValue.y);//根据公式算出Y
                return new Point(x, y);
            }
        });
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Point point = (Point) animation.getAnimatedValue();
                setX(point.x);
                setY(point.y);
                setRotation(point.x * 2);
            }
        });
        valueAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                if (listener != null) {
                    listener.onStart(animation);
                }
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (listener != null)
                    listener.onComplete(animation);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        valueAnimator.start();
    }

    public interface AnimationListener {
        void onStart(Animator animation);

        void onComplete(Animator animation);

    }

    private AnimationListener listener;

    public void setAnimationListener(AnimationListener listener) {
        this.listener = listener;
    }
}

结尾

年底了祝大家技术更上一层楼,有工作的甚至加薪,没工作找工作的找到满意的工作
新年快乐!

上一篇下一篇

猜你喜欢

热点阅读