* like adding/ removing rows from app to launcher, play video within the app */ public class DynamicRowsFragment extends BrowseFragment { private static final String TAG = "DynamicRowsFragment"; private static final boolean DEBUG = false; private static final int BACKGROUND_UPDATE_DELAY = 300; private final Handler mHandler = new Handler(); private DisplayMetrics mMetrics; private URI mBackgroundURI; private BackgroundManager mBackgroundManager; private Runnable mBackgroudUpdateRunnable; /** * All channel contents related to this app. */ private List mChannelContents; /** * Fragment UI setup * * The following function/ class is closely related to the UI which is related to the fragment * itself */ /** * Basic UI setting, including header state/ search button etc */ private void setupUi() { setHeadersState(HEADERS_ENABLED); setHeadersTransitionOnBackEnabled(true); setTitle(getString(R.string.channel_publish_title)); setOnSearchClickedListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getActivity(), getString(R.string.implement_search), Toast.LENGTH_LONG).show(); } }); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setupUi(); ChannelContents.initializePlaylists(this.getActivity()); mChannelContents = ChannelContents.sChannelContents; loadRows(); prepareBackgroundManager(); setupEventListeners(); mBackgroudUpdateRunnable = new Runnable() { @Override public void run() { if (mBackgroundURI != null) { updateBackgroundImage(mBackgroundURI.toString()); } } }; } @Override public void onDestroy() { super.onDestroy(); mHandler.removeCallbacks(mBackgroudUpdateRunnable); } /** * Populate card/ adding-removing button into ArrayObjectAdapter */ private void loadRows() { ArrayObjectAdapter rowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); for (int i = 0; i < mChannelContents.size(); i++) { ChannelContents playlist = mChannelContents.get(i); List clips = playlist.getVideos(); ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new VideoContentCardPresenter()); for (int j = 0; j < clips.size(); ++j) { listRowAdapter.add(clips.get(j)); } HeaderItem header = new HeaderItem(i, playlist.getName()); rowsAdapter.add(new ListRow(header, listRowAdapter)); } /** * Add an additional settings row at the bottom for channel publish customization */ String json = Utils .inputStreamToString(getResources().openRawResource(R.raw.settings_row)); CardRow settingsRow = new Gson().fromJson(json, CardRow.class); /** * Set specialized icon presenter to current row */ ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new IconCardInChannelPublishPresenter(getActivity())); for (Card card : settingsRow.getCards()) { listRowAdapter.add(card); } HeaderItem settingRowHeader = new HeaderItem(settingsRow.getTitle()); Row settingCardRow = new CardListRow(settingRowHeader, listRowAdapter, settingsRow); rowsAdapter.add(settingCardRow); setAdapter(rowsAdapter); } /** * Click and select event listener */ private final class ItemViewClickedListener implements OnItemViewClickedListener { @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) { if (isAdded()) { if (item instanceof VideoContent) { VideoContent clip = (VideoContent) item; Intent intent = new Intent(getActivity(), VideoPlaybackActivity.class); intent.putExtra(VideoExampleActivity.TAG, clip); startActivity(intent); } else { /** * Add to home screen feature is not allowed in the system less than android O * a toast will be popped up as notification */ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { Toast.makeText(getActivity(), "Add to home screen not supported", Toast.LENGTH_SHORT) .show(); return; } Intent intent = new Intent(getActivity(), ChannelPublishActivity.class); startActivity(intent); } } } } private final class ItemViewSelectedListener implements OnItemViewSelectedListener { @Override public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) { if (item instanceof VideoContent) { mBackgroundURI = ((VideoContent) item).getBackgroundImageURI(); startBackgroundTimer(); } else { /** * make sure the background of other items are removed so the setting icon can be * seen clearly */ mHandler.removeCallbacks(mBackgroudUpdateRunnable); mBackgroundManager.setDrawable(null); } } } /** * Helper functions for background image loading and associated animation */ private void prepareBackgroundManager() { mBackgroundManager = BackgroundManager.getInstance(getActivity()); mBackgroundManager.attach(getActivity().getWindow()); mMetrics = new DisplayMetrics(); getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics); } private void setupEventListeners() { setOnItemViewClickedListener(new ItemViewClickedListener()); setOnItemViewSelectedListener(new ItemViewSelectedListener()); } protected void updateBackgroundImage(String uri) { int width = mMetrics.widthPixels; int height = mMetrics.heightPixels; Glide.with(getActivity()) .load(uri) .into(new SimpleTarget(width, height) { @Override public void onResourceReady(Drawable resource, Transition super Drawable> glideAnimation) { mBackgroundManager.setDrawable(resource); } }); mHandler.removeCallbacks(mBackgroudUpdateRunnable); } private void startBackgroundTimer() { mHandler.removeCallbacks(mBackgroudUpdateRunnable); mHandler.postDelayed(mBackgroudUpdateRunnable, BACKGROUND_UPDATE_DELAY); } }