昨天已經把資料撈出來了
今天我們來塞進畫面吧
ArrayObjectAdapter 我自己的解讀是可以拆成三塊
再把他們合起來就是 數個物件的連接器 顧名思義就是將一堆物件串聯在一起
下面是我在其他文章中找到的兩張圖,大家應該可以稍微理解
而 Presenter 雖然翻作主持人,但我想其實應該是要控制物件的角色
所以在 BrowsSupportFragment 的實作中,會需要寫到很多 ArrayObjectAdapter
而 ArrayObjectAdapter 中也需要傳入各種繼承 Presenter 的類別去新建
這就是 BrowsSupportFragment 的架構
所以我們現在由小到大由內而外的先從呈現影片資訊的 CustomCardPresenter 開始
class CustomCardPresenter: Presenter(){
}
onCreateViewHolder
onBindViewHolder
onUnbindViewHolder
override fun onCreateViewHolder(parent: ViewGroup?): ViewHolder {
if(BuildConfig.DEBUG) Log.v(TAG, "===== onCreateViewHolder =====")
mContext = parent?.context
var cardView: ImageCardView = ImageCardView(mContext)
//顯示的類型
cardView.cardType = BaseCardView.CARD_TYPE_INFO_UNDER
return ViewHolder(cardView)
}
這裡補充一下在 onCreateViewHolder 中的 cardView.cardType
這是內容卡片的顯示類型,有以下四種
那我們現在 CustomCardPresenter 用的是 ImageCardView 而 ImageCardView 是以 ImageView 作為主要區域,標題和內容文字位於資訊區域,沒有設定額外的區域,所以 CARD_TYPE_INFO_UNDER 和CARD_TYPE_INFO_UNDER_WITH_EXTRA 之間的行為是相同的唷
再來是 ImageCardView,下面這張圖是它的結構,等等要依序填入相關內容
override fun onBindViewHolder(viewHolder: ViewHolder?, item: Any?) {
if(BuildConfig.DEBUG) Log.v(TAG, "===== onBindViewHolder =====")
if(viewHolder!=null){
val cardView: ImageCardView = viewHolder.view as ImageCardView
val movieItem: Item = item as Item
if(BuildConfig.DEBUG)Log.i(TAG, "movieItem: $movieItem")
cardView.titleText = movieItem.name
cardView.contentText = movieItem.imageUrl
cardView.setMainImageDimensions(280, 400)
if(mContext!=null){
Glide.with(mContext!!)
.load(movieItem.imageUrl)
.into(cardView.mainImageView)
}
}
}
接著要處理 MainFragment 裡的 ArrayObjectAdapter
我們要在昨天 init() 這個 function 裡新增幾行,程式碼如下
fun init(){
mRowsAdapter = ArrayObjectAdapter(ListRowPresenter())
val cardPresenter: CustomCardPresenter = CustomCardPresenter()
if(mMovieList!=null){
mMovieListData = mMovieList!!.data
if(mMovieListData!=null && mMovieListData!!.size>0){
for((index, categories) in mMovieListData!!.withIndex()){
val listRowAdapter: ArrayObjectAdapter = ArrayObjectAdapter(cardPresenter)
val categoryName: String? = categories.category_name
val items: List<Item>? = categories.items
if(items!=null && items.size>0){
for(item in items){
listRowAdapter.add(item)
}
val header: HeaderItem = HeaderItem(index.toLong(), categoryName)
if(mRowsAdapter!=null) mRowsAdapter!!.add(ListRow(header, listRowAdapter))
}
}
}
}
adapter = mRowsAdapter
if(context!=null){
//左側 HeaderSupportFragment 的背景
brandColor = ContextCompat.getColor(context!!, R.color.header_background)
//右側右上方 icon
badgeDrawable = ContextCompat.getDrawable(context!!, R.drawable.vscinemas_logo)
}
}
可以從程式碼看見多了一個 listRowAdapter (ArrayObjectAdapter) 傳進去的參數是剛剛新建的 CustomCardPresenter
我們用兩個 for 迴圈將每個 Cateogry 的 電影資訊(Item) 撈出來並透過 ArrayObjectAdapter 塞進去 CustomCardPresenter
之後再將每個電影的類型名稱(CategoryName)塞到 HeaderItem 裡,準備呈現在左側的 HeaderSupportFragment
最後用 ListRow 將 HeaderItem 和 listRowAdapter 包起來並透過最外層的 mRowsAdapter 塞到 ListRowPresenter 中
有點複雜,大家可能要多看幾次才會懂,哈
It-Iron-Man-Android-TV 的 Github 連結在此
今天專案選 Day 13 的 Commit 點喔~