diff options
author | Alan Viverette <alanv@google.com> | 2013-09-03 23:51:34 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-09-03 23:51:35 +0000 |
commit | 6416729c4732be6bcdbc5f303752a9d1885f86d0 (patch) | |
tree | eb79be4df0fa1aeb019169c4302da74728dfd19f /core/java/android | |
parent | de59baab31271a186a2f32719abd19a8adbda1e3 (diff) | |
parent | de213f708fc715c85f806fe5f4a7552e8b363bf9 (diff) | |
download | frameworks_base-6416729c4732be6bcdbc5f303752a9d1885f86d0.zip frameworks_base-6416729c4732be6bcdbc5f303752a9d1885f86d0.tar.gz frameworks_base-6416729c4732be6bcdbc5f303752a9d1885f86d0.tar.bz2 |
Merge "Add methods for managing subtitle overlays in VideoView" into klp-dev
Diffstat (limited to 'core/java/android')
-rw-r--r-- | core/java/android/widget/VideoView.java | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java index 855ce12..0ddc131 100644 --- a/core/java/android/widget/VideoView.java +++ b/core/java/android/widget/VideoView.java @@ -21,6 +21,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.res.Resources; +import android.graphics.Canvas; import android.media.AudioManager; import android.media.MediaFormat; import android.media.MediaPlayer; @@ -42,6 +43,7 @@ import android.widget.MediaController.MediaPlayerControl; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Map; import java.util.Vector; @@ -94,6 +96,15 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { private boolean mCanSeekBack; private boolean mCanSeekForward; + /** List of views overlaid on top of the video. */ + private ArrayList<View> mOverlays; + + /** + * Listener for overlay layout changes. Invalidates the video view to ensure + * that captions are redrawn whenever their layout changes. + */ + private OnLayoutChangeListener mOverlayLayoutListener; + public VideoView(Context context) { super(context); initVideoView(); @@ -766,4 +777,101 @@ public class VideoView extends SurfaceView implements MediaPlayerControl { } return mAudioSession; } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + + // Layout overlay views, if necessary. + if (changed && mOverlays != null && !mOverlays.isEmpty()) { + measureAndLayoutOverlays(); + } + } + + @Override + public void draw(Canvas canvas) { + super.draw(canvas); + + final int count = mOverlays.size(); + for (int i = 0; i < count; i++) { + final View overlay = mOverlays.get(i); + overlay.draw(canvas); + } + } + + /** + * Adds a view to be overlaid on top of this video view. During layout, the + * view will be forced to match the bounds, less padding, of the video view. + * <p> + * Overlays are drawn in the order they are added. The last added overlay + * will be drawn on top. + * + * @param overlay the view to overlay + * @see #removeOverlay(View) + */ + private void addOverlay(View overlay) { + if (mOverlays == null) { + mOverlays = new ArrayList<View>(1); + } + + if (mOverlayLayoutListener == null) { + mOverlayLayoutListener = new OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + invalidate(); + } + }; + } + + if (mOverlays.isEmpty()) { + setWillNotDraw(false); + } + + mOverlays.add(overlay); + overlay.addOnLayoutChangeListener(mOverlayLayoutListener); + measureAndLayoutOverlays(); + } + + /** + * Removes a view previously added using {@link #addOverlay}. + * + * @param overlay the view to remove + * @see #addOverlay(View) + */ + private void removeOverlay(View overlay) { + if (mOverlays == null) { + return; + } + + overlay.removeOnLayoutChangeListener(mOverlayLayoutListener); + mOverlays.remove(overlay); + + if (mOverlays.isEmpty()) { + setWillNotDraw(true); + } + + invalidate(); + } + + /** + * Forces a measurement and layout pass for all overlaid views. + * + * @see #addOverlay(View) + */ + private void measureAndLayoutOverlays() { + final int left = getPaddingLeft(); + final int top = getPaddingTop(); + final int right = getWidth() - left - getPaddingRight(); + final int bottom = getHeight() - top - getPaddingBottom(); + final int widthSpec = MeasureSpec.makeMeasureSpec(right - left, MeasureSpec.EXACTLY); + final int heightSpec = MeasureSpec.makeMeasureSpec(bottom - top, MeasureSpec.EXACTLY); + + final int count = mOverlays.size(); + for (int i = 0; i < count; i++) { + final View overlay = mOverlays.get(i); + overlay.measure(widthSpec, heightSpec); + overlay.layout(left, top, right, bottom); + } + } } |