package io.github.xwz.base.fragments; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.support.v17.leanback.app.BrowseFragment; import android.support.v17.leanback.widget.ArrayObjectAdapter; import android.support.v17.leanback.widget.BrowseFrameLayout; 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.Presenter; import android.support.v17.leanback.widget.Row; import android.support.v17.leanback.widget.RowPresenter; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import android.util.TypedValue; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.ProgressBar; import android.widget.TextView; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import io.github.xwz.base.R; import io.github.xwz.base.Utils; import io.github.xwz.base.adapters.BaseArrayAdapter; import io.github.xwz.base.adapters.CardSelector; import io.github.xwz.base.api.CategoryModel; import io.github.xwz.base.api.EpisodeBaseModel; import io.github.xwz.base.content.ContentManagerBase; public abstract class MainFragment extends BrowseFragment { private static final String TAG = "MainFragment"; private ProgressBar progress; private TextView progressText; private static final int SHOW_CATEGORY_COUNT = 30; private final BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.d(TAG, "Action: " + action); if (ContentManagerBase.CONTENT_SHOW_LIST_DONE.equals(action)) { updateAdapter(); getContentManger().updateRecommendations(getActivity()); } else if (ContentManagerBase.CONTENT_SHOW_LIST_PROGRESS.equals(action)) { String msg = intent.getStringExtra(ContentManagerBase.CONTENT_TAG); updateProgress(msg); } } }; protected abstract ContentManagerBase getContentManger(); @Override public void onActivityCreated(Bundle savedInstanceState) { Log.i(TAG, "onCreate"); super.onActivityCreated(savedInstanceState); setupUIElements(); setupListeners(); } @SuppressWarnings("deprecation") protected void setupUIElements() { setHeadersState(HEADERS_DISABLED | HEADERS_HIDDEN); setupHeader(); View root = getView(); if (root != null) { progress = new ProgressBar(getActivity()); progress.setLayoutParams(new FrameLayout.LayoutParams(150, 150, Gravity.CENTER)); progressText = new TextView(getActivity()); FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER); lp.topMargin = 150; progressText.setLayoutParams(lp); progressText.setGravity(Gravity.CENTER); progressText.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.fontHuge)); BrowseFrameLayout frame = getBrowseFrame(root); frame.addView(progress); frame.addView(progressText); } } protected abstract void setupHeader(); protected abstract BrowseFrameLayout getBrowseFrame(View root); private void hideProgress() { if (progress != null) { progress.setVisibility(View.GONE); } if (progressText != null) { progressText.setVisibility(View.GONE); } } private void updateProgress(String msg) { if (progressText != null) { progressText.setText(msg); } } private void setupListeners() { setOnSearchClickedListener(getSearchClickedListener()); setOnItemViewClickedListener(getItemClickedListener()); } private View.OnClickListener getSearchClickedListener() { return new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(getActivity(), getSearchActivityClass()); startActivity(intent); } }; } private OnItemViewClickedListener getItemClickedListener() { return new OnItemViewClickedListener() { @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) { if (item instanceof CategoryModel) { Intent intent = new Intent(getActivity(), getCategoryActivityClass()); intent.putExtra(ContentManagerBase.CONTENT_ID, ((CategoryModel) item).getTitle()); startActivity(intent); } else if (item instanceof EpisodeBaseModel) { Intent intent = new Intent(getActivity(), getDetailsActivityClass()); intent.putExtra(ContentManagerBase.CONTENT_ID, (EpisodeBaseModel) item); startActivity(intent); } } }; } protected abstract Class<?> getSearchActivityClass(); protected abstract Class<?> getDetailsActivityClass(); protected abstract Class<?> getCategoryActivityClass(); private LinkedHashMap<String, List<EpisodeBaseModel>> getAllShows() { LinkedHashMap<String, List<EpisodeBaseModel>> all = new LinkedHashMap<>(); List<EpisodeBaseModel> recent = getContentManger().getRecentlyPlayed(); if (recent.size() > 0) { all.put(ContentManagerBase.RECENTLY_PLAYED, recent); } for (Map.Entry<String, List<EpisodeBaseModel>> collection : getContentManger().getAllShowsByCategories().entrySet()) { all.put(collection.getKey(), collection.getValue()); } return all; } private void updateRows(ArrayObjectAdapter adapter) { Log.d(TAG, "Update rows"); LinkedHashMap<String, List<EpisodeBaseModel>> all = getAllShows(); int currentRows = adapter.size(); int newRows = all.size(); List<String> categories = new ArrayList<>(all.keySet()); for (int i = 0; i < newRows; i++) { String category = categories.get(i); List<EpisodeBaseModel> episodes = new ArrayList<>(all.get(category)); if (SHOW_CATEGORY_COUNT > 0 && episodes.size() > SHOW_CATEGORY_COUNT) { CategoryModel collection = new CategoryModel(category); collection.setEpisodeCount(episodes.size()); episodes.add(0, collection); } if (i < currentRows) { // update row ListRow row = (ListRow) adapter.get(i); row.setHeaderItem(new HeaderItem(i, Utils.stripCategory(category))); BaseArrayAdapter<EpisodeBaseModel> items = (BaseArrayAdapter<EpisodeBaseModel>) row.getAdapter(); items.replaceItems(episodes); } else { // add BaseArrayAdapter<EpisodeBaseModel> items = new BaseArrayAdapter<>(new CardSelector()); items.addAll(0, episodes); HeaderItem header = new HeaderItem(i, Utils.stripCategory(category)); ListRow row = new ListRow(header, items); adapter.add(row); } } int deleteRows = currentRows - newRows; if (deleteRows > 0) { adapter.removeItems(newRows, deleteRows); } } private void updateRecentlyPlayed() { ArrayObjectAdapter adapter = (ArrayObjectAdapter) getAdapter(); if (adapter != null) { ListRow row = (ListRow) adapter.get(0); if (ContentManagerBase.RECENTLY_PLAYED.equals(row.getHeaderItem().getName())) { Log.d(TAG, "Update recently played"); BaseArrayAdapter<EpisodeBaseModel> items = (BaseArrayAdapter<EpisodeBaseModel>) row.getAdapter(); List<EpisodeBaseModel> recent = getContentManger().getRecentlyPlayed(); items.replaceItems(recent); } else { updateRows(adapter); } } } private void updateAdapter() { ArrayObjectAdapter adapter = (ArrayObjectAdapter) getAdapter(); if (adapter == null) { adapter = new ArrayObjectAdapter(new ListRowPresenter()); updateRows(adapter); setAdapter(adapter); } else { updateRows(adapter); } hideProgress(); } @Override public void onResume() { super.onResume(); registerReceiver(); boolean update = getAdapter() == null || getAdapter().size() == 0; getContentManger().fetchShowList(update); updateRecentlyPlayed(); } public void onPause() { super.onPause(); LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(receiver); } private void registerReceiver() { Log.i(TAG, "Register receiver"); IntentFilter filter = new IntentFilter(); filter.addAction(ContentManagerBase.CONTENT_SHOW_LIST_START); filter.addAction(ContentManagerBase.CONTENT_SHOW_LIST_DONE); filter.addAction(ContentManagerBase.CONTENT_SHOW_LIST_ERROR); filter.addAction(ContentManagerBase.CONTENT_SHOW_LIST_PROGRESS); LocalBroadcastManager.getInstance(getActivity()).registerReceiver(receiver, filter); } }