iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 13
0

昨天已經把資料撈出來了
今天我們來塞進畫面吧


What is ArrayObjectAdapter and Presenter

ArrayObjectAdapter 我自己的解讀是可以拆成三塊

  1. Array 數組、陣列
  2. Object 物件
  3. Adapter 連接器 (對岸是翻適配器)

再把他們合起來就是 數個物件的連接器 顧名思義就是將一堆物件串聯在一起
下面是我在其他文章中找到的兩張圖,大家應該可以稍微理解
https://ithelp.ithome.com.tw/upload/images/20200927/201071659Rd10eYZ6G.png
https://ithelp.ithome.com.tw/upload/images/20200927/20107165SxKvIUaaJC.png

Presenter 雖然翻作主持人,但我想其實應該是要控制物件的角色

所以在 BrowsSupportFragment 的實作中,會需要寫到很多 ArrayObjectAdapter
而 ArrayObjectAdapter 中也需要傳入各種繼承 Presenter 的類別去新建
這就是 BrowsSupportFragment 的架構

所以我們現在由小到大由內而外的先從呈現影片資訊的 CustomCardPresenter 開始

新建 CustomCardPresenter

  1. 新建一個叫 CustomCardPresenter 的 Class 並繼承 Presenter
class CustomCardPresenter: Presenter(){
}
  1. 覆寫 onCreateViewHolder onBindViewHolder onUnbindViewHolder
  2. 在 onCreateViewHolder 中寫下下面這段程式碼
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 這是內容卡片的顯示類型,有以下四種

  • CARD_TYPE_MAIN_ONLY 只顯示圖片
    https://ithelp.ithome.com.tw/upload/images/20200928/20107165fTbqSVVmtL.png
  • CARD_TYPE_INFO_OVER 顯示圖片跟內容,但是內容是壓在圖片上
    https://ithelp.ithome.com.tw/upload/images/20200928/20107165wAvX7O3iZC.png
  • CARD_TYPE_INFO_UNDER 顯示圖片跟內容,內容放在圖片下方
  • CARD_TYPE_INFO_UNDER_WITH_EXTRA 顯示圖片跟內容,內容放在圖片下方
    https://ithelp.ithome.com.tw/upload/images/20200928/201071652oFsfZAs7c.png

那我們現在 CustomCardPresenter 用的是 ImageCardView 而 ImageCardView 是以 ImageView 作為主要區域,標題和內容文字位於資訊區域,沒有設定額外的區域,所以 CARD_TYPE_INFO_UNDER 和CARD_TYPE_INFO_UNDER_WITH_EXTRA 之間的行為是相同的唷

再來是 ImageCardView,下面這張圖是它的結構,等等要依序填入相關內容
https://ithelp.ithome.com.tw/upload/images/20200928/20107165nn1Sx1z83n.jpg

  1. 在 onBindViewHolder 中寫下
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)
        }
    }
}
  1. 完成 CustomCardPresenter

接著要處理 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 中
有點複雜,大家可能要多看幾次才會懂,哈

以下就是我們今天完成的結果唷~
Yes

It-Iron-Man-Android-TV 的 Github 連結在此
今天專案選 Day 13 的 Commit 點喔~


上一篇
Day 12 - [實作]使用威秀影城做為 App 主要內容
下一篇
Day 14 - 多個 RowsSupportFragment
系列文
宅經濟起飛,想當顆沙發馬鈴薯嗎??智慧電視會是未來的趨勢嗎??讓我們一探 Android TV 的神秘世界30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言