像音乐播放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);
    }
}
时间: 2024-10-12 20:39:58

像音乐播放App一样移动背景的相关文章

音乐播放APP初步开发(二)自动登录和 扫码识别设备

在登录页面login.html初次登录时,发送post请求,对返回的数据判断,如果code=0,表示已经登录成功的用户.则将其_id数据设置到类似cookie的全局中去. if(data.code==0){ window.localStorage.setItem("user",data.data._id); // console.log(window.localStorage.getItem("user")); console.log(JSON.stringify(

Android开发实战之简单音乐播放器

最近开始学习音频相关.所以,很想自己做一个音乐播放器,于是,花了一天学习,将播放器的基本功能实现了出来.我觉得学习知识点还是蛮多的,所以写篇博客总结一下关于一个音乐播放器实现的逻辑.希望这篇博文对你的学习和生活有所帮助.效果图: **实现逻辑** 在市面上的音乐播放app,即时你关了.那么一样会在后台播放,所以播放的逻辑应该写在Service中.并且能够实现Service和Activity之间进行通信.那么Service是四大组件之一,所以在使用的时候一定不要忘了在配置文件中声明一下. <ser

微信小程序(有始有终,全部代码)开发---跑步App+音乐播放器

我的微信开发者工具 开篇语 好不容易,终于把所有的基础课程全部看完了!昨天,我很高兴地开始了看别人做的项目进行深度的学习.其实也说不上是项目吧,更多的像是一种给新手看的示例代码.然后我在这些代码上面进行我自己的改进.最后也就有了接下来我会给大家带来的这篇文章中的项目.这个项目是完整的,它包括了一个原本的示例代码中带着的莫名其妙的动画组件(可能是为了更多额展示微信小程序的控件体系)以及跑步的组件,还有我后来自己加上去的一个音乐播放组件.总共也就有了三个的功能:动画效果展示:跑步的定时以及定位功能:

基于我们3组的网易云APP制作,找的APlayer H5音乐播放器

APlayer是一个非常漂亮的HTML5音频播放器,UI参考自网易云音乐外链播放器.它将audio标签封装,并结合CSS制作出漂亮的播放器UI,它支持设置歌名.歌手和歌词,可以设置是否自动播放,支持缩略图,支持播放进度以及设置播放源. HTML 首先是要加载播放器样式文件,这个播放器的样式酷似网易云音乐播放器.接着载入APlayer.js文件.然后在body中加入播放器div#player1,用于显示播放.<link rel="stylesheet" href="APl

音乐类型APP:如何添加正播放的音乐进度,歌手名,图片等信息显示 到锁屏和控制中心

使用的是豆瓣的音频播放类 导入头文件#import <MediaPlayer/MediaPlayer.h> #import <MediaPlayer/MPNowPlayingInfoCenter.h> #import <MediaPlayer/MPMediaItem.h> 远程控制事件接收与处理- (void)viewWillAppear:(BOOL)animated{[super viewWillAppear:animated];[[UIApplication sha

手把手教你做音乐播放器(八)桌面小工具(上)

第8节 桌面小工具 桌面小工具是可以放置在主界面的.快速控制应用的小助手.例如我们的音乐小工具,它可以帮助用户在桌面上就完成音乐的暂停.播放.切换等操作,而不需要启动应用本身. 在安卓系统中,我们也常常叫它App widget. 实现一个App widget要经过以下几个步骤, 创建一个App widget类,让它继承自AppWidgetProvider,例如AnddleMusicAppWidget类: 放在res\layout目录下,为App widget的界面定义一个布局,例如anddle_

iOS开发拓展篇—音频处理(音乐播放器6)

iOS开发拓展篇—音频处理(音乐播放器6) 一.图片处理 说明: Aspect表示按照原来的宽高比进行缩放. Aspectfit表示按照原来的宽高比缩放,要求看到全部图片,后果是不能完全覆盖窗口,会留有空白. Aspectfill表示按照原来的宽高比缩放,但只能看到部分图片.引发的问题:可能会有一部分超出屏幕. 所以,如果选择了Aspectfill模式,那么需要剪切超出的图片,在storyboard中也可以进行设置. 下面的两种设置是等效的. (1)在storyboard中进行设置 (2)使用代

Android 实现简单音乐播放器(一)

今天掐指一算,学习Android长达近两个月了,今天开始,对过去一段时间的学习收获以及遇到的疑难杂症做一些总结. 简单音乐播放器是我自己完成的第一个功能较为完整的APP,可以说是我的Android学习之路上的一个小小里程碑,给我增加了很多信心(~~真容易获得满足~~).从下面开始,我将详细介绍MusicPlayer的设计过程. 首先,先看一下这个项目的工程目录和运行效果:      从上面的图片看到,整个工程的布局文件有两个:activity_main.xml和musiclist.xml,其中,

【黑马Android】(11)音乐播放器/视频播放器/照相机/常见对话框/notification通知/样式和主题/帧动画/传感器/应用程序反编译与安装

音乐播放器api <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:or