[Android] Audio player: animate the big cover view

Adrien Maglo git at videolan.org
Thu Dec 5 18:04:23 CET 2013


vlc-ports/android | branch: master | Adrien Maglo <magsoft at videolan.org> | Thu Dec  5 18:04:17 2013 +0100| [dd31a34e9d233b5c106c324342d426aa91a6fa74] | committer: Adrien Maglo

Audio player: animate the big cover view

> http://git.videolan.org/gitweb.cgi/vlc-ports/android.git/?a=commit;h=dd31a34e9d233b5c106c324342d426aa91a6fa74
---

 vlc-android/res/layout/audio_player.xml            |    2 +-
 .../vlc/gui/audio/AudioPlayerFragment.java         |    9 +-
 .../org/videolan/vlc/widget/AnimatedCoverView.java |  115 ++++++++++++++++++++
 3 files changed, 122 insertions(+), 4 deletions(-)

diff --git a/vlc-android/res/layout/audio_player.xml b/vlc-android/res/layout/audio_player.xml
index 7563224..b10f1d7 100644
--- a/vlc-android/res/layout/audio_player.xml
+++ b/vlc-android/res/layout/audio_player.xml
@@ -69,7 +69,7 @@
             android:layout_height="fill_parent"
             android:background="?attr/background_menu" />
 
-        <ImageView
+        <org.videolan.vlc.widget.AnimatedCoverView
             android:id="@+id/big_cover"
             android:layout_width="fill_parent"
             android:layout_height="fill_parent"
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayerFragment.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayerFragment.java
index a7bd5e1..6c2cfc5 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayerFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayerFragment.java
@@ -31,6 +31,7 @@ import org.videolan.vlc.gui.CommonDialogs;
 import org.videolan.vlc.gui.MainActivity;
 import org.videolan.vlc.gui.CommonDialogs.MenuType;
 import org.videolan.vlc.interfaces.IAudioPlayer;
+import org.videolan.vlc.widget.AnimatedCoverView;
 
 import com.actionbarsherlock.app.SherlockFragment;
 
@@ -38,6 +39,7 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.graphics.Color;
 import android.media.AudioManager;
 import android.os.Bundle;
@@ -57,7 +59,7 @@ public class AudioPlayerFragment extends SherlockFragment implements IAudioPlaye
     public final static String TAG = "VLC/AudioPlayerFragment";
 
     private ImageView mCover;
-    private ImageView mBigCover;
+    private AnimatedCoverView mBigCover;
     private TextView mTitle;
     private TextView mArtist;
     private TextView mTime;
@@ -99,7 +101,7 @@ public class AudioPlayerFragment extends SherlockFragment implements IAudioPlaye
         View v = inflater.inflate(R.layout.audio_player, container, false);
 
         mCover = (ImageView) v.findViewById(R.id.cover);
-        mBigCover = (ImageView) v.findViewById(R.id.big_cover);
+        mBigCover = (AnimatedCoverView) v.findViewById(R.id.big_cover);
         mTitle = (TextView) v.findViewById(R.id.title);
         mArtist = (TextView) v.findViewById(R.id.artist);
         mTime = (TextView) v.findViewById(R.id.time);
@@ -274,9 +276,10 @@ public class AudioPlayerFragment extends SherlockFragment implements IAudioPlaye
                 mBigCover.setImageBitmap(cover);
             } else {
                 mCover.setVisibility(ImageView.GONE);
-                mBigCover.setImageResource(R.drawable.cone);
+                mBigCover.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.cone));
             }
         }
+
         lastTitle = title;
         mTitle.setText(lastTitle);
         mArtist.setText(mAudioController.getArtist());
diff --git a/vlc-android/src/org/videolan/vlc/widget/AnimatedCoverView.java b/vlc-android/src/org/videolan/vlc/widget/AnimatedCoverView.java
new file mode 100644
index 0000000..8bbc849
--- /dev/null
+++ b/vlc-android/src/org/videolan/vlc/widget/AnimatedCoverView.java
@@ -0,0 +1,115 @@
+/*****************************************************************************
+ * AnimatedCoverImageView.java
+ *****************************************************************************
+ * Copyright © 2011-2013 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+package org.videolan.vlc.widget;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Transformation;
+import android.view.animation.TranslateAnimation;
+
+
+public class AnimatedCoverView extends View {
+
+    private Bitmap mImage;
+
+    private TranslateAnimation mCurrentAnim = null;
+    private final static int ANIMATION_MOVE_1 = 0;
+    private final static int ANIMATION_MOVE_2 = 1;
+    private int mCurrentMove = ANIMATION_MOVE_2;
+
+    public AnimatedCoverView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    public AnimatedCoverView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public AnimatedCoverView(Context context) {
+        super(context);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        if (mImage != null) {
+            // Determine the animation parameters.
+            Rect rect = new Rect();
+            canvas.getClipBounds(rect);
+
+            float ARview = (float)rect.width() / rect.height();
+            float ARimage = (float)mImage.getWidth() / mImage.getHeight();
+
+            int scaledImageWidth;
+            int scaledImageHeight;
+
+            if (ARimage > ARview) {
+                scaledImageWidth = (int)((float)mImage.getWidth() * rect.bottom / mImage.getHeight());
+                scaledImageHeight = rect.bottom;
+            }
+            else {
+                scaledImageWidth = rect.right;
+                scaledImageHeight = (int)((float)mImage.getHeight() * rect.right / mImage.getWidth());
+            }
+
+            // Switch the current animation if needed.
+            if (mCurrentAnim == null || mCurrentAnim.hasEnded())
+            {
+                mCurrentMove = mCurrentMove == ANIMATION_MOVE_1 ? ANIMATION_MOVE_2 : ANIMATION_MOVE_1;
+
+                mCurrentAnim = new TranslateAnimation(
+                        mCurrentMove == ANIMATION_MOVE_1 ? 0 : rect.right - scaledImageWidth,
+                        mCurrentMove == ANIMATION_MOVE_1 ? rect.right - scaledImageWidth : 0,
+                        mCurrentMove == ANIMATION_MOVE_1 ? 0 : rect.bottom - scaledImageHeight,
+                        mCurrentMove == ANIMATION_MOVE_1 ? rect.bottom - scaledImageHeight : 0);
+
+                int animationDuration = scaledImageHeight == rect.bottom ?
+                        (scaledImageWidth - rect.right) * 15 : (scaledImageHeight - rect.bottom) * 15;
+                mCurrentAnim.setDuration(animationDuration);
+                mCurrentAnim.setInterpolator(new AccelerateDecelerateInterpolator());
+                mCurrentAnim.initialize(mImage.getWidth(), mImage.getHeight(), rect.right, rect.bottom);
+            }
+
+            // Animate and draw
+            Transformation trans = new Transformation();
+            mCurrentAnim.getTransformation(AnimationUtils.currentAnimationTimeMillis(), trans);
+            float[] pt = new float[2];
+            trans.getMatrix().mapPoints(pt);
+
+            Rect src = new Rect(0, 0, mImage.getWidth(), mImage.getHeight());
+            Rect dst = new Rect((int)pt[0], (int)pt[1], (int)pt[0] + scaledImageWidth, (int)pt[1] + scaledImageHeight);
+            canvas.drawBitmap(mImage, src, dst, null);
+            super.onDraw(canvas);
+
+            // Request another draw operation until time is up.
+            invalidate();
+        }
+    }
+
+    public void setImageBitmap(Bitmap b) {
+        mImage = b;
+        invalidate();
+    }
+}
\ No newline at end of file



More information about the Android mailing list