Skip to content

Commit

Permalink
Merge pull request #7798 from yoobi:trackSelectionView
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 333751261
  • Loading branch information
ojw28 committed Sep 25, 2020
2 parents 908785b + 869981a commit 19a0258
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 10 deletions.
4 changes: 4 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
([#7967](https://github.com/google/ExoPlayer/issues/7967)).
* Use TLEN ID3 tag to compute the duration in Mp3Extractor
([#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) ###

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,12 @@ public View onCreateView(
trackSelectionView.setAllowMultipleOverrides(allowMultipleOverrides);
trackSelectionView.setAllowAdaptiveSelections(allowAdaptiveSelections);
trackSelectionView.init(
mappedTrackInfo, rendererIndex, isDisabled, overrides, /* listener= */ this);
mappedTrackInfo,
rendererIndex,
isDisabled,
overrides,
/* trackFormatComparator= */ null,
/* listener= */ this);
return rootView;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@
import android.view.View;
import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
import com.google.android.exoplayer2.trackselection.TrackSelectionUtil;
import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/** Builder for a dialog with a {@link TrackSelectionView}. */
Expand Down Expand Up @@ -62,6 +64,7 @@ public interface DialogCallback {
@Nullable private TrackNameProvider trackNameProvider;
private boolean isDisabled;
private List<SelectionOverride> overrides;
@Nullable private Comparator<Format> trackFormatComparator;

/**
* Creates a builder for a track selection dialog.
Expand Down Expand Up @@ -208,6 +211,16 @@ public TrackSelectionDialogBuilder setShowDisableOption(boolean showDisableOptio
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
* updates the view with track names queried from the specified provider.
Expand Down Expand Up @@ -287,7 +300,13 @@ private Dialog.OnClickListener setUpDialogView(View dialogView) {
if (trackNameProvider != null) {
selectionView.setTrackNameProvider(trackNameProvider);
}
selectionView.init(mappedTrackInfo, rendererIndex, isDisabled, overrides, /* listener= */ null);
selectionView.init(
mappedTrackInfo,
rendererIndex,
isDisabled,
overrides,
trackFormatComparator,
/* listener= */ null);
return (dialog, which) ->
callback.onTracksSelected(selectionView.getIsDisabled(), selectionView.getOverrides());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Pair;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckedTextView;
import android.widget.LinearLayout;
import androidx.annotation.AttrRes;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
Expand All @@ -35,6 +35,7 @@
import com.google.android.exoplayer2.util.Assertions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
Expand Down Expand Up @@ -71,6 +72,7 @@ public interface TrackSelectionListener {
private int rendererIndex;
private TrackGroupArray trackGroups;
private boolean isDisabled;
@Nullable private Comparator<TrackInfo> trackInfoComparator;
@Nullable private TrackSelectionListener listener;

/** Creates a track selection view. */
Expand Down Expand Up @@ -196,17 +198,24 @@ public void setTrackNameProvider(TrackNameProvider trackNameProvider) {
* @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
* 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.
*/
public void init(
MappedTrackInfo mappedTrackInfo,
int rendererIndex,
boolean isDisabled,
List<SelectionOverride> overrides,
@Nullable Comparator<Format> trackFormatComparator,
@Nullable TrackSelectionListener listener) {
this.mappedTrackInfo = mappedTrackInfo;
this.rendererIndex = rendererIndex;
this.isDisabled = isDisabled;
this.trackInfoComparator =
trackFormatComparator == null
? null
: (o1, o2) -> trackFormatComparator.compare(o1.format, o2.format);
this.listener = listener;
int maxOverrides = allowMultipleOverrides ? overrides.size() : Math.min(overrides.size(), 1);
for (int i = 0; i < maxOverrides; i++) {
Expand Down Expand Up @@ -259,7 +268,16 @@ private void updateViews() {
TrackGroup group = trackGroups.get(groupIndex);
boolean enableMultipleChoiceForAdaptiveSelections = shouldEnableAdaptiveSelection(groupIndex);
trackViews[groupIndex] = new CheckedTextView[group.length];

TrackInfo[] trackInfos = new TrackInfo[group.length];
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) {
addView(inflater.inflate(R.layout.exo_list_divider, this, false));
}
Expand All @@ -270,11 +288,11 @@ private void updateViews() {
CheckedTextView trackView =
(CheckedTextView) inflater.inflate(trackViewLayoutId, this, false);
trackView.setBackgroundResource(selectableItemBackgroundResourceId);
trackView.setText(trackNameProvider.getTrackName(group.getFormat(trackIndex)));
trackView.setText(trackNameProvider.getTrackName(trackInfos[trackIndex].format));
if (mappedTrackInfo.getTrackSupport(rendererIndex, groupIndex, trackIndex)
== RendererCapabilities.FORMAT_HANDLED) {
trackView.setFocusable(true);
trackView.setTag(Pair.create(groupIndex, trackIndex));
trackView.setTag(trackInfos[trackIndex]);
trackView.setOnClickListener(componentListener);
} else {
trackView.setFocusable(false);
Expand All @@ -294,7 +312,12 @@ private void updateViewStates() {
for (int i = 0; i < trackViews.length; i++) {
SelectionOverride override = overrides.get(i);
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);
}
}
}
}
Expand Down Expand Up @@ -325,10 +348,9 @@ private void onDefaultViewClicked() {

private void onTrackViewClicked(View view) {
isDisabled = false;
@SuppressWarnings("unchecked")
Pair<Integer, Integer> tag = (Pair<Integer, Integer>) Assertions.checkNotNull(view.getTag());
int groupIndex = tag.first;
int trackIndex = tag.second;
TrackInfo trackInfo = (TrackInfo) Assertions.checkNotNull(view.getTag());
int groupIndex = trackInfo.groupIndex;
int trackIndex = trackInfo.trackIndex;
SelectionOverride override = overrides.get(groupIndex);
Assertions.checkNotNull(mappedTrackInfo);
if (override == null) {
Expand Down Expand Up @@ -406,4 +428,16 @@ public void onClick(View 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;
}
}
}

0 comments on commit 19a0258

Please sign in to comment.