今天我們來解決之前在 Day 14 的時候遇到的問題
如何讓 HeaderSupportFragment 中的每個 HeaderItem 對應到一個 RowsSupportFragment
所以今天我們要用到 PageRow 和 FragmentFactory
這兩個從字面上來看
我們從 PageRow 的原始碼來看,其實很簡單,只有幾行
public class PageRow extends Row {
public PageRow(HeaderItem headerItem) {
super(headerItem);
}
@Override
final public boolean isRenderedAsRowView() {
return false;
}
}
主要就是在建構子中傳入 HeaderItem
所以到目前為止在 MainFragment 中我們只需要處理把左半部 HeaderItem 傳進 PageRow 中
並透過 ArrayObjectAdapter 把 PageRow 丟進 mainAdapter 中,最後在指定給 BrowseSupportFragment 的 adaper
程式碼如下
fun init(){
val mainAdapter: ArrayObjectAdapter = ArrayObjectAdapter(ListRowPresenter())
adapter = mainAdapter
if(mMovieList!=null){
mMovieListData = mMovieList!!.data
if(mMovieListData!=null && mMovieListData!!.isNotEmpty()){
for((categoryIndex, category) in mMovieListData!!.withIndex()){
val categoryName: String? = category.category_name
if(BuildConfig.DEBUG) Log.w(TAG, "categoryName: $categoryName")
val header: CustomHeaderItem = CustomHeaderItem(categoryIndex.toLong(), categoryName, category)
val pageRow: PageRow = PageRow(header)
mainAdapter.add(pageRow)
}
}
}
}
再來是 FragmentFactory 的部分
我們新創建一個 PageRowFragmentFactory 並繼承 BrowsSupportFragment.FragmentFactory<Fragment?>
繼承 FragmentFactory 必須要覆寫 createFragment 他會傳入我們剛剛傳入的 PageRow
那因為我們有三個 HeaderItem 分別是由三個不同的 RowsSupportFragment 來呈現
所以我們要把資料透過 HeaderItem 來取得,因此我寫了一個 CustomHeaderItem 繼承 HeaderItem 然後多加了一個參數 item 讓資料傳進來
完成後我們的 PageRowFragmentFactory 會長這樣
class PageRowFragmentFactory: BrowseSupportFragment.FragmentFactory<Fragment?>() {
private val TAG: String = javaClass.simpleName
override fun createFragment(row: Any?): Fragment? {
val row: Row = row as Row
val headerItem: CustomHeaderItem = row.headerItem as CustomHeaderItem
val item: Any? = headerItem.item
item?.run {
when(this){
is Data -> {
val subCategoryList: List<SubCategory>? = sub_categories
if(subCategoryList!=null && subCategoryList.isNotEmpty()){
val rowsSupportFragment: RowsSupportFragment = RowsSupportFragment()
val rowsAdapter: ArrayObjectAdapter = ArrayObjectAdapter(ListRowPresenter())
for ((subCategoryIndex, subCategory) in subCategoryList.withIndex()){
val subCategoryName: String? = subCategory.sub_category_name
if(BuildConfig.DEBUG) Log.d(TAG, "subCategoryName: $subCategoryName")
val items: List<Item>? = subCategory.items
val listRowAdapter: ArrayObjectAdapter = ArrayObjectAdapter(CustomCardPresenter())
if(items!=null && items.isNotEmpty()){
for(item in items){
if(BuildConfig.DEBUG) Log.i(TAG, "movieName: ${item.name}")
listRowAdapter.add(item)
}
val header: HeaderItem = HeaderItem(0, subCategoryName)
rowsAdapter.add(ListRow(header, listRowAdapter))
}
}
rowsSupportFragment.adapter = rowsAdapter
return rowsSupportFragment
}
}
}
}
return null
}
}
最後一個步驟
回到 MainFragment
在 init() 這個 function 底下
新增以下程式碼mainFragmentRegistry.registerFragment(PageRow::class.java, PageRowFragmentFactory())
這是用來註冊 FragmentFactory 的,到時候 MainFragment 會依據 PageRowFragmentFactory 回吐的 Fragment 去做置換
最後跑起來看看吧
如果出現以下畫面就是完成囉!!