Commit 053dc27a by []inger Committed by Oliver Woodman

Introduce resize mode for AspectRatioFrameLayout.

https://github.com/google/ExoPlayer/issues/1827

Three different modes available: fit (default), fixed_width, fixed_height
Developers need to use wrap_content for the dimension which is not fixed:

app:resize_mode="fixed_width"
android:layout_width="320dp"
android:layout_height="wrap_content"

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=135264861
parent 2cf339e0
...@@ -16,15 +16,31 @@ ...@@ -16,15 +16,31 @@
package com.google.android.exoplayer2.ui; package com.google.android.exoplayer2.ui;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import com.google.android.exoplayer2.R;
/** /**
* A {@link FrameLayout} that resizes itself to match a specified aspect ratio. * A {@link FrameLayout} that resizes itself to match a specified aspect ratio.
*/ */
public final class AspectRatioFrameLayout extends FrameLayout { public final class AspectRatioFrameLayout extends FrameLayout {
/** /**
* Either the width or height is decreased to obtain the desired aspect ratio.
*/
public static final int RESIZE_MODE_FIT = 0;
/**
* The width is fixed and the height is increased or decreased to obtain the desired aspect ratio.
*/
public static final int RESIZE_MODE_FIXED_WIDTH = 1;
/**
* The height is fixed and the width is increased or decreased to obtain the desired aspect ratio.
*/
public static final int RESIZE_MODE_FIXED_HEIGHT = 2;
/**
* The {@link FrameLayout} will not resize itself if the fractional difference between its natural * The {@link FrameLayout} will not resize itself if the fractional difference between its natural
* aspect ratio and the requested aspect ratio falls below this threshold. * aspect ratio and the requested aspect ratio falls below this threshold.
* <p> * <p>
...@@ -36,13 +52,24 @@ public final class AspectRatioFrameLayout extends FrameLayout { ...@@ -36,13 +52,24 @@ public final class AspectRatioFrameLayout extends FrameLayout {
private static final float MAX_ASPECT_RATIO_DEFORMATION_FRACTION = 0.01f; private static final float MAX_ASPECT_RATIO_DEFORMATION_FRACTION = 0.01f;
private float videoAspectRatio; private float videoAspectRatio;
private int resizeMode;
public AspectRatioFrameLayout(Context context) { public AspectRatioFrameLayout(Context context) {
super(context); this(context, null);
} }
public AspectRatioFrameLayout(Context context, AttributeSet attrs) { public AspectRatioFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
resizeMode = RESIZE_MODE_FIT;
if (attrs != null) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.AspectRatioFrameLayout, 0, 0);
try {
resizeMode = a.getInt(R.styleable.AspectRatioFrameLayout_resize_mode, RESIZE_MODE_FIT);
} finally {
a.recycle();
}
}
} }
/** /**
...@@ -57,6 +84,19 @@ public final class AspectRatioFrameLayout extends FrameLayout { ...@@ -57,6 +84,19 @@ public final class AspectRatioFrameLayout extends FrameLayout {
} }
} }
/**
* Sets the resize mode which can be of value {@link #RESIZE_MODE_FIT},
* {@link #RESIZE_MODE_FIXED_HEIGHT} or {@link #RESIZE_MODE_FIXED_WIDTH}.
*
* @param resizeMode The resize mode.
*/
public void setResizeMode(int resizeMode) {
if (this.resizeMode != resizeMode) {
this.resizeMode = resizeMode;
requestLayout();
}
}
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec);
...@@ -74,10 +114,20 @@ public final class AspectRatioFrameLayout extends FrameLayout { ...@@ -74,10 +114,20 @@ public final class AspectRatioFrameLayout extends FrameLayout {
return; return;
} }
if (aspectDeformation > 0) { switch (resizeMode) {
height = (int) (width / videoAspectRatio); case RESIZE_MODE_FIXED_WIDTH:
} else { height = (int) (width / videoAspectRatio);
width = (int) (height * videoAspectRatio); break;
case RESIZE_MODE_FIXED_HEIGHT:
width = (int) (height * videoAspectRatio);
break;
default:
if (aspectDeformation > 0) {
height = (int) (width / videoAspectRatio);
} else {
width = (int) (height * videoAspectRatio);
}
break;
} }
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
......
...@@ -63,6 +63,7 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -63,6 +63,7 @@ public final class SimpleExoPlayerView extends FrameLayout {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);
boolean useTextureView = false; boolean useTextureView = false;
int resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT;
if (attrs != null) { if (attrs != null) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.SimpleExoPlayerView, 0, 0); R.styleable.SimpleExoPlayerView, 0, 0);
...@@ -70,6 +71,8 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -70,6 +71,8 @@ public final class SimpleExoPlayerView extends FrameLayout {
useController = a.getBoolean(R.styleable.SimpleExoPlayerView_use_controller, useController); useController = a.getBoolean(R.styleable.SimpleExoPlayerView_use_controller, useController);
useTextureView = a.getBoolean(R.styleable.SimpleExoPlayerView_use_texture_view, useTextureView = a.getBoolean(R.styleable.SimpleExoPlayerView_use_texture_view,
useTextureView); useTextureView);
resizeMode = a.getInt(R.styleable.SimpleExoPlayerView_resize_mode,
AspectRatioFrameLayout.RESIZE_MODE_FIT);
} finally { } finally {
a.recycle(); a.recycle();
} }
...@@ -78,6 +81,7 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -78,6 +81,7 @@ public final class SimpleExoPlayerView extends FrameLayout {
LayoutInflater.from(context).inflate(R.layout.exo_simple_player_view, this); LayoutInflater.from(context).inflate(R.layout.exo_simple_player_view, this);
componentListener = new ComponentListener(); componentListener = new ComponentListener();
layout = (AspectRatioFrameLayout) findViewById(R.id.video_frame); layout = (AspectRatioFrameLayout) findViewById(R.id.video_frame);
layout.setResizeMode(resizeMode);
controller = (PlaybackControlView) findViewById(R.id.control); controller = (PlaybackControlView) findViewById(R.id.control);
shutterView = findViewById(R.id.shutter); shutterView = findViewById(R.id.shutter);
subtitleLayout = (SubtitleView) findViewById(R.id.subtitles); subtitleLayout = (SubtitleView) findViewById(R.id.subtitles);
...@@ -148,6 +152,17 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -148,6 +152,17 @@ public final class SimpleExoPlayerView extends FrameLayout {
} }
/** /**
* Sets the resize mode which can be of value {@link AspectRatioFrameLayout#RESIZE_MODE_FIT},
* {@link AspectRatioFrameLayout#RESIZE_MODE_FIXED_HEIGHT} or
* {@link AspectRatioFrameLayout#RESIZE_MODE_FIXED_WIDTH}.
*
* @param resizeMode The resize mode.
*/
public void setResizeMode(int resizeMode) {
layout.setResizeMode(resizeMode);
}
/**
* Set the {@link PlaybackControlView.VisibilityListener}. * Set the {@link PlaybackControlView.VisibilityListener}.
* *
* @param listener The listener to be notified about visibility changes. * @param listener The listener to be notified about visibility changes.
......
...@@ -14,8 +14,21 @@ ...@@ -14,8 +14,21 @@
limitations under the License. limitations under the License.
--> -->
<resources> <resources>
<attr name="resize_mode" format="enum">
<enum name="fit" value="0"/>
<enum name="fixed_width" value="1"/>
<enum name="fixed_height" value="2"/>
</attr>
<declare-styleable name="SimpleExoPlayerView"> <declare-styleable name="SimpleExoPlayerView">
<attr name="use_controller" format="boolean"/> <attr name="use_controller" format="boolean"/>
<attr name="use_texture_view" format="boolean"/> <attr name="use_texture_view" format="boolean"/>
<attr name="resize_mode"/>
</declare-styleable> </declare-styleable>
<declare-styleable name="AspectRatioFrameLayout">
<attr name="resize_mode"/>
</declare-styleable>
</resources> </resources>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment