Propagate attributes to DefaultTimeBar

Issue: #5765
PiperOrigin-RevId: 249251150
This commit is contained in:
olly 2019-05-21 16:05:56 +01:00 committed by Toni
parent b6d6d8c411
commit 37fc1d879d
7 changed files with 137 additions and 38 deletions

View File

@ -15,8 +15,11 @@
for the underlying track was changing (e.g., at some period transitions). for the underlying track was changing (e.g., at some period transitions).
* Add `SilenceMediaSource` that can be used to play silence of a given * Add `SilenceMediaSource` that can be used to play silence of a given
duration ([#5735](https://github.com/google/ExoPlayer/issues/5735)). duration ([#5735](https://github.com/google/ExoPlayer/issues/5735)).
* UI: Change playback controls toggle from touch down to touch up events * UI:
([#5784](https://github.com/google/ExoPlayer/issues/5784)). * Allow setting `DefaultTimeBar` attributes on `PlayerView` and
`PlayerControlView`.
* Change playback controls toggle from touch down to touch up events
([#5784](https://github.com/google/ExoPlayer/issues/5784)).
* Add a workaround for broken raw audio decoding on Oppo R9 * Add a workaround for broken raw audio decoding on Oppo R9
([#5782](https://github.com/google/ExoPlayer/issues/5782)). ([#5782](https://github.com/google/ExoPlayer/issues/5782)).
* Offline: Add Scheduler implementation which uses WorkManager. * Offline: Add Scheduler implementation which uses WorkManager.

View File

@ -220,11 +220,26 @@ public class DefaultTimeBar extends View implements TimeBar {
private @Nullable long[] adGroupTimesMs; private @Nullable long[] adGroupTimesMs;
private @Nullable boolean[] playedAdGroups; private @Nullable boolean[] playedAdGroups;
/** Creates a new time bar. */ public DefaultTimeBar(Context context) {
this(context, null);
}
public DefaultTimeBar(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public DefaultTimeBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, attrs);
}
// Suppress warnings due to usage of View methods in the constructor. // Suppress warnings due to usage of View methods in the constructor.
@SuppressWarnings("nullness:method.invocation.invalid") @SuppressWarnings("nullness:method.invocation.invalid")
public DefaultTimeBar(Context context, AttributeSet attrs) { public DefaultTimeBar(
super(context, attrs); Context context,
@Nullable AttributeSet attrs,
int defStyleAttr,
@Nullable AttributeSet timebarAttrs) {
super(context, attrs, defStyleAttr);
seekBounds = new Rect(); seekBounds = new Rect();
progressBar = new Rect(); progressBar = new Rect();
bufferedBar = new Rect(); bufferedBar = new Rect();
@ -251,9 +266,9 @@ public class DefaultTimeBar extends View implements TimeBar {
int defaultScrubberEnabledSize = dpToPx(density, DEFAULT_SCRUBBER_ENABLED_SIZE_DP); int defaultScrubberEnabledSize = dpToPx(density, DEFAULT_SCRUBBER_ENABLED_SIZE_DP);
int defaultScrubberDisabledSize = dpToPx(density, DEFAULT_SCRUBBER_DISABLED_SIZE_DP); int defaultScrubberDisabledSize = dpToPx(density, DEFAULT_SCRUBBER_DISABLED_SIZE_DP);
int defaultScrubberDraggedSize = dpToPx(density, DEFAULT_SCRUBBER_DRAGGED_SIZE_DP); int defaultScrubberDraggedSize = dpToPx(density, DEFAULT_SCRUBBER_DRAGGED_SIZE_DP);
if (attrs != null) { if (timebarAttrs != null) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.DefaultTimeBar, 0, TypedArray a =
0); context.getTheme().obtainStyledAttributes(timebarAttrs, R.styleable.DefaultTimeBar, 0, 0);
try { try {
scrubberDrawable = a.getDrawable(R.styleable.DefaultTimeBar_scrubber_drawable); scrubberDrawable = a.getDrawable(R.styleable.DefaultTimeBar_scrubber_drawable);
if (scrubberDrawable != null) { if (scrubberDrawable != null) {

View File

@ -28,6 +28,7 @@ import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
@ -97,6 +98,9 @@ import java.util.Locale;
* <li>Corresponding method: None * <li>Corresponding method: None
* <li>Default: {@code R.layout.exo_player_control_view} * <li>Default: {@code R.layout.exo_player_control_view}
* </ul> * </ul>
* <li>All attributes that can be set on {@link DefaultTimeBar} can also be set on a
* PlayerControlView, and will be propagated to the inflated {@link DefaultTimeBar} unless the
* layout is overridden to specify a custom {@code exo_progress} (see below).
* </ul> * </ul>
* *
* <h3>Overriding the layout file</h3> * <h3>Overriding the layout file</h3>
@ -154,7 +158,15 @@ import java.util.Locale;
* <ul> * <ul>
* <li>Type: {@link TextView} * <li>Type: {@link TextView}
* </ul> * </ul>
* <li><b>{@code exo_progress_placeholder}</b> - A placeholder that's replaced with the inflated
* {@link DefaultTimeBar}. Ignored if an {@code exo_progress} view exists.
* <ul>
* <li>Type: {@link View}
* </ul>
* <li><b>{@code exo_progress}</b> - Time bar that's updated during playback and allows seeking. * <li><b>{@code exo_progress}</b> - Time bar that's updated during playback and allows seeking.
* {@link DefaultTimeBar} attributes set on the PlayerControlView will not be automatically
* propagated through to this instance. If a view exists with this id, any {@code
* exo_progress_placeholder} view will be ignored.
* <ul> * <ul>
* <li>Type: {@link TimeBar} * <li>Type: {@link TimeBar}
* </ul> * </ul>
@ -330,9 +342,27 @@ public class PlayerControlView extends FrameLayout {
LayoutInflater.from(context).inflate(controllerLayoutId, this); LayoutInflater.from(context).inflate(controllerLayoutId, this);
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS); setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
TimeBar customTimeBar = findViewById(R.id.exo_progress);
View timeBarPlaceholder = findViewById(R.id.exo_progress_placeholder);
if (customTimeBar != null) {
timeBar = customTimeBar;
} else if (timeBarPlaceholder != null) {
// Propagate attrs as timebarAttrs so that DefaultTimeBar's custom attributes are transferred,
// but standard attributes (e.g. background) are not.
DefaultTimeBar defaultTimeBar = new DefaultTimeBar(context, null, 0, playbackAttrs);
defaultTimeBar.setId(R.id.exo_progress);
defaultTimeBar.setLayoutParams(timeBarPlaceholder.getLayoutParams());
ViewGroup parent = ((ViewGroup) timeBarPlaceholder.getParent());
int timeBarIndex = parent.indexOfChild(timeBarPlaceholder);
parent.removeView(timeBarPlaceholder);
parent.addView(defaultTimeBar, timeBarIndex);
timeBar = defaultTimeBar;
} else {
timeBar = null;
}
durationView = findViewById(R.id.exo_duration); durationView = findViewById(R.id.exo_duration);
positionView = findViewById(R.id.exo_position); positionView = findViewById(R.id.exo_position);
timeBar = findViewById(R.id.exo_progress);
if (timeBar != null) { if (timeBar != null) {
timeBar.addListener(componentListener); timeBar.addListener(componentListener);
} }

View File

@ -162,9 +162,10 @@ import java.util.List;
* <li>Corresponding method: None * <li>Corresponding method: None
* <li>Default: {@code R.layout.exo_player_control_view} * <li>Default: {@code R.layout.exo_player_control_view}
* </ul> * </ul>
* <li>All attributes that can be set on a {@link PlayerControlView} can also be set on a * <li>All attributes that can be set on {@link PlayerControlView} and {@link DefaultTimeBar} can
* PlayerView, and will be propagated to the inflated {@link PlayerControlView} unless the * also be set on a PlayerView, and will be propagated to the inflated {@link
* layout is overridden to specify a custom {@code exo_controller} (see below). * PlayerControlView} unless the layout is overridden to specify a custom {@code
* exo_controller} (see below).
* </ul> * </ul>
* *
* <h3>Overriding the layout file</h3> * <h3>Overriding the layout file</h3>
@ -214,9 +215,10 @@ import java.util.List;
* <li>Type: {@link View} * <li>Type: {@link View}
* </ul> * </ul>
* <li><b>{@code exo_controller}</b> - An already inflated {@link PlayerControlView}. Allows use * <li><b>{@code exo_controller}</b> - An already inflated {@link PlayerControlView}. Allows use
* of a custom extension of {@link PlayerControlView}. Note that attributes such as {@code * of a custom extension of {@link PlayerControlView}. {@link PlayerControlView} and {@link
* rewind_increment} will not be automatically propagated through to this instance. If a view * DefaultTimeBar} attributes set on the PlayerView will not be automatically propagated
* exists with this id, any {@code exo_controller_placeholder} view will be ignored. * through to this instance. If a view exists with this id, any {@code
* exo_controller_placeholder} view will be ignored.
* <ul> * <ul>
* <li>Type: {@link PlayerControlView} * <li>Type: {@link PlayerControlView}
* </ul> * </ul>
@ -456,8 +458,9 @@ public class PlayerView extends FrameLayout implements AdsLoader.AdViewProvider
this.controller = customController; this.controller = customController;
} else if (controllerPlaceholder != null) { } else if (controllerPlaceholder != null) {
// Propagate attrs as playbackAttrs so that PlayerControlView's custom attributes are // Propagate attrs as playbackAttrs so that PlayerControlView's custom attributes are
// transferred, but standard FrameLayout attributes (e.g. background) are not. // transferred, but standard attributes (e.g. background) are not.
this.controller = new PlayerControlView(context, null, 0, attrs); this.controller = new PlayerControlView(context, null, 0, attrs);
controller.setId(R.id.exo_controller);
controller.setLayoutParams(controllerPlaceholder.getLayoutParams()); controller.setLayoutParams(controllerPlaceholder.getLayoutParams());
ViewGroup parent = ((ViewGroup) controllerPlaceholder.getParent()); ViewGroup parent = ((ViewGroup) controllerPlaceholder.getParent());
int controllerIndex = parent.indexOfChild(controllerPlaceholder); int controllerIndex = parent.indexOfChild(controllerPlaceholder);

View File

@ -76,8 +76,7 @@
android:includeFontPadding="false" android:includeFontPadding="false"
android:textColor="#FFBEBEBE"/> android:textColor="#FFBEBEBE"/>
<com.google.android.exoplayer2.ui.DefaultTimeBar <View android:id="@id/exo_progress_placeholder"
android:id="@id/exo_progress"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight="1" android:layout_weight="1"
android:layout_height="26dp"/> android:layout_height="26dp"/>

View File

@ -31,18 +31,36 @@
<enum name="texture_view" value="2"/> <enum name="texture_view" value="2"/>
<enum name="spherical_view" value="3"/> <enum name="spherical_view" value="3"/>
</attr> </attr>
<attr name="show_timeout" format="integer"/>
<attr name="rewind_increment" format="integer"/> <!-- Must be kept in sync with RepeatModeUtil -->
<attr name="fastforward_increment" format="integer"/>
<attr name="player_layout_id" format="reference"/>
<attr name="controller_layout_id" format="reference"/>
<attr name="repeat_toggle_modes"> <attr name="repeat_toggle_modes">
<flag name="none" value="0"/> <flag name="none" value="0"/>
<flag name="one" value="1"/> <flag name="one" value="1"/>
<flag name="all" value="2"/> <flag name="all" value="2"/>
</attr> </attr>
<!-- PlayerControlView attributes -->
<attr name="show_timeout" format="integer"/>
<attr name="rewind_increment" format="integer"/>
<attr name="fastforward_increment" format="integer"/>
<attr name="show_shuffle_button" format="boolean"/> <attr name="show_shuffle_button" format="boolean"/>
<attr name="time_bar_min_update_interval" format="integer"/> <attr name="time_bar_min_update_interval" format="integer"/>
<attr name="controller_layout_id" format="reference"/>
<!-- DefaultTimeBar attributes -->
<attr name="bar_height" format="dimension"/>
<attr name="touch_target_height" format="dimension"/>
<attr name="ad_marker_width" format="dimension"/>
<attr name="scrubber_enabled_size" format="dimension"/>
<attr name="scrubber_disabled_size" format="dimension"/>
<attr name="scrubber_dragged_size" format="dimension"/>
<attr name="scrubber_drawable" format="reference"/>
<attr name="played_color" format="color"/>
<attr name="scrubber_color" format="color"/>
<attr name="buffered_color" format="color"/>
<attr name="unplayed_color" format="color"/>
<attr name="ad_marker_color" format="color"/>
<attr name="played_ad_marker_color" format="color"/>
<declare-styleable name="PlayerView"> <declare-styleable name="PlayerView">
<attr name="use_artwork" format="boolean"/> <attr name="use_artwork" format="boolean"/>
@ -58,9 +76,11 @@
<enum name="always" value="2"/> <enum name="always" value="2"/>
</attr> </attr>
<attr name="keep_content_on_player_reset" format="boolean"/> <attr name="keep_content_on_player_reset" format="boolean"/>
<attr name="resize_mode"/> <attr name="player_layout_id" format="reference"/>
<attr name="surface_type"/> <attr name="surface_type"/>
<attr name="player_layout_id"/> <!-- AspectRatioFrameLayout attributes -->
<attr name="resize_mode"/>
<!-- PlayerControlView attributes --> <!-- PlayerControlView attributes -->
<attr name="show_timeout"/> <attr name="show_timeout"/>
<attr name="rewind_increment"/> <attr name="rewind_increment"/>
@ -69,6 +89,20 @@
<attr name="show_shuffle_button"/> <attr name="show_shuffle_button"/>
<attr name="time_bar_min_update_interval"/> <attr name="time_bar_min_update_interval"/>
<attr name="controller_layout_id"/> <attr name="controller_layout_id"/>
<!-- DefaultTimeBar attributes -->
<attr name="bar_height"/>
<attr name="touch_target_height"/>
<attr name="ad_marker_width"/>
<attr name="scrubber_enabled_size"/>
<attr name="scrubber_disabled_size"/>
<attr name="scrubber_dragged_size"/>
<attr name="scrubber_drawable"/>
<attr name="played_color"/>
<attr name="scrubber_color"/>
<attr name="buffered_color" />
<attr name="unplayed_color"/>
<attr name="ad_marker_color"/>
<attr name="played_ad_marker_color"/>
</declare-styleable> </declare-styleable>
<declare-styleable name="AspectRatioFrameLayout"> <declare-styleable name="AspectRatioFrameLayout">
@ -83,22 +117,36 @@
<attr name="show_shuffle_button"/> <attr name="show_shuffle_button"/>
<attr name="time_bar_min_update_interval"/> <attr name="time_bar_min_update_interval"/>
<attr name="controller_layout_id"/> <attr name="controller_layout_id"/>
<!-- DefaultTimeBar attributes -->
<attr name="bar_height"/>
<attr name="touch_target_height"/>
<attr name="ad_marker_width"/>
<attr name="scrubber_enabled_size"/>
<attr name="scrubber_disabled_size"/>
<attr name="scrubber_dragged_size"/>
<attr name="scrubber_drawable"/>
<attr name="played_color"/>
<attr name="scrubber_color"/>
<attr name="buffered_color" />
<attr name="unplayed_color"/>
<attr name="ad_marker_color"/>
<attr name="played_ad_marker_color"/>
</declare-styleable> </declare-styleable>
<declare-styleable name="DefaultTimeBar"> <declare-styleable name="DefaultTimeBar">
<attr name="bar_height" format="dimension"/> <attr name="bar_height"/>
<attr name="touch_target_height" format="dimension"/> <attr name="touch_target_height"/>
<attr name="ad_marker_width" format="dimension"/> <attr name="ad_marker_width"/>
<attr name="scrubber_enabled_size" format="dimension"/> <attr name="scrubber_enabled_size"/>
<attr name="scrubber_disabled_size" format="dimension"/> <attr name="scrubber_disabled_size"/>
<attr name="scrubber_dragged_size" format="dimension"/> <attr name="scrubber_dragged_size"/>
<attr name="scrubber_drawable" format="reference"/> <attr name="scrubber_drawable"/>
<attr name="played_color" format="color"/> <attr name="played_color"/>
<attr name="scrubber_color" format="color"/> <attr name="scrubber_color"/>
<attr name="buffered_color" format="color"/> <attr name="buffered_color" />
<attr name="unplayed_color" format="color"/> <attr name="unplayed_color"/>
<attr name="ad_marker_color" format="color"/> <attr name="ad_marker_color"/>
<attr name="played_ad_marker_color" format="color"/> <attr name="played_ad_marker_color"/>
</declare-styleable> </declare-styleable>
</resources> </resources>

View File

@ -33,6 +33,7 @@
<item name="exo_repeat_toggle" type="id"/> <item name="exo_repeat_toggle" type="id"/>
<item name="exo_duration" type="id"/> <item name="exo_duration" type="id"/>
<item name="exo_position" type="id"/> <item name="exo_position" type="id"/>
<item name="exo_progress_placeholder" type="id"/>
<item name="exo_progress" type="id"/> <item name="exo_progress" type="id"/>
<item name="exo_buffering" type="id"/> <item name="exo_buffering" type="id"/>
<item name="exo_error_message" type="id"/> <item name="exo_error_message" type="id"/>