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 移动资料 的步骤了

完成!!

Github 在这里唷~


<<:  Gamma校正

>>:  Day 26 讨论 AI 深度学习论点

android studio 30天学习笔记-day 16-databinding Recyclerview

今天会使用databinding的方式去实作一个Recyclerview。 建立model publ...

Day.3 「建构网页的基石!」 —— 使用网页标签

我们前面已经稍微认识了网页的架构了,就像乐高一块一块堆叠起来,前一篇已经介绍的就不多赘述了。 虽然...

【Day 26】指标介绍(下)

指标可以进行许多运算,让我们看看下面的例子: #include<stdio.h> int...

JavaScript Day21 - AJAX(3)

axios axios 是处理 AJAX 的套件,是透过 JavaScript Day19 - AJ...

[Day29] HTB Netmon

URL : https://app.hackthebox.eu/machines/Netmon I...