Override WebViewSubtitleOutput.onLayout()

Some of the CSS font sizes are derived from the current view height, if
this calculation is done before the view has been measured then a zero
view height results in a zero px font size and no visible text.

This can happen when the view type is changed (and so the
WebViewSubtitleOutput has been recently added to the SubtitleView
ViewGroup).

PiperOrigin-RevId: 311552052
This commit is contained in:
ibaker 2020-05-14 17:56:00 +01:00 committed by Oliver Woodman
parent a39233d2fd
commit 710374f83a
2 changed files with 42 additions and 10 deletions

View file

@ -201,7 +201,6 @@ public final class SubtitleView extends FrameLayout implements TextOutput {
innerSubtitleView = view; innerSubtitleView = view;
output = view; output = view;
addView(view); addView(view);
updateOutput();
} }
/** /**

View file

@ -16,6 +16,9 @@
*/ */
package com.google.android.exoplayer2.ui; package com.google.android.exoplayer2.ui;
import static com.google.android.exoplayer2.ui.SubtitleView.DEFAULT_BOTTOM_PADDING_FRACTION;
import static com.google.android.exoplayer2.ui.SubtitleView.DEFAULT_TEXT_SIZE_FRACTION;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.text.Layout; import android.text.Layout;
@ -32,6 +35,7 @@ import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
@ -52,6 +56,12 @@ import java.util.List;
private final WebView webView; private final WebView webView;
private List<Cue> textCues;
private CaptionStyleCompat style;
private float defaultTextSize;
@Cue.TextSizeType private int defaultTextSizeType;
private float bottomPaddingFraction;
public WebViewSubtitleOutput(Context context) { public WebViewSubtitleOutput(Context context) {
this(context, null); this(context, null);
} }
@ -59,6 +69,12 @@ import java.util.List;
public WebViewSubtitleOutput(Context context, @Nullable AttributeSet attrs) { public WebViewSubtitleOutput(Context context, @Nullable AttributeSet attrs) {
super(context, attrs); super(context, attrs);
textCues = Collections.emptyList();
style = CaptionStyleCompat.DEFAULT;
defaultTextSize = DEFAULT_TEXT_SIZE_FRACTION;
defaultTextSizeType = Cue.TEXT_SIZE_TYPE_FRACTIONAL;
bottomPaddingFraction = DEFAULT_BOTTOM_PADDING_FRACTION;
canvasSubtitleOutput = new CanvasSubtitleOutput(context, attrs); canvasSubtitleOutput = new CanvasSubtitleOutput(context, attrs);
webView = webView =
new WebView(context, attrs) { new WebView(context, attrs) {
@ -89,6 +105,11 @@ import java.util.List;
float textSize, float textSize,
@Cue.TextSizeType int textSizeType, @Cue.TextSizeType int textSizeType,
float bottomPaddingFraction) { float bottomPaddingFraction) {
this.style = style;
this.defaultTextSize = textSize;
this.defaultTextSizeType = textSizeType;
this.bottomPaddingFraction = bottomPaddingFraction;
List<Cue> bitmapCues = new ArrayList<>(); List<Cue> bitmapCues = new ArrayList<>();
List<Cue> textCues = new ArrayList<>(); List<Cue> textCues = new ArrayList<>();
for (int i = 0; i < cues.size(); i++) { for (int i = 0; i < cues.size(); i++) {
@ -99,10 +120,27 @@ import java.util.List;
textCues.add(cue); textCues.add(cue);
} }
} }
if (!this.textCues.isEmpty() || !textCues.isEmpty()) {
this.textCues = textCues;
// Skip updating if this is a transition from empty-cues to empty-cues (i.e. only positioning
// info has changed) since a positional-only change with no cues is a visual no-op. The new
// position info will be used when we get non-empty cue data in a future update() call.
updateWebView();
}
canvasSubtitleOutput.update(bitmapCues, style, textSize, textSizeType, bottomPaddingFraction); canvasSubtitleOutput.update(bitmapCues, style, textSize, textSizeType, bottomPaddingFraction);
// Invalidate to trigger canvasSubtitleOutput to draw. // Invalidate to trigger canvasSubtitleOutput to draw.
invalidate(); invalidate();
updateWebView(textCues, style, textSize, textSizeType, bottomPaddingFraction); }
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (changed && !textCues.isEmpty()) {
// A positional change with no cues is a visual no-op. The new layout info will be used
// automatically next time update() is called.
updateWebView();
}
} }
/** /**
@ -115,12 +153,7 @@ import java.util.List;
webView.destroy(); webView.destroy();
} }
private void updateWebView( private void updateWebView() {
List<Cue> cues,
CaptionStyleCompat style,
float defaultTextSize,
@Cue.TextSizeType int defaultTextSizeType,
float bottomPaddingFraction) {
StringBuilder html = new StringBuilder(); StringBuilder html = new StringBuilder();
html.append( html.append(
Util.formatInvariant( Util.formatInvariant(
@ -141,8 +174,8 @@ import java.util.List;
String backgroundColorCss = HtmlUtils.toCssRgba(style.backgroundColor); String backgroundColorCss = HtmlUtils.toCssRgba(style.backgroundColor);
for (int i = 0; i < cues.size(); i++) { for (int i = 0; i < textCues.size(); i++) {
Cue cue = cues.get(i); Cue cue = textCues.get(i);
float positionPercent = (cue.position != Cue.DIMEN_UNSET) ? (cue.position * 100) : 50; float positionPercent = (cue.position != Cue.DIMEN_UNSET) ? (cue.position * 100) : 50;
int positionAnchorTranslatePercent = anchorTypeToTranslatePercent(cue.positionAnchor); int positionAnchorTranslatePercent = anchorTypeToTranslatePercent(cue.positionAnchor);