Skip to content

Commit 028a6b0

Browse files
committed
1. Icon on header
Model: IconHeaderItem View: icon_header_item.xml Presenter: IconHeaderItemPresenter 2. Refactoring of loadRows(), setRows()
1 parent 2bcde4e commit 028a6b0

14 files changed

Lines changed: 185 additions & 38 deletions

File tree

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.corochann.androidtvapptutorial.model;
2+
3+
import android.support.v17.leanback.widget.HeaderItem;
4+
5+
import com.corochann.androidtvapptutorial.ui.presenter.IconHeaderItemPresenter;
6+
7+
/**
8+
* Subclass of {@link HeaderItem} to hold icon resource id
9+
* to show icon on header with {@link IconHeaderItemPresenter}
10+
*/
11+
public class IconHeaderItem extends HeaderItem {
12+
13+
14+
private static final String TAG = IconHeaderItem.class.getSimpleName();
15+
public static final int ICON_NONE = -1;
16+
17+
/** Hold an icon resource id */
18+
private int mIconResId = ICON_NONE;
19+
20+
public IconHeaderItem(long id, String name, int iconResId) {
21+
super(id, name);
22+
mIconResId = iconResId;
23+
}
24+
25+
public IconHeaderItem(long id, String name) {
26+
this(id, name, ICON_NONE);
27+
}
28+
29+
public IconHeaderItem(String name) {
30+
super(name);
31+
}
32+
33+
public int getIconResId() {
34+
return mIconResId;
35+
}
36+
37+
public void setIconResId(int iconResId) {
38+
this.mIconResId = iconResId;
39+
}
40+
}

app/src/main/java/com/corochann/androidtvapptutorial/ui/MainFragment.java

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
import android.os.SystemClock;
1010
import android.support.v17.leanback.app.BrowseFragment;
1111
import android.support.v17.leanback.widget.ArrayObjectAdapter;
12-
import android.support.v17.leanback.widget.HeaderItem;
1312
import android.support.v17.leanback.widget.ListRow;
1413
import android.support.v17.leanback.widget.ListRowPresenter;
1514
import android.support.v17.leanback.widget.OnItemViewClickedListener;
1615
import android.support.v17.leanback.widget.OnItemViewSelectedListener;
1716
import android.support.v17.leanback.widget.Presenter;
17+
import android.support.v17.leanback.widget.PresenterSelector;
1818
import android.support.v17.leanback.widget.Row;
1919
import android.support.v17.leanback.widget.RowPresenter;
2020
import android.support.v4.app.NotificationCompat;
@@ -27,10 +27,12 @@
2727

2828
import com.corochann.androidtvapptutorial.R;
2929
import com.corochann.androidtvapptutorial.data.VideoItemLoader;
30+
import com.corochann.androidtvapptutorial.model.IconHeaderItem;
3031
import com.corochann.androidtvapptutorial.model.Movie;
3132
import com.corochann.androidtvapptutorial.recommendation.RecommendationFactory;
3233
import com.corochann.androidtvapptutorial.ui.background.PicassoBackgroundManager;
3334
import com.corochann.androidtvapptutorial.ui.presenter.CardPresenter;
35+
import com.corochann.androidtvapptutorial.ui.presenter.IconHeaderItemPresenter;
3436

