Merge pull request #7798 from yoobi:trackSelectionView
PiperOrigin-RevId: 333751261
This commit is contained in:
commit
19a0258bac
@ -24,6 +24,10 @@
|
|||||||
([#7967](https://github.com/google/ExoPlayer/issues/7967)).
|
([#7967](https://github.com/google/ExoPlayer/issues/7967)).
|
||||||
* Use TLEN ID3 tag to compute the duration in Mp3Extractor
|
* Use TLEN ID3 tag to compute the duration in Mp3Extractor
|
||||||
([#7949](https://github.com/google/ExoPlayer/issues/7949)).
|
([#7949](https://github.com/google/ExoPlayer/issues/7949)).
|
||||||
|
* UI
|
||||||
|
* Add the option to sort tracks by `Format` in `TrackSelectionView` and
|
||||||
|
`TrackSelectionDialogBuilder`
|
||||||
|
([#7709](https://github.com/google/ExoPlayer/issues/7709)).
|
||||||
|
|
||||||
### 2.12.0 (2020-09-11) ###
|
### 2.12.0 (2020-09-11) ###
|
||||||
|
|
||||||
|
@ -354,7 +354,12 @@ public final class TrackSelectionDialog extends DialogFragment {
|
|||||||
trackSelectionView.setAllowMultipleOverrides(allowMultipleOverrides);
|
trackSelectionView.setAllowMultipleOverrides(allowMultipleOverrides);
|
||||||
trackSelectionView.setAllowAdaptiveSelections(allowAdaptiveSelections);
|
trackSelectionView.setAllowAdaptiveSelections(allowAdaptiveSelections);
|
||||||
trackSelectionView.init(
|
trackSelectionView.init(
|
||||||
mappedTrackInfo, rendererIndex, isDisabled, overrides, /* listener= */ this);
|
mappedTrackInfo,
|
||||||
|
rendererIndex,
|
||||||
|
isDisabled,
|
||||||
|
overrides,
|
||||||
|
/* trackFormatComparator= */ null,
|
||||||
|
/* listener= */ this);
|
||||||
return rootView;
|
return rootView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.StyleRes;
|
import androidx.annotation.StyleRes;
|
||||||
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
|
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
|
||||||
@ -32,6 +33,7 @@ import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedT
|
|||||||
import com.google.android.exoplayer2.trackselection.TrackSelectionUtil;
|
import com.google.android.exoplayer2.trackselection.TrackSelectionUtil;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** Builder for a dialog with a {@link TrackSelectionView}. */
|
/** Builder for a dialog with a {@link TrackSelectionView}. */
|
||||||
@ -62,6 +64,7 @@ public final class TrackSelectionDialogBuilder {
|
|||||||
@Nullable private TrackNameProvider trackNameProvider;
|
@Nullable private TrackNameProvider trackNameProvider;
|
||||||
private boolean isDisabled;
|
private boolean isDisabled;
|
||||||
private List<SelectionOverride> overrides;
|
private List<SelectionOverride> overrides;
|
||||||
|
@Nullable private Comparator<Format> trackFormatComparator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a builder for a track selection dialog.
|
* Creates a builder for a track selection dialog.
|
||||||
@ -208,6 +211,16 @@ public final class TrackSelectionDialogBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a {@link Comparator} used to determine the display order of the tracks within each track
|
||||||
|
* group.
|
||||||
|
*
|
||||||
|
* @param trackFormatComparator The comparator, or {@code null} to use the original order.
|
||||||
|
*/
|
||||||
|
public void setTrackFormatComparator(@Nullable Comparator<Format> trackFormatComparator) {
|
||||||
|
this.trackFormatComparator = trackFormatComparator;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link TrackNameProvider} used to generate the user visible name of each track and
|
* Sets the {@link TrackNameProvider} used to generate the user visible name of each track and
|
||||||
* updates the view with track names queried from the specified provider.
|
* updates the view with track names queried from the specified provider.
|
||||||
@ -287,7 +300,13 @@ public final class TrackSelectionDialogBuilder {
|
|||||||
if (trackNameProvider != null) {
|
if (trackNameProvider != null) {
|
||||||
selectionView.setTrackNameProvider(trackNameProvider);
|
selectionView.setTrackNameProvider(trackNameProvider);
|
||||||
}
|
}
|
||||||
selectionView.init(mappedTrackInfo, rendererIndex, isDisabled, overrides, /* listener= */ null);
|
selectionView.init(
|
||||||
|
mappedTrackInfo,
|
||||||
|
rendererIndex,
|
||||||
|
isDisabled,
|
||||||
|
overrides,
|
||||||
|
trackFormatComparator,
|
||||||
|
/* listener= */ null);
|
||||||
return (dialog, which) ->
|
return (dialog, which) ->
|
||||||
callback.onTracksSelected(selectionView.getIsDisabled(), selectionView.getOverrides());
|
callback.onTracksSelected(selectionView.getIsDisabled(), selectionView.getOverrides());
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ package com.google.android.exoplayer2.ui;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Pair;
|
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -26,6 +25,7 @@ import android.widget.CheckedTextView;
|
|||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import androidx.annotation.AttrRes;
|
import androidx.annotation.AttrRes;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.RendererCapabilities;
|
import com.google.android.exoplayer2.RendererCapabilities;
|
||||||
import com.google.android.exoplayer2.source.TrackGroup;
|
import com.google.android.exoplayer2.source.TrackGroup;
|
||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
@ -35,6 +35,7 @@ import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedT
|
|||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
@ -71,6 +72,7 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
private int rendererIndex;
|
private int rendererIndex;
|
||||||
private TrackGroupArray trackGroups;
|
private TrackGroupArray trackGroups;
|
||||||
private boolean isDisabled;
|
private boolean isDisabled;
|
||||||
|
@Nullable private Comparator<TrackInfo> trackInfoComparator;
|
||||||
@Nullable private TrackSelectionListener listener;
|
@Nullable private TrackSelectionListener listener;
|
||||||
|
|
||||||
/** Creates a track selection view. */
|
/** Creates a track selection view. */
|
||||||
@ -196,6 +198,8 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
* @param overrides List of initial overrides to be shown for this renderer. There must be at most
|
* @param overrides List of initial overrides to be shown for this renderer. There must be at most
|
||||||
* one override for each track group. If {@link #setAllowMultipleOverrides(boolean)} hasn't
|
* one override for each track group. If {@link #setAllowMultipleOverrides(boolean)} hasn't
|
||||||
* been set to {@code true}, only the first override is used.
|
* been set to {@code true}, only the first override is used.
|
||||||
|
* @param trackFormatComparator An optional comparator used to determine the display order of the
|
||||||
|
* tracks within each track group.
|
||||||
* @param listener An optional listener for track selection updates.
|
* @param listener An optional listener for track selection updates.
|
||||||
*/
|
*/
|
||||||
public void init(
|
public void init(
|
||||||
@ -203,10 +207,15 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
int rendererIndex,
|
int rendererIndex,
|
||||||
boolean isDisabled,
|
boolean isDisabled,
|
||||||
List<SelectionOverride> overrides,
|
List<SelectionOverride> overrides,
|
||||||
|
@Nullable Comparator<Format> trackFormatComparator,
|
||||||
@Nullable TrackSelectionListener listener) {
|
@Nullable TrackSelectionListener listener) {
|
||||||
this.mappedTrackInfo = mappedTrackInfo;
|
this.mappedTrackInfo = mappedTrackInfo;
|
||||||
this.rendererIndex = rendererIndex;
|
this.rendererIndex = rendererIndex;
|
||||||
this.isDisabled = isDisabled;
|
this.isDisabled = isDisabled;
|
||||||
|
this.trackInfoComparator =
|
||||||
|
trackFormatComparator == null
|
||||||
|
? null
|
||||||
|
: (o1, o2) -> trackFormatComparator.compare(o1.format, o2.format);
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
int maxOverrides = allowMultipleOverrides ? overrides.size() : Math.min(overrides.size(), 1);
|
int maxOverrides = allowMultipleOverrides ? overrides.size() : Math.min(overrides.size(), 1);
|
||||||
for (int i = 0; i < maxOverrides; i++) {
|
for (int i = 0; i < maxOverrides; i++) {
|
||||||
@ -259,7 +268,16 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
TrackGroup group = trackGroups.get(groupIndex);
|
TrackGroup group = trackGroups.get(groupIndex);
|
||||||
boolean enableMultipleChoiceForAdaptiveSelections = shouldEnableAdaptiveSelection(groupIndex);
|
boolean enableMultipleChoiceForAdaptiveSelections = shouldEnableAdaptiveSelection(groupIndex);
|
||||||
trackViews[groupIndex] = new CheckedTextView[group.length];
|
trackViews[groupIndex] = new CheckedTextView[group.length];
|
||||||
|
|
||||||
|
TrackInfo[] trackInfos = new TrackInfo[group.length];
|
||||||
for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
|
for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
|
||||||
|
trackInfos[trackIndex] = new TrackInfo(groupIndex, trackIndex, group.getFormat(trackIndex));
|
||||||
|
}
|
||||||
|
if (trackInfoComparator != null) {
|
||||||
|
Arrays.sort(trackInfos, trackInfoComparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int trackIndex = 0; trackIndex < trackInfos.length; trackIndex++) {
|
||||||
if (trackIndex == 0) {
|
if (trackIndex == 0) {
|
||||||
addView(inflater.inflate(R.layout.exo_list_divider, this, false));
|
addView(inflater.inflate(R.layout.exo_list_divider, this, false));
|
||||||
}
|
}
|
||||||
@ -270,11 +288,11 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
CheckedTextView trackView =
|
CheckedTextView trackView =
|
||||||
(CheckedTextView) inflater.inflate(trackViewLayoutId, this, false);
|
(CheckedTextView) inflater.inflate(trackViewLayoutId, this, false);
|
||||||
trackView.setBackgroundResource(selectableItemBackgroundResourceId);
|
trackView.setBackgroundResource(selectableItemBackgroundResourceId);
|
||||||
trackView.setText(trackNameProvider.getTrackName(group.getFormat(trackIndex)));
|
trackView.setText(trackNameProvider.getTrackName(trackInfos[trackIndex].format));
|
||||||
if (mappedTrackInfo.getTrackSupport(rendererIndex, groupIndex, trackIndex)
|
if (mappedTrackInfo.getTrackSupport(rendererIndex, groupIndex, trackIndex)
|
||||||
== RendererCapabilities.FORMAT_HANDLED) {
|
== RendererCapabilities.FORMAT_HANDLED) {
|
||||||
trackView.setFocusable(true);
|
trackView.setFocusable(true);
|
||||||
trackView.setTag(Pair.create(groupIndex, trackIndex));
|
trackView.setTag(trackInfos[trackIndex]);
|
||||||
trackView.setOnClickListener(componentListener);
|
trackView.setOnClickListener(componentListener);
|
||||||
} else {
|
} else {
|
||||||
trackView.setFocusable(false);
|
trackView.setFocusable(false);
|
||||||
@ -294,7 +312,12 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
for (int i = 0; i < trackViews.length; i++) {
|
for (int i = 0; i < trackViews.length; i++) {
|
||||||
SelectionOverride override = overrides.get(i);
|
SelectionOverride override = overrides.get(i);
|
||||||
for (int j = 0; j < trackViews[i].length; j++) {
|
for (int j = 0; j < trackViews[i].length; j++) {
|
||||||
trackViews[i][j].setChecked(override != null && override.containsTrack(j));
|
if (override != null) {
|
||||||
|
TrackInfo trackInfo = (TrackInfo) Assertions.checkNotNull(trackViews[i][j].getTag());
|
||||||
|
trackViews[i][j].setChecked(override.containsTrack(trackInfo.trackIndex));
|
||||||
|
} else {
|
||||||
|
trackViews[i][j].setChecked(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -325,10 +348,9 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
|
|
||||||
private void onTrackViewClicked(View view) {
|
private void onTrackViewClicked(View view) {
|
||||||
isDisabled = false;
|
isDisabled = false;
|
||||||
@SuppressWarnings("unchecked")
|
TrackInfo trackInfo = (TrackInfo) Assertions.checkNotNull(view.getTag());
|
||||||
Pair<Integer, Integer> tag = (Pair<Integer, Integer>) Assertions.checkNotNull(view.getTag());
|
int groupIndex = trackInfo.groupIndex;
|
||||||
int groupIndex = tag.first;
|
int trackIndex = trackInfo.trackIndex;
|
||||||
int trackIndex = tag.second;
|
|
||||||
SelectionOverride override = overrides.get(groupIndex);
|
SelectionOverride override = overrides.get(groupIndex);
|
||||||
Assertions.checkNotNull(mappedTrackInfo);
|
Assertions.checkNotNull(mappedTrackInfo);
|
||||||
if (override == null) {
|
if (override == null) {
|
||||||
@ -406,4 +428,16 @@ public class TrackSelectionView extends LinearLayout {
|
|||||||
TrackSelectionView.this.onClick(view);
|
TrackSelectionView.this.onClick(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class TrackInfo {
|
||||||
|
public final int groupIndex;
|
||||||
|
public final int trackIndex;
|
||||||
|
public final Format format;
|
||||||
|
|
||||||
|
public TrackInfo(int groupIndex, int trackIndex, Format format) {
|
||||||
|
this.groupIndex = groupIndex;
|
||||||
|
this.trackIndex = trackIndex;
|
||||||
|
this.format = format;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user