blob: 9114d7ee0f0b25cfb6ff01bce29ff68da01ce356 [file] [log] [blame]
/*
* Copyright (C) 2014 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.example.android.tvleanback.ui;
import android.app.LoaderManager;
import android.content.Intent;
import android.content.Loader;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.support.v17.leanback.app.BackgroundManager;
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.ImageCardView;
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.ActivityOptionsCompat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.example.android.tvleanback.R;
import com.example.android.tvleanback.data.VideoItemLoader;
import com.example.android.tvleanback.data.VideoProvider;
import com.example.android.tvleanback.model.Movie;
import com.example.android.tvleanback.presenter.CardPresenter;
import com.example.android.tvleanback.presenter.GridItemPresenter;
import com.example.android.tvleanback.recommendation.UpdateRecommendationsService;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
/*
* Main class to show BrowseFragment with header and rows of videos
*/
public class MainFragment extends BrowseFragment implements
LoaderManager.LoaderCallbacks<HashMap<String, List<Movie>>> {
private static final String TAG = "MainFragment";
private static int BACKGROUND_UPDATE_DELAY = 300;
private static String mVideosUrl;
private final Handler mHandler = new Handler();
private ArrayObjectAdapter mRowsAdapter;
private Drawable mDefaultBackground;
private DisplayMetrics mMetrics;
private Timer mBackgroundTimer;
private URI mBackgroundURI;
private BackgroundManager mBackgroundManager;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
Log.d(TAG, "onCreate");
super.onActivityCreated(savedInstanceState);
loadVideoData();
prepareBackgroundManager();
setupUIElements();
setupEventListeners();
}
@Override
public void onDestroy() {
super.onDestroy();
if (null != mBackgroundTimer) {
Log.d(TAG, "onDestroy: " + mBackgroundTimer.toString());
mBackgroundTimer.cancel();
}
}
private void prepareBackgroundManager() {
mBackgroundManager = BackgroundManager.getInstance(getActivity());
mBackgroundManager.attach(getActivity().getWindow());
mDefaultBackground = getResources().getDrawable(R.drawable.default_background);
mMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics);
}
private void setupUIElements() {
setBadgeDrawable(getActivity().getResources().getDrawable(R.drawable.videos_by_google_banner));
setTitle(getString(R.string.browse_title)); // Badge, when set, takes precedent over title
setHeadersState(HEADERS_ENABLED);
setHeadersTransitionOnBackEnabled(true);
// set fastLane (or headers) background color
setBrandColor(getResources().getColor(R.color.fastlane_background));
// set search icon color
setSearchAffordanceColor(getResources().getColor(R.color.search_opaque));
}
private void loadVideoData() {
VideoProvider.setContext(getActivity());
mVideosUrl = getActivity().getResources().getString(R.string.catalog_url);
getLoaderManager().initLoader(0, null, this);
}
private void setupEventListeners() {
setOnSearchClickedListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(), SearchActivity.class);
startActivity(intent);
}
});
setOnItemViewClickedListener(new ItemViewClickedListener());
setOnItemViewSelectedListener(new ItemViewSelectedListener());
}
/*
* (non-Javadoc)
* @see android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader(int,
* android.os.Bundle)
*/
@Override
public Loader<HashMap<String, List<Movie>>> onCreateLoader(int arg0, Bundle arg1) {
Log.d(TAG, "VideoItemLoader created ");
return new VideoItemLoader(getActivity(), mVideosUrl);
}
/*
* (non-Javadoc)
* @see android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished(android
* .support.v4.content.Loader, java.lang.Object)
*/
@Override
public void onLoadFinished(Loader<HashMap<String, List<Movie>>> arg0,
HashMap<String, List<Movie>> data) {
mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
CardPresenter cardPresenter = new CardPresenter();
int i = 0;
for (Map.Entry<String, List<Movie>> entry : data.entrySet()) {
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
List<Movie> list = entry.getValue();
for (int j = 0; j < list.size(); j++) {
listRowAdapter.add(list.get(j));
}
HeaderItem header = new HeaderItem(i, entry.getKey());
i++;
mRowsAdapter.add(new ListRow(header, listRowAdapter));
}
HeaderItem gridHeader = new HeaderItem(i, getString(R.string.more_samples));
GridItemPresenter gridPresenter = new GridItemPresenter(this);
ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(gridPresenter);
gridRowAdapter.add(getString(R.string.grid_view));
gridRowAdapter.add(getString(R.string.error_fragment));
gridRowAdapter.add(getString(R.string.personal_settings));
mRowsAdapter.add(new ListRow(gridHeader, gridRowAdapter));
setAdapter(mRowsAdapter);
updateRecommendations();
}
@Override
public void onLoaderReset(Loader<HashMap<String, List<Movie>>> arg0) {
mRowsAdapter.clear();
}
protected void setDefaultBackground(Drawable background) {
mDefaultBackground = background;
}
protected void setDefaultBackground(int resourceId) {
mDefaultBackground = getResources().getDrawable(resourceId);
}
protected void updateBackground(String uri) {
int width = mMetrics.widthPixels;
int height = mMetrics.heightPixels;
Glide.with(getActivity())
.load(uri)
.centerCrop()
.error(mDefaultBackground)
.into(new SimpleTarget<GlideDrawable>(width, height) {
@Override
public void onResourceReady(GlideDrawable resource,
GlideAnimation<? super GlideDrawable>
glideAnimation) {
mBackgroundManager.setDrawable(resource);
}
});
mBackgroundTimer.cancel();
}
protected void updateBackground(Drawable drawable) {
BackgroundManager.getInstance(getActivity()).setDrawable(drawable);
}
protected void clearBackground() {
BackgroundManager.getInstance(getActivity()).setDrawable(mDefaultBackground);
}
private void startBackgroundTimer() {
if (null != mBackgroundTimer) {
mBackgroundTimer.cancel();
}
mBackgroundTimer = new Timer();
mBackgroundTimer.schedule(new UpdateBackgroundTask(), BACKGROUND_UPDATE_DELAY);
}
private void updateRecommendations() {
Intent recommendationIntent = new Intent(getActivity(), UpdateRecommendationsService.class);
getActivity().startService(recommendationIntent);
}
private class UpdateBackgroundTask extends TimerTask {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
if (mBackgroundURI != null) {
updateBackground(mBackgroundURI.toString());
}
}
});
}
}
private final class ItemViewClickedListener implements OnItemViewClickedListener {
@Override
public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
RowPresenter.ViewHolder rowViewHolder, Row row) {
if (item instanceof Movie) {
Movie movie = (Movie) item;
Log.d(TAG, "Movie: " + movie.toString());
Intent intent = new Intent(getActivity(), MovieDetailsActivity.class);
intent.putExtra(MovieDetailsActivity.MOVIE, movie);
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
getActivity(),
((ImageCardView) itemViewHolder.view).getMainImageView(),
MovieDetailsActivity.SHARED_ELEMENT_NAME).toBundle();
getActivity().startActivity(intent, bundle);
} else if (item instanceof String) {
if (((String) item).indexOf(getString(R.string.grid_view)) >= 0) {
Intent intent = new Intent(getActivity(), VerticalGridActivity.class);
startActivity(intent);
} else if (((String) item).indexOf(getString(R.string.error_fragment)) >= 0) {
Intent intent = new Intent(getActivity(), BrowseErrorActivity.class);
startActivity(intent);
} else {
Toast.makeText(getActivity(), ((String) item), Toast.LENGTH_SHORT)
.show();
}
}
}
}
private final class ItemViewSelectedListener implements OnItemViewSelectedListener {
@Override
public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
RowPresenter.ViewHolder rowViewHolder, Row row) {
if (item instanceof Movie) {
mBackgroundURI = ((Movie) item).getBackgroundImageURI();
startBackgroundTimer();
}
}
}
}