iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 27
0
Mobile Development

宅經濟起飛,想當顆沙發馬鈴薯嗎??智慧電視會是未來的趨勢嗎??讓我們一探 Android TV 的神秘世界系列 第 27

Day 27 - 客製化 ListRowPresenter 來實作 Loop Banner 效果 Part3

今天我們要來完成 Banner 的效果啦!!

修改 CustomListRowPresenter

我們在 constructor 的地方新增一個參數叫 isBanner 來判斷是不是要做 Banner 的處理

class CustomListRowPresenter(var mContext: Context?,
                             var mFocusType: FocusType? = FocusType.NORMAL,
                             var isBanner: Boolean = false,
                             focusHightlightMode: Int = FocusHighlight.ZOOM_FACTOR_MEDIUM): ListRowPresenter(focusHightlightMode) {

新增 OnLayoutCompletedListener

接下來在 onBindViewHolder 裡新增以下片段

addOnLayoutCompletedListener(object : BaseGridView.OnLayoutCompletedListener{
    override fun onLayoutCompleted(state: RecyclerView.State) {
        if(!isHorizontalGridViewInitFinish){
            isHorizontalGridViewInitFinish = true
            mNotifyDataType = NotifyDataType.INCREASE
            notifyData()
        }
    }
})

這邊要注意的是
HorizontalGridView 在 androidx.leanback:leanback:1.0.0 中是沒有 onLayoutCompletedListener 的
他目前還在 alpha 版中,所以要到 Gradle 中修改版本成 1.1.0-alpha05

implementation 'androidx.leanback:leanback:1.1.0-alpha05'

接著講講 isHorizontalGridViewInitFinish 我們會需要這個變數的原因是因為
onLayoutCompletedListener 的觸發時機是在它塞好資料完成 Select 後會觸發
因此 isHorizontalGridViewInitFinish 這就是控制它我們剛塞好資料後要將第0筆資料移動到第1個焦點
以及避免每次 select 完成後都觸發到移動資料的行為

新增 OnChildViewHolderSelectedListener

接下來在一樣在 onBindViewHolder 裡新增以下片段

addOnChildViewHolderSelectedListener(object: OnChildViewHolderSelectedListener(){
    override fun onChildViewHolderSelected(
        parent: RecyclerView?,
        child: RecyclerView.ViewHolder?,
        position: Int,
        subposition: Int
    ) {
        if(position==parent.adapter!!.itemCount-1){
            mNotifyDataType = NotifyDataType.DECREASE
            notifyData()
        }else if(position==0){
            mNotifyDataType = NotifyDataType.INCREASE
            notifyData()
        }
    }
})

這裡就是在呼應昨天所說的
我的焦點只會在第一個到倒數第二個中間移動
所以當他 Select 到第0個焦點位置時,前面必須在塞入最後一筆資料讓第0筆資料維持在第1個焦點位置
相反的也是一樣
當他 Select 到最後一個焦點位置時,後面必須在塞入第0筆資料讓最後一筆資料維持在倒數第二個焦點位置

notifyData()

fun notifyData() {
    Log.v(TAG, "===== notifyData =====")
    if (mListRow != null && vHorizontalGridView!=null) {
        var adapter: ArrayObjectAdapter = mListRow!!.adapter as ArrayObjectAdapter
        Log.e(TAG, "adapter is null or not?? ${adapter == null}")
        Log.e(TAG, "adapter size?? ${adapter.size()}")
        Handler().postDelayed(Runnable {

            var count: Int = adapter.size()
            var fromPosition: Int = 0
            var toPosition: Int = 0
            when (mNotifyDataType) {
                NotifyDataType.INCREASE -> {
                    fromPosition = count - 1
                    toPosition = 0
                }
                NotifyDataType.DECREASE -> {
                    fromPosition = 0
                    toPosition = count - 1
                }
            }

            Log.e(TAG, "count: $count")
            Log.e(TAG, "fromPosition: $fromPosition")
            Log.e(TAG, "toPosition: $toPosition")
            var imageUrl: String? =
                adapter.get(fromPosition) as String
            adapter.remove(imageUrl)
            adapter.add(toPosition, imageUrl)
            for (i in 0 until adapter.size()) {
                Log.i(TAG, "imageUrl: ${(adapter.get(i) as String)}")
            }

        }, 100)
    }
}

這個 function 移動資料 的步驟了

完成!!

Yes

Github 在這裡唷~


上一篇
Day 26 - 客製化 ListRowPresenter 來實作 Loop Banner 效果 Part2
下一篇
Day 28 - 上架 App 到 Google Play Store for Android TV Part 1
系列文
宅經濟起飛,想當顆沙發馬鈴薯嗎??智慧電視會是未來的趨勢嗎??讓我們一探 Android TV 的神秘世界30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言