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

    假设你常常听歌。你会发现歌曲app的背景会随着音乐移动的,从左到右或者从上到下。这样的动画尽管简单,可是这里有一个技巧。

    假设你还不明确这样的动效看看以下的demo
    演示动画
    (很多其它具体请參考:https://github.com/flavienlaurent/PanningView
    一,使用setImageMatrix播放图片动画
    以下是官方文档给出的解释
    这里写图片描写叙述
    你能够看到这里的解释非常easy。就是取代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);
        }
    }
  • 相关阅读:
    硬盘
    [编译] 6、开源两个简单且有用的安卓APP命令行开发工具和nRF51822命令行开发工具
    [编译] 5、在Linux下搭建安卓APP的开发烧写环境(makefile版)—— 在Linux上用命令行+VIM开发安卓APP
    [Zephyr] 1、在linux上安装Zephyr-OS并跑DEMO
    [编译] 4、在Linux下搭建nRF51822的开发烧写环境(makefile版)
    [BlueZ] 2、使用bluetoothctl搜索、连接、配对、读写、使能notify蓝牙低功耗设备
    [BlueZ] 1、Download install and use the BlueZ and hcitool on PI 3B+
    [python] 3 、基于串口通信的嵌入式设备上位机自动测试程序框架(简陋框架)
    [ARCH] 1、virtualbox中安装archlinux+i3桌面,并做简单美化
    [编译] 3、在Linux下搭建51单片机的开发烧写环境(makefile版)
  • 原文地址:https://www.cnblogs.com/llguanli/p/7186893.html
Copyright © 2011-2022 走看看