Add TrackSelectionDialog (with swipe tabs) to demo app.
PiperOrigin-RevId: 233582549
This commit is contained in:
parent
00c31265cd
commit
1dd36ae391
@ -63,6 +63,9 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation 'com.android.support:support-annotations:' + supportLibraryVersion
|
||||
implementation 'com.android.support:support-core-ui:' + supportLibraryVersion
|
||||
implementation 'com.android.support:support-fragment:' + supportLibraryVersion
|
||||
implementation 'com.android.support:design:' + supportLibraryVersion
|
||||
implementation project(modulePrefix + 'library-core')
|
||||
implementation project(modulePrefix + 'library-dash')
|
||||
implementation project(modulePrefix + 'library-hls')
|
||||
|
@ -39,7 +39,8 @@
|
||||
|
||||
<activity android:name="com.google.android.exoplayer2.demo.SampleChooserActivity"
|
||||
android:configChanges="keyboardHidden"
|
||||
android:label="@string/application_name">
|
||||
android:label="@string/application_name"
|
||||
android:theme="@style/Theme.AppCompat">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
|
@ -15,20 +15,12 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.demo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.Resources;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.widget.Toast;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.RenderersFactory;
|
||||
@ -46,11 +38,6 @@ 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.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionUtil;
|
||||
import com.google.android.exoplayer2.ui.DefaultTrackNameProvider;
|
||||
import com.google.android.exoplayer2.ui.TrackNameProvider;
|
||||
import com.google.android.exoplayer2.ui.TrackSelectionDialogBuilder;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
@ -81,7 +68,6 @@ public class DownloadTracker implements DownloadManager.Listener {
|
||||
|
||||
private final Context context;
|
||||
private final DataSource.Factory dataSourceFactory;
|
||||
private final TrackNameProvider trackNameProvider;
|
||||
private final CopyOnWriteArraySet<Listener> listeners;
|
||||
private final HashMap<Uri, DownloadState> trackedDownloadStates;
|
||||
private final DefaultDownloadIndex downloadIndex;
|
||||
@ -92,7 +78,6 @@ public class DownloadTracker implements DownloadManager.Listener {
|
||||
this.context = context.getApplicationContext();
|
||||
this.dataSourceFactory = dataSourceFactory;
|
||||
this.downloadIndex = downloadIndex;
|
||||
trackNameProvider = new DefaultTrackNameProvider(context.getResources());
|
||||
listeners = new CopyOnWriteArraySet<>();
|
||||
trackedDownloadStates = new HashMap<>();
|
||||
HandlerThread actionFileWriteThread = new HandlerThread("DownloadTracker");
|
||||
@ -122,7 +107,7 @@ public class DownloadTracker implements DownloadManager.Listener {
|
||||
}
|
||||
|
||||
public void toggleDownload(
|
||||
Activity activity,
|
||||
FragmentManager fragmentManager,
|
||||
String name,
|
||||
Uri uri,
|
||||
String extension,
|
||||
@ -133,7 +118,7 @@ public class DownloadTracker implements DownloadManager.Listener {
|
||||
startServiceWithAction(removeAction);
|
||||
} else {
|
||||
new StartDownloadDialogHelper(
|
||||
activity, getDownloadHelper(uri, extension, renderersFactory), name);
|
||||
fragmentManager, getDownloadHelper(uri, extension, renderersFactory), name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,42 +210,23 @@ public class DownloadTracker implements DownloadManager.Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("UngroupedOverloads")
|
||||
private final class StartDownloadDialogHelper
|
||||
implements DownloadHelper.Callback,
|
||||
DialogInterface.OnClickListener,
|
||||
DialogInterface.OnDismissListener,
|
||||
View.OnClickListener {
|
||||
DialogInterface.OnDismissListener {
|
||||
|
||||
private final FragmentManager fragmentManager;
|
||||
private final DownloadHelper downloadHelper;
|
||||
private final String name;
|
||||
private final LayoutInflater dialogInflater;
|
||||
private final AlertDialog dialog;
|
||||
private final LinearLayout selectionList;
|
||||
|
||||
private TrackSelectionDialog trackSelectionDialog;
|
||||
private MappedTrackInfo mappedTrackInfo;
|
||||
private DefaultTrackSelector.Parameters parameters;
|
||||
|
||||
private StartDownloadDialogHelper(
|
||||
Activity activity, DownloadHelper downloadHelper, String name) {
|
||||
public StartDownloadDialogHelper(
|
||||
FragmentManager fragmentManager, DownloadHelper downloadHelper, String name) {
|
||||
this.fragmentManager = fragmentManager;
|
||||
this.downloadHelper = downloadHelper;
|
||||
this.name = name;
|
||||
AlertDialog.Builder builder =
|
||||
new AlertDialog.Builder(activity)
|
||||
.setTitle(R.string.download_preparing)
|
||||
.setPositiveButton(android.R.string.ok, /* listener= */ this)
|
||||
.setNegativeButton(android.R.string.cancel, /* listener= */ null);
|
||||
|
||||
// Inflate with the builder's context to ensure the correct style is used.
|
||||
dialogInflater = LayoutInflater.from(builder.getContext());
|
||||
selectionList = (LinearLayout) dialogInflater.inflate(R.layout.start_download_dialog, null);
|
||||
builder.setView(selectionList);
|
||||
dialog = builder.create();
|
||||
dialog.setOnDismissListener(/* listener= */ this);
|
||||
dialog.show();
|
||||
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
|
||||
|
||||
parameters = DownloadHelper.DEFAULT_TRACK_SELECTOR_PARAMETERS;
|
||||
downloadHelper.prepare(this);
|
||||
}
|
||||
|
||||
@ -268,12 +234,19 @@ public class DownloadTracker implements DownloadManager.Listener {
|
||||
|
||||
@Override
|
||||
public void onPrepared(DownloadHelper helper) {
|
||||
if (helper.getPeriodCount() > 0) {
|
||||
mappedTrackInfo = downloadHelper.getMappedTrackInfo(/* periodIndex= */ 0);
|
||||
updateSelectionList();
|
||||
if (helper.getPeriodCount() == 0) {
|
||||
onPrepareError(helper, new IOException("No periods found."));
|
||||
return;
|
||||
}
|
||||
dialog.setTitle(R.string.exo_download_description);
|
||||
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
|
||||
mappedTrackInfo = downloadHelper.getMappedTrackInfo(/* periodIndex= */ 0);
|
||||
trackSelectionDialog = new TrackSelectionDialog();
|
||||
trackSelectionDialog.init(
|
||||
mappedTrackInfo,
|
||||
/* allowAdaptiveSelections =*/ false,
|
||||
/* allowMultipleOverrides= */ true,
|
||||
/* onClickListener= */ this,
|
||||
/* onDismissListener= */ this);
|
||||
trackSelectionDialog.show(fragmentManager, "download");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -282,33 +255,44 @@ public class DownloadTracker implements DownloadManager.Listener {
|
||||
context.getApplicationContext(), R.string.download_start_error, Toast.LENGTH_LONG)
|
||||
.show();
|
||||
Log.e(TAG, "Failed to start download", e);
|
||||
dialog.cancel();
|
||||
}
|
||||
|
||||
// View.OnClickListener implementation.
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Integer rendererIndex = (Integer) v.getTag();
|
||||
TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(rendererIndex);
|
||||
String dialogTitle = getTrackTypeString(mappedTrackInfo.getRendererType(rendererIndex));
|
||||
new TrackSelectionDialogBuilder(
|
||||
dialog.getContext(),
|
||||
dialogTitle,
|
||||
mappedTrackInfo,
|
||||
rendererIndex,
|
||||
(isDisabled, overrides) -> updateTracks(rendererIndex, isDisabled, overrides))
|
||||
.setShowDisableOption(true)
|
||||
.setIsDisabled(parameters.getRendererDisabled(rendererIndex))
|
||||
.setOverride(parameters.getSelectionOverride(rendererIndex, trackGroupArray))
|
||||
.build()
|
||||
.show();
|
||||
}
|
||||
|
||||
// DialogInterface.OnClickListener implementation.
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
DefaultTrackSelector.ParametersBuilder builder =
|
||||
DownloadHelper.DEFAULT_TRACK_SELECTOR_PARAMETERS.buildUpon();
|
||||
for (int i = 0; i < mappedTrackInfo.getRendererCount(); i++) {
|
||||
builder.setRendererDisabled(/* rendererIndex= */ i, /* disabled= */ true);
|
||||
}
|
||||
for (int i = 0; i < downloadHelper.getPeriodCount(); i++) {
|
||||
downloadHelper.clearTrackSelections(/* periodIndex = */ i);
|
||||
}
|
||||
for (int i = 0; i < mappedTrackInfo.getRendererCount(); i++) {
|
||||
if (trackSelectionDialog.getIsDisabled(/* rendererIndex= */ i)) {
|
||||
continue;
|
||||
}
|
||||
builder.setRendererDisabled(/* rendererIndex= */ i, /* disabled= */ false);
|
||||
List<SelectionOverride> overrides =
|
||||
trackSelectionDialog.getOverrides(/* rendererIndex= */ i);
|
||||
if (overrides.isEmpty()) {
|
||||
for (int j = 0; j < downloadHelper.getPeriodCount(); j++) {
|
||||
downloadHelper.addTrackSelection(/* periodIndex = */ j, builder.build());
|
||||
}
|
||||
} else {
|
||||
TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(/* rendererIndex= */ i);
|
||||
for (int overrideIndex = 0; overrideIndex < overrides.size(); overrideIndex++) {
|
||||
builder.setSelectionOverride(
|
||||
/* rendererIndex= */ i, trackGroupArray, overrides.get(overrideIndex));
|
||||
for (int j = 0; j < downloadHelper.getPeriodCount(); j++) {
|
||||
downloadHelper.addTrackSelection(/* periodIndex = */ j, builder.build());
|
||||
}
|
||||
}
|
||||
builder.clearSelectionOverrides();
|
||||
}
|
||||
builder.setRendererDisabled(/* rendererIndex= */ i, /* disabled= */ true);
|
||||
}
|
||||
DownloadAction downloadAction = downloadHelper.getDownloadAction(Util.getUtf8Bytes(name));
|
||||
startDownload(downloadAction);
|
||||
}
|
||||
@ -316,86 +300,8 @@ public class DownloadTracker implements DownloadManager.Listener {
|
||||
// DialogInterface.OnDismissListener implementation.
|
||||
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
public void onDismiss(DialogInterface dialogInterface) {
|
||||
downloadHelper.release();
|
||||
}
|
||||
|
||||
// Internal methods.
|
||||
|
||||
private void updateTracks(
|
||||
int rendererIndex, boolean isDisabled, List<SelectionOverride> overrides) {
|
||||
parameters =
|
||||
TrackSelectionUtil.updateParametersWithOverride(
|
||||
parameters,
|
||||
rendererIndex,
|
||||
mappedTrackInfo.getTrackGroups(rendererIndex),
|
||||
isDisabled,
|
||||
overrides.isEmpty() ? null : overrides.get(0));
|
||||
for (int i = 0; i < downloadHelper.getPeriodCount(); i++) {
|
||||
downloadHelper.replaceTrackSelections(/* periodIndex= */ i, parameters);
|
||||
}
|
||||
updateSelectionList();
|
||||
}
|
||||
|
||||
private void updateSelectionList() {
|
||||
selectionList.removeAllViews();
|
||||
for (int i = 0; i < mappedTrackInfo.getRendererCount(); i++) {
|
||||
TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(i);
|
||||
if (trackGroupArray.length == 0) {
|
||||
continue;
|
||||
}
|
||||
String trackTypeString =
|
||||
getTrackTypeString(mappedTrackInfo.getRendererType(/* rendererIndex= */ i));
|
||||
if (trackTypeString == null) {
|
||||
return;
|
||||
}
|
||||
String trackSelectionsString = getTrackSelectionString(/* rendererIndex= */ i);
|
||||
View view = dialogInflater.inflate(R.layout.download_track_item, selectionList, false);
|
||||
TextView trackTitleView = view.findViewById(R.id.track_title);
|
||||
TextView trackDescView = view.findViewById(R.id.track_desc);
|
||||
ImageButton editButton = view.findViewById(R.id.edit_button);
|
||||
trackTitleView.setText(trackTypeString);
|
||||
trackDescView.setText(trackSelectionsString);
|
||||
editButton.setTag(i);
|
||||
editButton.setOnClickListener(this);
|
||||
selectionList.addView(view);
|
||||
}
|
||||
}
|
||||
|
||||
private String getTrackSelectionString(int rendererIndex) {
|
||||
List<TrackSelection> trackSelections =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, rendererIndex);
|
||||
String selectedTracks = "";
|
||||
Resources resources = selectionList.getResources();
|
||||
for (int i = 0; i < trackSelections.size(); i++) {
|
||||
TrackSelection selection = trackSelections.get(i);
|
||||
for (int j = 0; j < selection.length(); j++) {
|
||||
String trackName = trackNameProvider.getTrackName(selection.getFormat(j));
|
||||
if (i == 0 && j == 0) {
|
||||
selectedTracks = trackName;
|
||||
} else {
|
||||
selectedTracks = resources.getString(R.string.exo_item_list, selectedTracks, trackName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return selectedTracks.isEmpty()
|
||||
? resources.getString(R.string.exo_track_selection_none)
|
||||
: selectedTracks;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getTrackTypeString(int trackType) {
|
||||
Resources resources = selectionList.getResources();
|
||||
switch (trackType) {
|
||||
case C.TRACK_TYPE_VIDEO:
|
||||
return resources.getString(R.string.exo_track_selection_title_video);
|
||||
case C.TRACK_TYPE_AUDIO:
|
||||
return resources.getString(R.string.exo_track_selection_title_audio);
|
||||
case C.TRACK_TYPE_TEXT:
|
||||
return resources.getString(R.string.exo_track_selection_title_text);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.demo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.AssetManager;
|
||||
@ -23,6 +22,7 @@ import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.JsonReader;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
@ -55,7 +55,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/** An activity for selecting from a list of media samples. */
|
||||
public class SampleChooserActivity extends Activity
|
||||
public class SampleChooserActivity extends AppCompatActivity
|
||||
implements DownloadTracker.Listener, OnChildClickListener {
|
||||
|
||||
private static final String TAG = "SampleChooserActivity";
|
||||
@ -182,7 +182,11 @@ public class SampleChooserActivity extends Activity
|
||||
((DemoApplication) getApplication())
|
||||
.buildRenderersFactory(isNonNullAndChecked(preferExtensionDecodersMenuItem));
|
||||
downloadTracker.toggleDownload(
|
||||
this, sample.name, uriSample.uri, uriSample.extension, renderersFactory);
|
||||
getSupportFragmentManager(),
|
||||
sample.name,
|
||||
uriSample.uri,
|
||||
uriSample.extension,
|
||||
renderersFactory);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.demo;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentPagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.util.SparseArray;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
|
||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
|
||||
import com.google.android.exoplayer2.ui.TrackSelectionView;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/** Dialog to select tracks. */
|
||||
public final class TrackSelectionDialog extends DialogFragment {
|
||||
|
||||
private final SparseArray<TrackSelectionViewFragment> tabFragments;
|
||||
private final List<CharSequence> tabTitles;
|
||||
|
||||
private MappedTrackInfo mappedTrackInfo;
|
||||
private boolean allowAdaptiveSelections;
|
||||
private boolean allowMultipleOverrides;
|
||||
private DialogInterface.OnClickListener onClickListener;
|
||||
private DialogInterface.OnDismissListener onDismissListener;
|
||||
|
||||
/** Creates the dialog. */
|
||||
public TrackSelectionDialog() {
|
||||
tabFragments = new SparseArray<>();
|
||||
tabTitles = new ArrayList<>();
|
||||
// Retain instance across orientation changes to prevent loosing access to init data.
|
||||
setRetainInstance(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the dialog.
|
||||
*
|
||||
* @param mappedTrackInfo The {@link MappedTrackInfo} to display.
|
||||
* @param allowAdaptiveSelections Whether adaptive selections (consisting of more than one track)
|
||||
* can be made.
|
||||
* @param allowMultipleOverrides Whether tracks from multiple track groups can be selected.
|
||||
* @param onClickListener {@link DialogInterface.OnClickListener} called when tracks are selected.
|
||||
* @param onDismissListener {@link DialogInterface.OnDismissListener} called when the dialog is
|
||||
* dismissed.
|
||||
*/
|
||||
public void init(
|
||||
MappedTrackInfo mappedTrackInfo,
|
||||
boolean allowAdaptiveSelections,
|
||||
boolean allowMultipleOverrides,
|
||||
DialogInterface.OnClickListener onClickListener,
|
||||
DialogInterface.OnDismissListener onDismissListener) {
|
||||
this.mappedTrackInfo = mappedTrackInfo;
|
||||
this.allowAdaptiveSelections = allowAdaptiveSelections;
|
||||
this.allowMultipleOverrides = allowMultipleOverrides;
|
||||
this.onClickListener = onClickListener;
|
||||
this.onDismissListener = onDismissListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a renderer is disabled.
|
||||
*
|
||||
* @param rendererIndex Renderer index.
|
||||
* @return Whether the renderer is disabled.
|
||||
*/
|
||||
public boolean getIsDisabled(int rendererIndex) {
|
||||
TrackSelectionViewFragment rendererView = tabFragments.get(rendererIndex);
|
||||
return rendererView != null && rendererView.trackSelectionView.getIsDisabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of selected track selection overrides for the specified renderer. There will
|
||||
* be at most one override for each track group.
|
||||
*
|
||||
* @param rendererIndex Renderer index.
|
||||
* @return The list of track selection overrides for this renderer.
|
||||
*/
|
||||
public List<SelectionOverride> getOverrides(int rendererIndex) {
|
||||
TrackSelectionViewFragment rendererView = tabFragments.get(rendererIndex);
|
||||
return rendererView == null
|
||||
? Collections.emptyList()
|
||||
: rendererView.trackSelectionView.getOverrides();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.exo_download_description)
|
||||
.setPositiveButton(android.R.string.ok, onClickListener)
|
||||
.setNegativeButton(android.R.string.cancel, /* listener= */ null)
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
super.onDismiss(dialog);
|
||||
onDismissListener.onDismiss(dialog);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(
|
||||
LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
for (int i = 0; i < mappedTrackInfo.getRendererCount(); i++) {
|
||||
TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(i);
|
||||
if (trackGroupArray.length == 0) {
|
||||
continue;
|
||||
}
|
||||
String trackTypeString =
|
||||
getTrackTypeString(mappedTrackInfo.getRendererType(/* rendererIndex= */ i));
|
||||
if (trackTypeString == null) {
|
||||
continue;
|
||||
}
|
||||
TrackSelectionViewFragment tabFragment = new TrackSelectionViewFragment();
|
||||
tabFragment.init(
|
||||
mappedTrackInfo, /* rendererIndex= */ i, allowAdaptiveSelections, allowMultipleOverrides);
|
||||
tabFragments.put(i, tabFragment);
|
||||
tabTitles.add(trackTypeString);
|
||||
}
|
||||
View dialogView = inflater.inflate(R.layout.download_dialog, container, false);
|
||||
TabLayout tabLayout = dialogView.findViewById(R.id.download_dialog_tab_layout);
|
||||
ViewPager viewPager = dialogView.findViewById(R.id.download_dialog_view_pager);
|
||||
viewPager.setAdapter(new FragmentAdapter(getChildFragmentManager()));
|
||||
tabLayout.setupWithViewPager(viewPager);
|
||||
((AlertDialog) getDialog()).setView(dialogView);
|
||||
return dialogView;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getTrackTypeString(int trackType) {
|
||||
Resources resources = getResources();
|
||||
switch (trackType) {
|
||||
case C.TRACK_TYPE_VIDEO:
|
||||
return resources.getString(R.string.exo_track_selection_title_video);
|
||||
case C.TRACK_TYPE_AUDIO:
|
||||
return resources.getString(R.string.exo_track_selection_title_audio);
|
||||
case C.TRACK_TYPE_TEXT:
|
||||
return resources.getString(R.string.exo_track_selection_title_text);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private final class FragmentAdapter extends FragmentPagerAdapter {
|
||||
|
||||
public FragmentAdapter(FragmentManager fragmentManager) {
|
||||
super(fragmentManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
return tabFragments.valueAt(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return tabFragments.size();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
return tabTitles.get(position);
|
||||
}
|
||||
}
|
||||
|
||||
/** Fragment to show a track seleciton in tab of the track selection dialog. */
|
||||
public static final class TrackSelectionViewFragment extends Fragment {
|
||||
|
||||
private MappedTrackInfo mappedTrackInfo;
|
||||
private int rendererIndex;
|
||||
private boolean allowAdaptiveSelections;
|
||||
private boolean allowMultipleOverrides;
|
||||
|
||||
/* package */ TrackSelectionView trackSelectionView;
|
||||
|
||||
public void init(
|
||||
MappedTrackInfo mappedTrackInfo,
|
||||
int rendererIndex,
|
||||
boolean allowAdaptiveSelections,
|
||||
boolean allowMultipleOverrides) {
|
||||
this.mappedTrackInfo = mappedTrackInfo;
|
||||
this.rendererIndex = rendererIndex;
|
||||
this.allowAdaptiveSelections = allowAdaptiveSelections;
|
||||
this.allowMultipleOverrides = allowMultipleOverrides;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(
|
||||
LayoutInflater inflater,
|
||||
@Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View rootView =
|
||||
inflater.inflate(R.layout.download_dialog_tab, container, /* attachToRoot= */ false);
|
||||
trackSelectionView = rootView.findViewById(R.id.download_dialog_track_selection_view);
|
||||
trackSelectionView.setShowDisableOption(true);
|
||||
trackSelectionView.setAllowMultipleOverrides(allowMultipleOverrides);
|
||||
trackSelectionView.setAllowAdaptiveSelections(allowAdaptiveSelections);
|
||||
trackSelectionView.init(
|
||||
mappedTrackInfo,
|
||||
rendererIndex,
|
||||
/* isDisabled= */ false,
|
||||
/* overrides= */ Collections.emptyList());
|
||||
return rootView;
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 304 B |
Binary file not shown.
Before Width: | Height: | Size: 242 B |
Binary file not shown.
Before Width: | Height: | Size: 299 B |
Binary file not shown.
Before Width: | Height: | Size: 413 B |
Binary file not shown.
Before Width: | Height: | Size: 449 B |
@ -14,7 +14,15 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/selection_list"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
android:layout_height="wrap_content">
|
||||
<android.support.design.widget.TabLayout
|
||||
android:id="@+id/download_dialog_tab_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/download_dialog_view_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
24
demos/main/src/main/res/layout/download_dialog_tab.xml
Normal file
24
demos/main/src/main/res/layout/download_dialog_tab.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2018 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<com.google.android.exoplayer2.ui.TrackSelectionView
|
||||
android:id="@+id/download_dialog_track_selection_view"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</ScrollView>
|
@ -1,53 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2018 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_title"
|
||||
android:textStyle="bold"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="4dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_desc"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="4dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/edit_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:contentDescription="@string/download_edit_track"
|
||||
android:src="@drawable/ic_edit"/>
|
||||
|
||||
</LinearLayout>
|
@ -51,10 +51,6 @@
|
||||
|
||||
<string name="ima_not_loaded">Playing sample without ads, as the IMA extension was not loaded</string>
|
||||
|
||||
<string name="download_edit_track">Edit selection</string>
|
||||
|
||||
<string name="download_preparing">Preparing download…</string>
|
||||
|
||||
<string name="download_start_error">Failed to start download</string>
|
||||
|
||||
<string name="download_playlist_unsupported">This demo app does not support downloading playlists</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user