3537
import java.util.ArrayList;
3638
import java.util.LinkedHashMap;
@@ -43,7 +45,10 @@
4345
public class MainFragment extends BrowseFragment {
4446
private static final String TAG = MainFragment.class.getSimpleName();
4547

48+
/* Adapter and ListRows */
4649
private ArrayObjectAdapter mRowsAdapter;
50+
private ListRow mGridItemListRow;
51+
ArrayList<ListRow> mVideoListRowArray;
4752

4853
/* Grid row item settings */
4954
private static final int GRID_ITEM_WIDTH = 300;
@@ -67,16 +72,18 @@ public void onActivityCreated(Bundle savedInstanceState) {
6772

6873
setupUIElements();
6974

75+
/* Set up rows with light data. done in main thread. */
7076
loadRows();
77+
setRows();
78+
79+
/* Set up rows with heavy data (data from web, content provider etc) is done in background thread using Loader */
7180
LoaderManager.enableDebugLogging(true);
7281
getLoaderManager().initLoader(VIDEO_ITEM_LOADER_ID, null, new MainFragmentLoaderCallbacks());
7382

74-
7583
setupEventListeners();
7684

7785
picassoBackgroundManager = new PicassoBackgroundManager(getActivity());
7886
picassoBackgroundManager.updateBackgroundWithDelay();
79-
//picassoBackgroundManager.updateBackgroundWithDelay("http://heimkehrend.raindrop.jp/kl-hacker/wp-content/uploads/2014/10/RIMG0656.jpg");
8087
}
8188

8289
private void setupEventListeners() {
@@ -155,39 +162,50 @@ private void setupUIElements() {
155162
setBrandColor(getResources().getColor(R.color.fastlane_background));
156163
// set search icon color
157164
setSearchAffordanceColor(getResources().getColor(R.color.search_opaque));
158-
}
159-
160165

166+
setHeaderPresenterSelector(new PresenterSelector() {
167+
@Override
168+
public Presenter getPresenter(Object o) {
169+
return new IconHeaderItemPresenter();
170+
}
171+
});
172+
}
161173

174+
/**
175+
* only load rows which can be prepared (executed in main thread) instantaneously.
176+
* UI update is done in {@link #setRows}
177+
*/
162178
private void loadRows() {
163-
mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
164-
165179
/* GridItemPresenter */
166-
HeaderItem gridItemPresenterHeader = new HeaderItem(0, "GridItemPresenter");
180+
IconHeaderItem gridItemPresenterHeader = new IconHeaderItem(0, "GridItemPresenter", R.drawable.ic_add_white_48dp);
167181

168182
GridItemPresenter mGridPresenter = new GridItemPresenter();
169183
ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(mGridPresenter);
170184
gridRowAdapter.add(GRID_STRING_ERROR_FRAGMENT);
171185
gridRowAdapter.add(GRID_STRING_GUIDED_STEP_FRAGMENT);
172186
gridRowAdapter.add(GRID_STRING_RECOMMENDATION);
173187
gridRowAdapter.add(GRID_STRING_SPINNER);
174-
mRowsAdapter.add(new ListRow(gridItemPresenterHeader, gridRowAdapter));
188+
mGridItemListRow = new ListRow(gridItemPresenterHeader, gridRowAdapter);
189+
}
175190

176-
/* CardPresenter */
177-
/*
178-
HeaderItem cardPresenterHeader = new HeaderItem(1, "CardPresenter");
179-
CardPresenter cardPresenter = new CardPresenter();
180-
ArrayObjectAdapter cardRowAdapter = new ArrayObjectAdapter(cardPresenter);
191+
/**
192+
* Updates UI after loading Row done.
193+
*/
194+
private void setRows() {
195+
mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); // Initialize
181196

182-
for (Movie movie : mItems) {
183-
cardRowAdapter.add(movie);
197+
if(mVideoListRowArray != null) {
198+
for (ListRow videoListRow : mVideoListRowArray) {
199+
mRowsAdapter.add(videoListRow);
200+
}
201+
}
202+
if(mGridItemListRow != null) {
203+
mRowsAdapter.add(mGridItemListRow);
184204
}
185-
186-
mRowsAdapter.add(new ListRow(cardPresenterHeader, cardRowAdapter));
187-
*/
188205

189206
/* Set */
190207
setAdapter(mRowsAdapter);
208+
191209
}
192210

193211
private class MainFragmentLoaderCallbacks implements LoaderManager.LoaderCallbacks<LinkedHashMap<String, List<Movie>>> {
@@ -214,22 +232,9 @@ public void onLoadFinished(Loader<LinkedHashMap<String, List<Movie>>> loader, Li
214232
/* Hold data reference to use it for recommendation */
215233
mItems = new ArrayList<Movie>();
216234

217-
mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
218-
219-
int index = 0;
220-
/* GridItemPresenter */
221-
HeaderItem gridItemPresenterHeader = new HeaderItem(index, "GridItemPresenter");
222-
index++;
223-
224-
GridItemPresenter mGridPresenter = new GridItemPresenter();
225-
ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(mGridPresenter);
226-
gridRowAdapter.add(GRID_STRING_ERROR_FRAGMENT);
227-
gridRowAdapter.add(GRID_STRING_GUIDED_STEP_FRAGMENT);
228-
gridRowAdapter.add(GRID_STRING_RECOMMENDATION);
229-
gridRowAdapter.add(GRID_STRING_SPINNER);
230-
mRowsAdapter.add(new ListRow(gridItemPresenterHeader, gridRowAdapter));
231-
232-
/* CardPresenter */
235+
/* loadRows: videoListRow - CardPresenter */
236+
int index = 1;
237+
mVideoListRowArray = new ArrayList<>();
233238
CardPresenter cardPresenter = new CardPresenter();
234239

235240
if (null != data) {
@@ -242,15 +247,16 @@ public void onLoadFinished(Loader<LinkedHashMap<String, List<Movie>>> loader, Li
242247
cardRowAdapter.add(movie);
243248
mItems.add(movie); // Add movie reference for recommendation purpose.
244249
}
245-
HeaderItem header = new HeaderItem(index, entry.getKey());
250+
IconHeaderItem header = new IconHeaderItem(index, entry.getKey(), R.drawable.ic_play_arrow_white_48dp);
246251
index++;
247-
mRowsAdapter.add(new ListRow(header, cardRowAdapter));
252+
mVideoListRowArray.add(new ListRow(header, cardRowAdapter));
248253
}
249254
} else {
250255
Log.e(TAG, "An error occurred fetching videos");
251256
}
257+
252258
/* Set */
253-
setAdapter(mRowsAdapter);
259+
setRows();
254260
}
255261
}
256262

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.corochann.androidtvapptutorial.ui.presenter;
2+
3+
import android.content.Context;
4+
import android.graphics.drawable.Drawable;
5+
import android.support.v17.leanback.widget.ListRow;
6+
import android.support.v17.leanback.widget.Presenter;
7+
import android.support.v17.leanback.widget.RowHeaderPresenter;
8+
import android.view.LayoutInflater;
9+
import android.view.View;
10+
import android.view.ViewGroup;
11+
import android.widget.ImageView;
12+
import android.widget.TextView;
13+
14+
import com.corochann.androidtvapptutorial.R;
15+
import com.corochann.androidtvapptutorial.model.IconHeaderItem;
16+
17+
/**
18+
* Customized HeaderItem Presenter to show {@link IconHeaderItem}
19+
*/
20+
public class IconHeaderItemPresenter extends RowHeaderPresenter {
21+
22+
private static final String TAG = IconHeaderItemPresenter.class.getSimpleName();
23+
24+
private float mUnselectedAlpha;
25+
26+
@Override
27+
public ViewHolder onCreateViewHolder(ViewGroup viewGroup) {
28+
mUnselectedAlpha = viewGroup.getResources()
29+
.getFraction(R.fraction.lb_browse_header_unselect_alpha, 1, 1);
30+
LayoutInflater inflater = (LayoutInflater) viewGroup.getContext()
31+
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
32+
33+
View view = inflater.inflate(R.layout.icon_header_item, null);
34+
35+
return new ViewHolder(view);
36+
}
37+
38+
@Override
39+
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object o) {
40+
IconHeaderItem iconHeaderItem = (IconHeaderItem) ((ListRow) o).getHeaderItem();
41+
View rootView = viewHolder.view;
42+
43+
ImageView iconView = (ImageView) rootView.findViewById(R.id.header_icon);
44+
int iconResId = iconHeaderItem.getIconResId();
45+
if( iconResId != IconHeaderItem.ICON_NONE) { // Show icon only when it is set.
46+
Drawable icon = rootView.getResources().getDrawable(iconResId, null);
47+
iconView.setImageDrawable(icon);
48+
}
49+
50+
TextView label = (TextView) rootView.findViewById(R.id.header_label);
51+
label.setText(iconHeaderItem.getName());
52+
}
53+
54+
@Override
55+
public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
56+
// no op
57+
}
58+
59+
// TODO: TEMP - remove me when leanback onCreateViewHolder no longer sets the mUnselectAlpha,AND
60+
// also assumes the xml inflation will return a RowHeaderView
61+
@Override
62+
protected void onSelectLevelChanged(RowHeaderPresenter.ViewHolder holder) {
63+
// this is a temporary fix
64+
holder.view.setAlpha(mUnselectedAlpha + holder.getSelectLevel() *
65+
(1.0f - mUnselectedAlpha));
66+
}
67+
68+
}
97 Bytes
Loading
283 Bytes
Loading
97 Bytes
Loading
220 Bytes
Loading
102 Bytes
Loading
343 Bytes
Loading
113 Bytes
Loading

0 commit comments

Comments
 (0)