Commit 1dd36ae3 by tonihei Committed by Andrew Lewis

Add TrackSelectionDialog (with swipe tabs) to demo app.

PiperOrigin-RevId: 233582549
parent 00c31265
......@@ -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,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);
}
}
......
/*
* 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;
}
}
}
<?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:orientation="vertical"
android:layout_width="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>
......@@ -13,8 +13,12 @@
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:id="@+id/selection_list"
android:orientation="vertical"
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="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>
<?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>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment