線上直播系統原始碼,橫向無限迴圈滾動的單行彈幕效果
線上直播系統原始碼,橫向無限迴圈滾動的單行彈幕效果實現的相關程式碼
實現思路分析
要實現上面的效果,我們先拆分下實現要素:
1、彈幕布局是從螢幕的右側向左側滾動,單個彈幕之間的間距是固定的(設計要求)
2、彈幕要支援無限滾動,出於效能要求,如果不在螢幕內的,應該移除,不能無限追加到記憶體裡面。
拆分完需求要素之後,針對上面的需求要素,做一下思路解答:
1、對於滾動和超出螢幕後移除,可以使用動畫來實現,動畫從螢幕右邊開始移動到螢幕左邊,監聽如果已經動畫結束,則remove掉佈局。
2、無限迴圈效果,可以使用兩個連結串列實現,一個儲存加入到螢幕的彈幕資料(A),另一個儲存未新增到螢幕的彈幕資料(B)。讓進入螢幕前將佈局從B中poll出來,新增到A中。反之,螢幕移除的時候從A中poll出來,新增到B中。
程式碼實現
首先建立出來一個彈幕資料物件類
data class Danmu( //頭像 var headerUrl: String? = null, //暱稱 var userName: String? = null, //資訊 var info: String? = null, )
要被使用的彈幕itemView
class DanmuItemView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : LinearLayoutCompat(context, attrs, defStyleAttr) { private var danmuItemView: TextView? = null var danmu: Danmu? = null init { LayoutInflater.from(context).inflate(R.layout.danmu_item, this, true) danmuItemView = findViewById(R.id.tvDanmuItem) } fun setDanmuEntity(danmu: Danmu) { this.danmu = danmu danmuItemView?.text = "我是一個彈幕~~~~~哈哈哈哈哈哈" + danmu.userName measure(0, 0) } }
接下來就是彈幕布局的容器類,用來控制動畫和資料交替。注意程式碼中有很有用的註釋
class DanmuView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : FrameLayout(context, attrs, defStyleAttr) { private var mWidth = 0 //為展示在螢幕上的彈幕資料 private val mDanMuList = LinkedList<Danmu>() //螢幕中展示的彈幕資料 private val mVisibleDanMuList = LinkedList<Danmu>() //判斷是否在執行 private val mIsRunning = AtomicBoolean(false) override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { super.onMeasure(widthMeasureSpec, heightMeasureSpec) mWidth = measuredWidth } /** * 新增彈幕資料 */ fun enqueueDanMuList(danMuList: ArrayList<Danmu>) { danMuList.forEach { if (this.mDanMuList.contains(it).not()) { this.mDanMuList.add(it) } } if (mWidth == 0) { viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { mWidth = measuredWidth viewTreeObserver.removeOnGlobalLayoutListener(this) if (mIsRunning.get().not()) { mDanMuList.poll()?.apply { //這裡是用來處理佈局的交替工作,前面分析有說明 mVisibleDanMuList.add(this) createDanMuItemView(this) } } } }) } else { if (mIsRunning.get().not()) { mDanMuList.poll()?.apply { //這裡是用來處理佈局的交替工作,前面分析有說明 mVisibleDanMuList.add(this) createDanMuItemView(this) } } } } private fun startDanMuAnimate(danMuItemView: DanmuItemView) { var isInit = false danMuItemView.animate() //注意這邊設定的便宜量是容器佈局的寬度+彈幕item佈局的寬度,這樣就確保滾動值剛好是從螢幕右側外到螢幕左側外 .translationXBy((-(mWidth + danMuItemView.measuredWidth)).toFloat()) .setDuration(6000) .setInterpolator(LinearInterpolator()) .setUpdateListener { val danMuTranslateX = (mWidth + danMuItemView.measuredWidth) * (it.animatedValue as Float) //這裡是關鍵,用來確保每個item佈局的間距一致,判斷如果滾動進入螢幕的距離剛好是自身+20dp,也就是剛好空出來了20dp之後,緊接著下一個彈幕布局開始新增並動起來。 if (danMuTranslateX >= danMuItemView.measuredWidth + Utils.convertDpToPixel(20F) && isInit.not()) { isInit = true mDanMuList.poll()?.apply { mVisibleDanMuList.add(this) createDanMuItemView(this) } } } .setListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator?) { if (mIsRunning.get().not()) { mIsRunning.set(true) } //很重要,在動畫結束,也就是佈局從螢幕移除之後,切記從佈局中移除掉, //並且進行一波資料交替,方便實現無線迴圈 danMuItemView.danmu?.let { mVisibleDanMuList.remove(it) mDanMuList.add(it) } removeView(danMuItemView) } }).start() } private fun createDanMuItemView(danMu: Danmu) { val danMuItemView = DanmuItemView(context).apply { setDanmuEntity(danMu) } //這裡將佈局新增之後,預設便宜到螢幕右側出螢幕,造成佈局總是從右?移動到?左的效果。 val param = LayoutParams(danMuItemView.measuredWidth, danMuItemView.measuredHeight) param.gravity = Gravity.CENTER_VERTICAL param.leftMargin = mWidth startDanMuAnimate(danMuItemView) addView(danMuItemView, param) } }
以上就是線上直播系統原始碼,橫向無限迴圈滾動的單行彈幕效果實現的相關程式碼, 更多內容歡迎關注之後的文章
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69978258/viewspace-2839989/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 直播系統原始碼,圖片一直滾動,迴圈滾動,豎向和橫向原始碼
- 線上直播系統原始碼,迴圈滾動RecyclerView的實現原始碼View
- 直播系統app原始碼,垂直,水平無限迴圈滑動APP原始碼
- javascript無限迴圈滾動JavaScript
- 影片直播app原始碼,純css實現橫向滾動APP原始碼CSS
- 直播平臺原始碼,迴圈滾動RecyclerView的實現原始碼View
- 線上直播原始碼,JS動態效果之,側邊欄滾動固定效果原始碼JS
- 直播系統原始碼,vue實現無縫滾動原始碼Vue
- 文字垂直迴圈滾動效果
- 線上直播系統原始碼,彈出警告/提示類彈窗原始碼
- 無縫迴圈滾動
- 支援橫向、豎向無限滾動和自定義指示器的廣告條BannerView和淘寶頭條效果View
- 線上直播系統原始碼,滾動式內容展示控制元件原始碼控制元件
- 直播軟體原始碼,橫向滾動 自定義底部指示器樣式原始碼
- 無限for迴圈(死迴圈)
- 直播商城原始碼,vue 彈窗 慣性滾動 加速滾動原始碼Vue
- 直播系統原始碼,雲朵左右移動迴圈動畫實現原始碼動畫
- js文字橫向無縫滾動程式碼例項JS
- 短視訊系統原始碼,直播間實現彈幕的自動傳送原始碼
- Unity2D橫板遊戲之背景視差與無限滾動效果Unity遊戲
- 線上直播系統原始碼,實現翻頁載入、下拉滾動載入原始碼
- 線上直播系統原始碼,LinearLayout下多個ListView實現滾動原始碼View
- 縱向控制的橫向滾動
- 百萬線上的美拍直播彈幕系統架構實現架構
- 線上直播系統原始碼,滑鼠懸停後彈出氣泡原始碼
- 線上直播原始碼,VUE 獲獎名單滾動顯示的兩種方式原始碼Vue
- 直播原始碼,懸浮窗滾動漸變色效果原始碼
- 一行程式碼實現滑鼠橫向滾動💪行程
- CSS實現迴圈無縫滾動CSS
- JavaScript圖片橫向無縫滾動詳解JavaScript
- android可以無限迴圈滑動的ViewPagerAndroidViewpager
- 線上直播系統原始碼,平臺彈窗自適應裝置原始碼
- Android彈幕功能實現,模仿鬥魚直播的彈幕效果Android
- 線上直播系統原始碼,強制應用全域性橫屏或豎屏原始碼
- ViewPager實現左右無限迴圈滑動Viewpager
- 線上直播系統原始碼,簡單實現Android應用的啟動頁原始碼Android
- bootstrap table 橫向滾動條boot
- 直播app系統原始碼,css優化滾動條樣式APP原始碼CSS優化