Java tutorial
/* * This file is part of Butter. * * Butter is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Butter is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Butter. If not, see <http://www.gnu.org/licenses/>. */ package butter.droid.tv.fragments; import android.app.AlertDialog; import android.content.DialogInterface; import android.os.Bundle; import android.support.v17.leanback.app.BrowseFragment; import android.support.v17.leanback.widget.ArrayObjectAdapter; import android.support.v17.leanback.widget.HeaderItem; import android.support.v17.leanback.widget.ListRow; import android.support.v17.leanback.widget.ListRowPresenter; import android.support.v17.leanback.widget.OnItemViewClickedListener; import android.support.v17.leanback.widget.OnItemViewSelectedListener; import android.support.v17.leanback.widget.Presenter; import android.support.v17.leanback.widget.Row; import android.support.v17.leanback.widget.RowPresenter; import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityOptionsCompat; import android.view.View; import android.widget.EditText; import android.widget.Toast; import com.squareup.okhttp.Callback; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import butter.droid.base.providers.media.MoviesProvider; import butter.droid.base.providers.media.TVProvider; import hugo.weaving.DebugLog; import butter.droid.base.providers.media.MediaProvider; import butter.droid.base.providers.media.models.Media; import butter.droid.base.providers.media.models.Movie; import butter.droid.base.providers.subs.SubsProvider; import butter.droid.base.providers.subs.YSubsProvider; import butter.droid.base.torrent.StreamInfo; import butter.droid.base.utils.ThreadUtils; import butter.droid.tv.BuildConfig; import butter.droid.tv.R; import butter.droid.tv.activities.TVMediaDetailActivity; import butter.droid.tv.activities.TVMediaGridActivity; import butter.droid.tv.activities.TVPreferencesActivity; import butter.droid.tv.activities.TVSearchActivity; import butter.droid.tv.activities.TVVideoPlayerActivity; import butter.droid.tv.presenters.MediaCardPresenter; import butter.droid.tv.presenters.MorePresenter; import butter.droid.tv.utils.BackgroundUpdater; /* * Main class to show BrowseFragment with header and rows of videos */ public class TVOverviewFragment extends BrowseFragment implements OnItemViewClickedListener, OnItemViewSelectedListener { private Integer mSelectedRow = 0; private ArrayObjectAdapter mRowsAdapter; private ArrayObjectAdapter mShowAdapter; private ArrayObjectAdapter mMoviesAdapter; private MediaProvider mMoviesProvider = new MoviesProvider(); private MediaProvider mShowsProvider = new TVProvider(); private BackgroundUpdater mBackgroundUpdater; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); //setup background updater mBackgroundUpdater = new BackgroundUpdater(); mBackgroundUpdater.initialise(getActivity(), R.color.black); //setup main adapter ListRowPresenter mainMenuRowPresenter = new ListRowPresenter(); mainMenuRowPresenter.setShadowEnabled(false); mRowsAdapter = new ArrayObjectAdapter(mainMenuRowPresenter); setAdapter(mRowsAdapter); setupUIElements(); setupEventListeners(); setupAdapters(); loadData(); } @Override public void onDestroy() { super.onDestroy(); if (null != mBackgroundUpdater) mBackgroundUpdater.destroy(); } @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) { if (item instanceof MediaCardPresenter.MediaCardItem) { onMediaItemClicked((MediaCardPresenter.CustomImageCardView) itemViewHolder.view, (MediaCardPresenter.MediaCardItem) item); } else if (item instanceof MorePresenter.MoreItem) { onMoreItemClicked((MorePresenter.MoreItem) item); } } @Override public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) { mSelectedRow = mRowsAdapter.indexOf(row); if (item instanceof MediaCardPresenter.MediaCardItem) { MediaCardPresenter.MediaCardItem overviewItem = (MediaCardPresenter.MediaCardItem) item; if (overviewItem.isLoading()) return; mBackgroundUpdater .updateBackgroundAsync(((MediaCardPresenter.MediaCardItem) item).getMedia().headerImage); } } private void setupUIElements() { setBadgeDrawable(ActivityCompat.getDrawable(getActivity(), R.drawable.header_logo)); setTitle(getString(R.string.app_name)); // Badge, when set, takes precedent over title setHeadersState(HEADERS_ENABLED); setHeadersTransitionOnBackEnabled(true); // set fastLane (or headers) background color setBrandColor(ActivityCompat.getColor(getActivity(), R.color.primary)); // set search icon color setSearchAffordanceColor(ActivityCompat.getColor(getActivity(), R.color.primary_dark)); } private void loadData() { final MediaProvider.Filters showsFilter = new MediaProvider.Filters(); showsFilter.sort = MediaProvider.Filters.Sort.DATE; showsFilter.order = MediaProvider.Filters.Order.DESC; mShowsProvider.getList(null, showsFilter, new MediaProvider.Callback() { @DebugLog @Override public void onSuccess(MediaProvider.Filters filters, ArrayList<Media> items, boolean changed) { List<MediaCardPresenter.MediaCardItem> list = MediaCardPresenter.convertMediaToOverview(items); mShowAdapter.clear(); mShowAdapter.addAll(0, list); if (mSelectedRow == 1) mBackgroundUpdater.updateBackgroundAsync(items.get(0).headerImage); } @DebugLog @Override public void onFailure(Exception e) { e.printStackTrace(); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getActivity(), R.string.encountered_error, Toast.LENGTH_SHORT).show(); } }); } }); final MediaProvider.Filters movieFilters = new MediaProvider.Filters(); movieFilters.sort = MediaProvider.Filters.Sort.POPULARITY; movieFilters.order = MediaProvider.Filters.Order.DESC; mMoviesProvider.getList(null, movieFilters, new MediaProvider.Callback() { @DebugLog @Override public void onSuccess(MediaProvider.Filters filters, ArrayList<Media> items, boolean changed) { List<MediaCardPresenter.MediaCardItem> list = MediaCardPresenter.convertMediaToOverview(items); mMoviesAdapter.clear(); mMoviesAdapter.addAll(0, list); if (mSelectedRow == 0) mBackgroundUpdater.updateBackgroundAsync(items.get(0).headerImage); } @DebugLog @Override public void onFailure(Exception e) { e.printStackTrace(); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getActivity(), R.string.movies_error, Toast.LENGTH_SHORT).show(); } }); } }); } private void setupEventListeners() { setOnSearchClickedListener(new View.OnClickListener() { @Override public void onClick(View view) { TVSearchActivity.startActivity(getActivity()); } }); setOnItemViewClickedListener(this); setOnItemViewSelectedListener(this); } private void setupAdapters() { setupMovies(); setupTVShows(); setupMoreMovies(); setupMoreTVShows(); setupMore(); } private void setupMovies() { HeaderItem moviesHeader = new HeaderItem(0, getString(R.string.top_movies)); MediaCardPresenter mediaCardPresenter = new MediaCardPresenter(getActivity()); mMoviesAdapter = new ArrayObjectAdapter(mediaCardPresenter); mMoviesAdapter.add(new MediaCardPresenter.MediaCardItem(true)); mRowsAdapter.add(new ListRow(moviesHeader, mMoviesAdapter)); } private void setupMoreMovies() { HeaderItem moreMoviesHeader = new HeaderItem(1, getString(R.string.more_movies)); MorePresenter morePresenter = new MorePresenter(getActivity()); ArrayObjectAdapter moreRowAdapter = new ArrayObjectAdapter(morePresenter); // add items List<MediaProvider.NavInfo> navigation = mMoviesProvider.getNavigation(); for (MediaProvider.NavInfo info : navigation) { moreRowAdapter.add(new MorePresenter.MoreItem(info.getId(), info.getLabel(), info.getIcon(), info)); } mRowsAdapter.add(new ListRow(moreMoviesHeader, moreRowAdapter)); } private void setupTVShows() { HeaderItem showsHeader = new HeaderItem(0, getString(R.string.latest_shows)); MediaCardPresenter mediaCardPresenter = new MediaCardPresenter(getActivity()); mShowAdapter = new ArrayObjectAdapter(mediaCardPresenter); mShowAdapter.add(new MediaCardPresenter.MediaCardItem(true)); mRowsAdapter.add(new ListRow(showsHeader, mShowAdapter)); } private void setupMoreTVShows() { HeaderItem moreHeader = new HeaderItem(1, getString(R.string.more_shows)); MorePresenter morePresenter = new MorePresenter(getActivity()); ArrayObjectAdapter moreRowAdapter = new ArrayObjectAdapter(morePresenter); // add items List<MediaProvider.NavInfo> navigation = mShowsProvider.getNavigation(); for (MediaProvider.NavInfo info : navigation) { moreRowAdapter.add(new MorePresenter.MoreItem(info.getId(), info.getLabel(), info.getIcon(), info)); } mRowsAdapter.add(new ListRow(moreHeader, moreRowAdapter)); } private void setupMore() { HeaderItem gridHeader = new HeaderItem(0, getString(R.string.more)); MorePresenter gridPresenter = new MorePresenter(getActivity()); ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(gridPresenter); if (BuildConfig.DEBUG) { gridRowAdapter.add(new MorePresenter.MoreItem(R.id.more_player_tests, getString(R.string.tests), R.drawable.more_player_tests, null)); } gridRowAdapter.add(new MorePresenter.MoreItem(R.id.more_item_settings, getString(R.string.preferences), R.drawable.ic_settings, null)); mRowsAdapter.add(new ListRow(gridHeader, gridRowAdapter)); } private void onMediaItemClicked(MediaCardPresenter.CustomImageCardView view, MediaCardPresenter.MediaCardItem media) { if (media.isLoading()) return; Bundle options = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), view.getMainImageView(), TVMediaDetailActivity.SHARED_ELEMENT_NAME).toBundle(); Media mediaItem = media.getMedia(); mediaItem.color = view.getCustomSelectedSwatch().getRgb(); TVMediaDetailActivity.startActivity(getActivity(), options, mediaItem); } private void onMoreItemClicked(MorePresenter.MoreItem moreItem) { switch (moreItem.getId()) { case R.id.more_player_tests: openPlayerTestDialog(); break; case R.id.more_item_settings: TVPreferencesActivity.startActivity(getActivity()); break; case R.id.yts_filter_a_to_z: case R.id.yts_filter_trending: case R.id.yts_filter_release_date: case R.id.yts_filter_popular_now: case R.id.yts_filter_year: case R.id.yts_filter_top_rated: TVMediaGridActivity.startActivity(getActivity(), moreItem.getNavInfo().getLabel(), TVMediaGridActivity.ProviderType.MOVIE, moreItem.getNavInfo().getFilter(), moreItem.getNavInfo().getOrder(), null); break; case R.id.eztv_filter_a_to_z: case R.id.eztv_filter_trending: case R.id.eztv_filter_last_updated: case R.id.eztv_filter_popular_now: case R.id.eztv_filter_year: case R.id.eztv_filter_top_rated: TVMediaGridActivity.startActivity(getActivity(), moreItem.getNavInfo().getLabel(), TVMediaGridActivity.ProviderType.SHOW, moreItem.getNavInfo().getFilter(), moreItem.getNavInfo().getOrder(), null); break; case R.id.yts_filter_genres: Toast.makeText(getActivity(), "Not implemented yet", Toast.LENGTH_LONG).show(); break; } } private void openPlayerTestDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); final String[] file_types = getResources().getStringArray(R.array.file_types); final String[] files = getResources().getStringArray(R.array.files); builder.setTitle("Player Tests").setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { dialogInterface.dismiss(); } }).setSingleChoiceItems(file_types, -1, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int index) { dialogInterface.dismiss(); final String location = files[index]; if (location.equals("dialog")) { final EditText dialogInput = new EditText(getActivity()); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()).setView(dialogInput) .setPositiveButton("Start", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Movie media = new Movie(new MoviesProvider(), new YSubsProvider()); media.videoId = "dialogtestvideo"; media.title = "User input test video"; TVVideoPlayerActivity.startActivity(getActivity(), new StreamInfo(media, null, null, null, null, location), 0); } }); builder.show(); } final Movie media = new Movie(new MoviesProvider(), new YSubsProvider()); media.videoId = "bigbucksbunny"; media.title = file_types[index]; media.subtitles = new HashMap<>(); media.subtitles.put("en", "http://sv244.cf/bbb-subs.srt"); SubsProvider.download(getActivity(), media, "en", new Callback() { @Override public void onFailure(Request request, IOException e) { TVVideoPlayerActivity.startActivity(getActivity(), new StreamInfo(media, null, null, null, null, location)); } @Override public void onResponse(Response response) throws IOException { TVVideoPlayerActivity.startActivity(getActivity(), new StreamInfo(media, null, null, null, null, location)); } }); } }); builder.show(); } }