直播網站程式原始碼,FlowLayoutManager 流式佈局
直播網站程式原始碼,FlowLayoutManager 流式佈局
import android.graphics.Rect import android.util.Log import android.util.SparseArray import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView class FlowLayoutManager : RecyclerView.LayoutManager() { companion object { const val TAG = "FlowLayoutManager2" } var widthFlow = 0 var heightFlow = 0 private var left = 0 private var top = 0 private var right = 0 private var useMaxWidth = 0 private var verticalScrollOffset = 0 var totalHeight = 0 private set private var row = Row() private val lineRows: MutableList<Row> = mutableListOf() private val allItemFrames = SparseArray<Rect>() override fun isAutoMeasureEnabled(): Boolean { return true } override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams { return RecyclerView.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT ) } override fun onLayoutChildren(recycler: RecyclerView.Recycler?, state: RecyclerView.State?) { Log.d(TAG, "onLayoutChildren") totalHeight = 0 var cuLineTop = top //當前行使用的高度 var cuLineWidth = 0 var itemLeft: Int var itemTop: Int var maxHeightItem = 0 row = Row() lineRows.clear() allItemFrames.clear() removeAllViews() if (itemCount == 0) { recycler?.let { detachAndScrapAttachedViews(it) } verticalScrollOffset = 0 return } if (childCount == 0 && state?.isPreLayout == true) { return } //onLayoutChildren方法在RecyclerView 初始化時 會執行兩遍 recycler?.let { detachAndScrapAttachedViews(it) } if (childCount == 0) { widthFlow = width heightFlow = height left = paddingLeft right = paddingRight top = paddingTop useMaxWidth = widthFlow - left - right } for (i in 0 until itemCount) { Log.d(TAG, "index:$i") val childAt = recycler?.getViewForPosition(i) ?: continue if (View.GONE == childAt.visibility) { continue } measureChildWithMargins(childAt, 0, 0) val childWidth = getDecoratedMeasuredWidth(childAt) val childHeight = getDecoratedMeasuredHeight(childAt) if ((cuLineWidth + childWidth) <= useMaxWidth) { itemLeft = left + cuLineWidth itemTop = cuLineTop val frame = allItemFrames.get(i) ?: Rect() frame.set(itemLeft, itemTop, itemLeft + childWidth, itemTop + childHeight) allItemFrames.put(i, frame) cuLineWidth += childWidth maxHeightItem = maxHeightItem.coerceAtLeast(childHeight) row.views.add(Item(childHeight, childAt, frame)) row.cuTop = cuLineTop row.maxHeight = maxHeightItem } else { // 換行 formatAboveRow() cuLineTop += maxHeightItem totalHeight += maxHeightItem itemTop = cuLineTop itemLeft = left val frame = allItemFrames.get(i) ?: Rect() frame.set(itemLeft, itemTop, itemLeft + childWidth, itemTop + childHeight) allItemFrames.put(i, frame) cuLineWidth = childWidth maxHeightItem = childHeight row.views.add(Item(childHeight, childAt, frame)) row.cuTop = cuLineTop row.maxHeight = maxHeightItem } //不要忘了最後一行進行重新整理下佈局 if (i == itemCount - 1) { formatAboveRow() totalHeight += maxHeightItem } } totalHeight = totalHeight.coerceAtLeast(getVerticalSpace()) Log.d(TAG, "onLayoutChildren totalHeight:$totalHeight") fillLayout(state) } private fun fillLayout(state: RecyclerView.State?) { if (state?.isPreLayout == true || itemCount == 0) { // 跳過preLayout,preLayout主要用於支援動畫 return } //對所有的行資訊進行遍歷 for (j in 0 until lineRows.size) { val row = lineRows[j] val views = row.views for (i in 0 until views.size) { val scrap = views[i].view measureChildWithMargins(scrap, 0, 0) addView(scrap) val frame = views[i].rect //將這個item佈局出來 layoutDecoratedWithMargins( scrap, frame.left , frame.top - verticalScrollOffset, frame.right , frame.bottom - verticalScrollOffset ) } } } private fun formatAboveRow() { var lineNeedWidth = 0 val views = row.views for (i in 0 until views.size) { //計算行高居中 val item = views[i] val view = item.view val position = getPosition(view) if (allItemFrames[position].top < row.cuTop + (row.maxHeight - item.useHeight) / 2) { val frame = allItemFrames[position] ?: Rect() frame.set( allItemFrames[position].left, row.cuTop + (row.maxHeight - item.useHeight) / 2, allItemFrames[position].right, row.cuTop + (row.maxHeight - item.useHeight) / 2 + getDecoratedMeasuredHeight(view) ) allItemFrames.put(position,frame) item.rect = frame views[i] = item } //計算行寬居中 lineNeedWidth += (item.rect.right - item.rect.left) } val off = (useMaxWidth - lineNeedWidth) / 2 for (item in views) { item.rect.left += off item.rect.right += off } lineRows.add(row) row = Row() } override fun canScrollVertically(): Boolean { return true } override fun scrollVerticallyBy( dy: Int, recycler: RecyclerView.Recycler?, state: RecyclerView.State? ): Int { return super.scrollVerticallyBy(dy, recycler, state) } private fun getVerticalSpace(): Int { return height - paddingBottom - paddingTop } //行資訊的定義 class Row(val views: MutableList<Item> = mutableListOf()) { //每一行的頭部座標 var cuTop: Int = 0 //每一行需要佔據的最大高度 var maxHeight: Int = 0 } //每個item的定義 class Item(val useHeight: Int, val view: View, var rect: Rect) }
以上就是直播網站程式原始碼,FlowLayoutManager 流式佈局, 更多內容歡迎關注之後的文章
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69978258/viewspace-2928686/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 直播原始碼網站,自定製配置頁面佈局和寫法原始碼網站
- 一對一直播系統原始碼,Flexbox+ReclyclerView實現流式佈局原始碼FlexView
- 短視訊平臺原始碼,自定義流式佈局--kotlin原始碼Kotlin
- 移動佈局基礎之 流式佈局
- 流式佈局管理器
- 成品直播原始碼推薦,常用的css居中佈局原始碼CSS
- 自定義流式佈局:ViewGroup的測量與佈局View
- 直播網站程式原始碼,【openpyxl】只讀模式、只寫模式網站原始碼模式
- 線上直播原始碼,flutter 溢位幾種佈局方案原始碼Flutter
- 直播網站原始碼,centos7修改密碼網站原始碼CentOS密碼
- 直播網站程式原始碼,採用Redis實現購物車功能網站原始碼Redis
- 快速利用RecyclerView的LayoutManager搭建流式佈局View
- Android實現RecyclerView巢狀流式佈局AndroidView巢狀
- 直播網站程式原始碼,element el-menu,前端做選單搜尋網站原始碼前端
- 網站版式能不能修改,自定義網站佈局網站
- flutter系列之:在flutter中使用流式佈局Flutter
- 直播原始碼網站,任意更改底部圖示顏色原始碼網站
- 影片直播原始碼,標題居中,底部按鈕為三個時居中佈局原始碼
- Android ViewGroup&&RadioGroup 換行流式標籤佈局AndroidView
- Bootstrap柵格佈局原始碼解讀boot原始碼
- 手機直播原始碼,實現圖片瀑布流式滑動效果原始碼
- 直播原始碼網站,實現文字自動翻轉效果原始碼網站
- 直播網站原始碼,vue工具類,時間格式化網站原始碼Vue
- 直播網站原始碼,修改el-input邊框顏色網站原始碼
- 直播原始碼網站,直播間小遊戲java遞迴的實現方式原始碼網站遊戲Java遞迴
- flex居中佈局程式碼例項Flex
- 三段程式碼打造好看的流式佈局,flutter之wrap【flutter20個例項之七】Flutter
- 直播系統app原始碼,自定義九宮格,計算器佈局,驗證碼認證APP原始碼
- 直播平臺原始碼,flutter 自定義九宮格,計算器佈局,驗證碼認證原始碼Flutter
- 初略講解Flutter的Wrap和Flow(流式佈局)Flutter
- 前端成神之路-移動web開發_流式佈局前端Web
- Element原始碼分析系列1一Layout(佈局)原始碼
- 直播網站原始碼,寫一個android底部導航欄框架網站原始碼Android框架
- 直播網站原始碼,CardView如何顯示出底背景樣式?網站原始碼View
- 直播原始碼網站,各式各樣的淡入淡出動畫原始碼網站動畫
- 影片直播網站原始碼,flutter 頂部滾動欄頁面網站原始碼Flutter
- 直播網站原始碼,css實現狀態平滑的動畫網站原始碼CSS動畫
- 快速學習掌握移動Web開釋出局總結(流式佈局+flex伸縮佈局+rem佈局+Boostrap框架 )(更新中)WebFlexREM框架