預期效果是大多app都會用到的首頁頂部圖片banner,3s自動輪播,也可手動切換
用法很簡單,做attach就好(以下為kotlin代碼)
recyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) val snapHelper = PagerSnapHelper() snapHelper.attachToRecyclerView(recyclerView)
自動翻頁是定義的handler每3s執行一次bannerPos++然后recyclerView滾動,但是注意滾動的方法要使用
recyclerView.smoothScrollToPosition(bannerPos)
使用的話scrollToPosition()就不會有左右平滑的效果
如果需要同步更新Indicator,在recyclerView的滑動監聽里
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recycler: RecyclerView, newState: Int) { super.onScrollStateChanged(recycler, newState) when (newState) { RecyclerView.SCROLL_STATE_IDLE -> { val viewIdle = snapHelper.findSnapView(recyclerView.layoutManager) if (viewIdle != null) { val pos = recyclerView.layoutManager?.getPosition(viewIdle) ?: 0 updateIndicators(pos) } } } } }) /** * 更新到當前指示器 */ private fun updateIndicators(position: Int) { for (i in 0 until indicatorContainer.childCount) { val childView = indicatorContainer.getChildAt(i) childView.background = if (position == i) resources.getDrawable(R.drawable.shape_indicator_orange) else resources.getDrawable(R.drawable.shape_indicator_gray) } }
補充一下indicator的初始化方法
private fun setIndicators(bannerList: List<String>?) { //只有一頁的時候不顯示指示器 if (bannerList?.size ?: 0 <= 1) { return } indicatorContainer.removeAllViews() for (i in bannerList!!.indices) { val indicatorView = View(context) indicatorView.background = resources.getDrawable(R.drawable.shape_indicator_gray) val layoutParams: LinearLayout.LayoutParams = LinearLayout.LayoutParams( ConvertUtils.dp2px(6f), ConvertUtils.dp2px(6f) ) if (i != 0) layoutParams.leftMargin = ConvertUtils.dp2px(8f) indicatorView.layoutParams = layoutParams indicatorContainer.addView(indicatorView) } updateIndicators(indicatorContainer, 0) }
我這里把整個頁面都用一個recyclerView展示的,所以頂部banner也作為一個item嵌在數據里(感覺還是addHeader方法合理哈),嵌套在里面要更新呢就更新adapter,當時發現自動翻頁時滑動起來有重復頁面閃過的情況,這是因為adapter做notify的時候每次都重置到了第一頁再調用前面說的smooth方法滑動,所以中間頁面會展示出快速划過。
所以我在調用smooth滑動之前先把banner用scrollToPosition()方法無痕跡滑動到前一張,這樣就看不出閃頁了
if (bannerPos > 0){ recyclerView.scrollToPosition(bannerPos-1) }
