RecyclerView實現(xiàn)垂直自動無限滾動尼酿,類似于中獎信息美澳,跑馬燈
實現(xiàn)RecyclerView中的效果有兩種:
一種為以item為單體,每隔多少秒進行滾動一次
一種為整體流形式進行緩慢滾動
效果圖
實現(xiàn)無限滾動
這里實現(xiàn)無限滾動的方式為在adpater中設(shè)置itemCount為 Integer.MAX_VALUE
注意:此處基于BaseQuickAdapter的庫進行的必孤,也可直接使用原生
class MainAdatper(data: List<String>) : BaseQuickAdapter<String, BaseViewHolder>(R.layout.item_txt, data) {
override fun convert(helper: BaseViewHolder?, item: String?) {
helper?.setText(R.id.mTv, item)
}
override fun getItem(position: Int): String? {
val newPosition = position % data.size
return getData().get(newPosition)
}
override fun getItemViewType(position: Int): Int {
var count = getHeaderLayoutCount() + getData().size
//剛開始進入包含該類的activity時,count為0闸度。就會出現(xiàn)0%0的情況竭贩,這會拋出異常,所以我們要在下面做一下判斷
if (count <= 0) {
count = 1
}
var newPosition = position % count;
return super.getItemViewType(newPosition);
}
override fun getItemCount(): Int {
return Integer.MAX_VALUE
}
}
item為單位莺禁,每隔n秒滾動一個item
這邊主要是使用recyclerView中的smoothScrollToPosition() 方法實現(xiàn)留量,然后再配合自定義LinearSmoothScroller的calculateSpeedPerPixel控制速度,getVerticalSnapPreference實現(xiàn)滾動item置頂
mRv.layoutManager = LinearLayoutManager(this)
mRv.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
mRv.adapter = MainAdatper(data)
mSmoothScroll = object : LinearSmoothScroller(this) {
override fun getVerticalSnapPreference(): Int {
return LinearSmoothScroller.SNAP_TO_START
}
override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics?): Float {
// 移動一英寸需要花費3ms
return 3f / (displayMetrics?.density ?: 1f)
}
}
==============================================================
fun startAuto() {
if (mAutoTask != null && (mAutoTask?.isDisposed ?: true))
mAutoTask?.dispose()
//延時1秒,每2秒滾動一次
mAutoTask = Observable.interval(1, 2, TimeUnit.SECONDS).subscribe {
//定位到指定項如果該項可以置頂就將其置頂顯示
mSmoothScroll.targetPosition = it.toInt()
(mRv.layoutManager as LinearLayoutManager).startSmoothScroll(mSmoothScroll)
}
}
fun stopAuto() {
if (mAutoTask != null && (mAutoTask?.isDisposed ?: true)) {
mAutoTask?.dispose()
mAutoTask = null
}
}
override fun onStart() {
super.onStart()
//開始滾動
startAuto()
}
override fun onStop() {
super.onStop()
//停止?jié)L動
stopAuto()
}
流式滾動
流式滾動是使用recyclerView中的 smoothScrollBy(x, y) 方法來實現(xiàn)的
此處是通過自定義recyclerView來進行實現(xiàn)哟冬,也可直接在activity中進行實現(xiàn)楼熄。
class AutoScrollRecyclerView(mContext: Context, attrs: AttributeSet?) : RecyclerView(mContext, attrs) {
private var mAutoTask: Disposable? = null
//禁止手動滑動
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
return true
}
fun start() {
if (mAutoTask != null && !mAutoTask!!.isDisposed) {
mAutoTask!!.dispose()
}
mAutoTask = Observable.interval(1000, 100, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe { smoothScrollBy(0, 20) }
}
fun stop() {
if (mAutoTask != null && !mAutoTask!!.isDisposed) {
mAutoTask!!.dispose()
mAutoTask = null
}
}
}
==================================================
//在activity中調(diào)用開始滾動與停止?jié)L動
override fun onStart() {
super.onStart()
mRvTwo.start()
}
override fun onStop() {
super.onStop()
mRvTwo.stop()
}
項目地址
2018.10.24問題記錄:
- 自動滾動時出現(xiàn)越界異常(感謝@周曉川的問題反饋)
經(jīng)排查發(fā)現(xiàn)是使用了BaseRecyclerViewAdapterHelper舊版本2.9.21所導(dǎo)致
解決方案:
1.更新BaseRecyclerViewAdapterHelper庫至新版本2.9.30+
2.使用RecyclerView原生的adapter