| /* |
| * 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(); |
| } |
| |
| } |
| } |
| } |