zoukankan      html  css  js  c++  java
  • 像音乐播放App一样移动背景

    如果你经常听歌,你会发现歌曲app的背景会随着音乐移动的,从左到右或者从上到下,这种动画虽然简单,但是这里有一个技巧。如果你还不明白这种动效看看下面的demo
    演示动画
    (更多详细请参考:https://github.com/flavienlaurent/PanningView
    一,使用setImageMatrix播放图片动画
    下面是官方文档给出的解释
    这里写图片描述
    你可以看到这里的解释很简单,就是代替ImageView的图像矩阵,然后configureBounds和invalidate被调用。
    在java代码中我们可以设置Matrix的scaleType

    mImageView.setScaleType(ScaleType.MATRIX)

    或者在xml文件中设置

    android:scaleType="matrix"

    下面是ImageView的初始矩阵(matrix)
    这里写图片描述
    在x和y方向上放大2倍

    final Matrix matrix = new Matrix();
    matrix.postScale(2, 2);
    imageView.setImageMatrix(matrix);

    这里写图片描述

    final Matrix matrix = new Matrix();
    matrix.postScale(2, 2);
    matrix.postRotate(15);
    imageView.setImageMatrix(matrix);

    这里写图片描述
    二,使你的图片移动
    首先我们需要计算ImageView当前方向(水平,纵向)和图片当前方向的比例,就比如水平方向吧,我们就要让图片和view的高度相同,横向放大或者缩小。

    float scaleFactor = (float)imageView.getHeight() / (float) drawable.getIntrinsicHeight();
    mMatrix.postScale(scaleFactor, scaleFactor);

    这样我们就能保证图片的高和ImageView相同,并且填充满ImageView.
    接下来我们就让ImageView的图片移动,我们要用到一个强大的Android动画框架:ValueAnimator,其原理就是利用ImageView的图像矩阵在x轴方向变换移动。

    mAnimator = ValueAnimator.ofFloat(0, 100);
    mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
          float value = (Float) animation.getAnimatedValue();
          matrix.reset();
          matrix.postScale(scaleFactor, scaleFactor);
          matrix.postTranslate(-value, 0);
          imageView.setImageMatrix(matrix);
    
      }
    });
    mAnimator.setDuration(5000);
    mAnimator.start();

    整个代码如下:

    package com.testimageview;
    import android.animation.Animator;
    import android.animation.AnimatorListenerAdapter;
    import android.animation.ValueAnimator;
    import android.app.Activity;
    import android.graphics.Matrix;
    import android.graphics.RectF;
    import android.os.Bundle;
    import android.widget.ImageView;
    
    public class MainActivity extends Activity{
        private static final int RightToLeft = 1;
        private static final int LeftToRight = 2;
        private static final int DURATION = 5000;
    
        private ValueAnimator mCurrentAnimator;
        private final Matrix mMatrix = new Matrix();
        private ImageView mImageView;
        private float mScaleFactor;
        private int mDirection = RightToLeft;
        private RectF mDisplayRect = new RectF();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
          mImageView = (ImageView) findViewById(R.id.imageView);
    
          mImageView.post(new Runnable() {
              @Override
              public void run() {
                  mScaleFactor = (float)  mImageView.getHeight() 
                          / (float) mImageView.getDrawable().getIntrinsicHeight();
                  mMatrix.postScale(mScaleFactor, mScaleFactor);
                  mImageView.setImageMatrix(mMatrix);
                  animate();
              }
          });
    
        }
    
        private void animate() {
          updateDisplayRect();
          if(mDirection == RightToLeft) {
              animate(mDisplayRect.left, mDisplayRect.left
                      - (mDisplayRect.right - mImageView.getWidth()));
          } else {
              animate(mDisplayRect.left, 0.0f);
          }
        }
    
        private void animate(float from, float to) {
          mCurrentAnimator = ValueAnimator.ofFloat(from, to);
          mCurrentAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
              @Override
              public void onAnimationUpdate(ValueAnimator animation) {
                  float value = (Float) animation.getAnimatedValue();
    
                  mMatrix.reset();
                  mMatrix.postScale(mScaleFactor, mScaleFactor);
                  mMatrix.postTranslate(value, 0);
    
                  mImageView.setImageMatrix(mMatrix);
    
              }
          });
          mCurrentAnimator.setDuration(DURATION);
          mCurrentAnimator.addListener(new AnimatorListenerAdapter() {
              @Override
              public void onAnimationEnd(Animator animation) {
                  if(mDirection == RightToLeft)
                      mDirection = LeftToRight;
                  else
                      mDirection = RightToLeft;
    
                  animate();
              }
          });
          mCurrentAnimator.start();
        }
    
        private void updateDisplayRect() {
          mDisplayRect.set(0, 0, mImageView.getDrawable().getIntrinsicWidth(),
                  mImageView.getDrawable().getIntrinsicHeight());
          mMatrix.mapRect(mDisplayRect);
        }
    }
  • 相关阅读:
    Django连接SQL Server,安装相关扩展包及相关配置
    安装pipenv
    报错及网络上的解决方案
    Nucleus-SE迁移:未实现的设施和兼容性
    RTOS诊断和错误检查
    Nucleus SE RTOS初始化和启动
    Nucleus 实时操作系统中断(下)
    Nucleus 实时操作系统中断(上)
    系统时间
    应用程序计时器
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6468501.html
Copyright © 2011-2022 走看看