TV 縱向滑動列表介紹
構(gòu)建滑動列表的幾種方式:
- ListView / RecyclerView
- 自定義LinearLayout/ScrollView/ViewGroup
- 采用leanback庫
google leanback 庫簡介
“Leanback” 就是靠著看的意思榕暇。是指以放松的姿勢倒在沙發(fā)上.谷歌推出 android.support.v17.leanback 軟件包提供的 API 支持在電視設(shè)備上構(gòu)建用戶界面茧球。它為電視應(yīng)用提供了一些重要的小部件。這個庫只支持到api 17以上的版本晤锹,也就是andorid 4.2,而一些效果也只是在api-21以上支持坛吁。
demo介紹:
- 首先用android Tv的例子來介紹劳殖。運行程序時,整體內(nèi)容被對齊在一個網(wǎng)格布局里拨脉。左側(cè)的每一個標題header,都有右側(cè)對應(yīng)的一個內(nèi)容行row哆姻,他們是一一對應(yīng)的。header+content row由一個類 ListRow來表示玫膀。頁面的整體其實是ListRow的集合
- 整體是一個大的ArrayObjectAdapter 由一系列的ListRow來填充矛缨。view的呈現(xiàn)方式由ListRowPresenter來定義。
- 一個ListRow 由HeaderItem 和一個小的ArrayObjectAdapter組成,這個一行中的ArrayObjectAdapter中放置我們定義的view,呈現(xiàn)方式由CardPresenter來定義箕昭。
典型的代碼如下:
List<Movie> list = MovieList.setupMovies();
mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
CardPresenter cardPresenter = new CardPresenter();
for (int i = 0; i < NUM_ROWS; i++) {
if (i != 0) {
Collections.shuffle(list);
}
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
for (int j = 0; j < NUM_COLS; j++) {
listRowAdapter.add(list.get(j % 5));
}
HeaderItem header = new HeaderItem(i, MovieList.MOVIE_CATEGORY[i]);
mRowsAdapter.add(new ListRow(header, listRowAdapter));
}
setAdapter(mRowsAdapter);
- 基本關(guān)系:
ArrayObjectAdapter (RowsAdapter) ← A set of ListRow
ListRow = HeaderItem + ArrayObjectAdapter (RowAdapter)
ArrayObjectAdapter (RowAdapter) ← A set of Object (CardInfo/Item)
MVP的構(gòu)建模式
Leanback 提供了model-view-presenter mvp的方式來構(gòu)建應(yīng)用誉简。
model 是由應(yīng)用開發(fā)者來提供,leanback對于model的實現(xiàn)沒有加額外的限制盟广,任何對象都是可以的闷串。
view 還是由原來的android.view包下的類來實現(xiàn)。
Presenter 是基于現(xiàn)在的Adapter的該概念筋量,并擴充為更具的靈活性和組合性烹吵。特別的是,綁定數(shù)據(jù)到view上的操作已經(jīng)將adapter中分離出去桨武,這部分邏輯由presenter去承擔肋拔。
Presenter
Presenter class 是用來做數(shù)據(jù)和視圖的橋梁的
每一行的視圖展示,每一個卡片的視圖展示都是由Presenter來定義呀酸。Presenter是一個抽象類凉蜂,需要自己來繼承該類。
需要實現(xiàn)下面的三個方法:
- onCreateViewHolder(ViewGroup parent);
- OnBindViewHolder(ViewHolder ViewHolder,Ojbect item);
- onUnBindViewHolder(Viewholder viewhlder);可以看到這些方法跟RecyclerView 的Apdater的實現(xiàn)方法很像性誉,實際上這些方法就是借鑒了recyclerview的實現(xiàn)窿吩。
不同的是多了一個onUnBindViewHolder的方法,在這個方法里错览,可以做一下釋放資源的操作纫雁,主要包括圖片資源。
View
數(shù)據(jù)model的容器 ObjectAdapter,類似于RecyclerView.Adapter,但是將迭代展示每個item對應(yīng)的view的任務(wù)分離了出去倾哺。實現(xiàn)類有ArrayObjectAdapter和CursorOjbectAdapter,前者持有列表數(shù)據(jù)轧邪。我們可以是實現(xiàn)自己的ObjectAdapter的子類。
Preseter 負責將數(shù)據(jù)綁定到view上羞海,并呈現(xiàn)view忌愚;presener和ObjectAdapter合起來相當于現(xiàn)在的Android里的Adapter.這種分離的優(yōu)勢在于,我們可以在Adaper的范圍之外去控制view的創(chuàng)建却邓。例如一個view是從單個對象的數(shù)據(jù)中產(chǎn)生的硕糊,另外的view是有ObjectAdapter來提供數(shù)據(jù)。比如我們現(xiàn)在頁面的構(gòu)成是由一個header 加一個vip行申尤,再加多個相同模式的行癌幕。
PresenterSelector類衙耕,用來選擇用哪一個Presenter去對于ObjectAdapter提供的數(shù)據(jù)適配昧穿。通常是根據(jù)不同的item類型選擇Presenter去適配.現(xiàn)在的頁面中有多行相同視圖展示的,也有其他少數(shù)幾行展示的模式橙喘,這中情況下时鸵,例如聚好看的有頭部的一行,和進入vip的一行,還有其他的列表行饰潜,這種情況下就可以用初坠。
leanback 提供的基本界面是縱向的列表,每個行元素是一個橫向的列表彭雾,縱向列表和橫向列表都用ObjectAdapter來提供數(shù)據(jù)碟刺。
Row 是leanback中定義的一個抽象類,包含一個header和一個ListRow ,ListRow是Row的實現(xiàn)類薯酝,代表一個橫行.用ListRowPresenter來展示view.我們也可以定義自己的RowPresenter來定義行的展示半沽。
整體的介紹:
整體是一個縱向的recyclerview VerticalCardVeiw 是一個經(jīng)過改寫的recyclerview,增加了不少的適用于大屏幕的方法吴菠。
ItemBridgeAdapter 繼承自RecyclerView.Adapter,作為從RecyclerView.Adpater到Presenter的橋梁者填。
內(nèi)部持有PresenterSelector 的一個引用。
在getItemViewType 方法的實現(xiàn)中做葵,會返回相應(yīng)的Presenter,以此實現(xiàn)不同的item布局選擇占哟。在onCreateViewHolder的方法實現(xiàn)中,會調(diào)用在上面的方法里選擇出的Presenter 的presenter.onCreateViewHolder方法酿矢,返回一個Presenter.ViewHolder 該類是FacetProvider的實現(xiàn)類榨乎。 ItemBridgeAdapter 本身有一個Viewholder,持有上面生成的 presenter和一個itemVeiw.
在OnBindViewHolder中瘫筐,用上面拿到的presenter的引用來調(diào)用mPresenter.onBindViewHolder(viewHolder.mHolder, viewHolder.mItem)谬哀,如這次是CardPrenter的 onBindViewHolder在這個方法里執(zhí)行對數(shù)據(jù)與視圖的綁定。
在itemview不可見時严肪,onViewRecycled方法會被調(diào)用史煎,在這個里面會調(diào)用presenter.onUnbindViewHolder,從名字可以看出來這個是在解除view的綁定時執(zhí)行驳糯,通常在這個方法里執(zhí)行釋放資源的操作篇梭,例如釋放圖片的引用。