今天我們要來完成 Banner 的效果啦!!
我們在 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) {
接下來在 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 完成後都觸發到移動資料的行為
接下來在一樣在 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筆資料讓最後一筆資料維持在倒數第二個焦點位置
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 在這裡唷~