Android 輕松實現 增強版靈活的 滑動式表格視圖

表格視圖組件,支持:
1. ?無標題模式:只有數據行也可以正常滑動
2. ?兩種滑動模式:固定第一列 或 全部滑動
3. ?全面的樣式自定義能力
4. ?智能列寬計算

?1. 無標題模式支持


設置無標題:調用?

setHeaderData(null)

setHeaderData(emptyList())

自動調整:
? ??隱藏標題行相關視圖
? ??智能計算列寬時忽略標題行
? ? 保持數據行正常顯示和滑動

?2. 兩種滑動模式


固定第一列模式:

 tableView.setScrollMode(FlexibleTableView.ScrollMode.FIXED_FIRST_COLUMN)

? ? 第一列垂直固定
? ??標題行和內容區域可水平滾動
? ? 適合需要固定標識列的場景

全滑動模式:

? ? tableView.setScrollMode(FlexibleTableView.ScrollMode.FULL_SCROLL)

? ?- 整個表格可水平滾動
? ?- 標題行和內容區域同步滾動
? ?- 適合所有列同等重要的場景

3. 智能列寬計算


等寬模式:

? ? tableView.setEqualColumnWidth(true)

? - 所有列使用相同寬度

? - 寬度取所有列內容最大寬度

自適應模式:

 tableView.setEqualColumnWidth(false)

每列根據內容計算寬度
可設置最小寬度保證可讀性最小寬度設置:

? // 設置第一列最小寬度tableView.setFirstColumnMinWidth(120) // 120dp// 設置其他列最小寬度tableView.setOtherColumnMinWidth(90) // 90dp

4. 全面的樣式自定義

   //標題行樣式:tableView.setHeaderTextColor(Color.WHITE)tableView.setHeaderBackgroundColor(Color.BLUE)//第一列樣式:tableView.setFirstColumnTextColor(Color.DKGRAY)tableView.setFirstColumnBackgroundColor(Color.LTGRAY)//內容區域樣式:tableView.setContentTextColor(Color.BLACK)tableView.setContentBackgroundColor(Color.WHITE)//網格線樣式:tableView.setGridLineColor(Color.GRAY)

使用方法示例

class MainActivity : AppCompatActivity() {private lateinit var tableView: FlexibleTableViewoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)tableView = findViewById(R.id.tableView)// 1. 設置表格模式tableView.setScrollMode(FlexibleTableView.ScrollMode.FIXED_FIRST_COLUMN)// 2. 設置表格列寬配置tableView.setEqualColumnWidth(true) // 所有列等寬tableView.setFirstColumnMinWidth(120) // 第一列最小寬度120dptableView.setOtherColumnMinWidth(90) ?// 其他列最小寬度90dp// 3. 設置樣式tableView.setHeaderTextColor(Color.WHITE)tableView.setHeaderBackgroundColor(Color.parseColor("#3F51B5"))tableView.setFirstColumnTextColor(Color.DKGRAY)tableView.setFirstColumnBackgroundColor(Color.parseColor("#E8EAF6"))tableView.setContentTextColor(Color.BLACK)tableView.setContentBackgroundColor(Color.parseColor("#F5F5F5"))tableView.setGridLineColor(Color.parseColor("#9E9E9E"))// 4. 場景1: 有標題行的情況setupWithHeaders()// 5. 場景2: 無標題行的情況setupWithoutHeaders()// 6. 添加切換按鈕setupModeSwitchButton()}private fun setupWithHeaders() {// 有標題行的數據val headers = listOf("產品", "一月", "二月", "三月", "四月", "五月", "六月")tableView.setHeaderData(headers)val products = listOf(listOf("智能手機", "1250", "1380", "1520", "1670", "1820", "1980"),listOf("筆記本電腦", "780", "820", "890", "920", "950", "980"),listOf("平板電腦", "620", "680", "710", "750", "790", "820"))tableView.setRowData(products)}private fun setupWithoutHeaders() {// 無標題行的數據tableView.setHeaderData(null) // 不設置標題行val data = listOf(listOf("張三", "90", "85", "95", "88", "92"),listOf("李四", "88", "92", "90", "85", "90"),listOf("王五", "78", "80", "85", "90", "86"),listOf("趙六", "92", "90", "88", "92", "94"),listOf("錢七", "76", "85", "80", "78", "82"))tableView.setRowData(data)}private fun setupModeSwitchButton() {val switchButton: Button = findViewById(R.id.switchModeButton)switchButton.setOnClickListener {val newMode = if (tableView.getScrollMode() == FlexibleTableView.ScrollMode.FIXED_FIRST_COLUMN) {FlexibleTableView.ScrollMode.FULL_SCROLL} else {FlexibleTableView.ScrollMode.FIXED_FIRST_COLUMN}tableView.setScrollMode(newMode)switchButton.text = if (newMode == FlexibleTableView.ScrollMode.FIXED_FIRST_COLUMN) {"切換到全滑動模式"} else {"切換到固定第一列模式"}}}
}

完整實現代碼

FlexibleTableView

class FlexibleTableView @JvmOverloads constructor(context: Context,attrs: AttributeSet? = null,defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {enum class ScrollMode {FIXED_FIRST_COLUMN, // 固定第一列模式FULL_SCROLL ? ? ? ?// 全部滑動模式}private val mContext: Context = contextprivate lateinit var rvHeader: RecyclerViewprivate lateinit var rvFirstColumn: RecyclerViewprivate lateinit var rvItems: RecyclerViewprivate lateinit var tvFirstHeader: TableCellprivate lateinit var headerAdapter: TableAdapterprivate lateinit var firstColumnAdapter: TableAdapterprivate lateinit var itemAdapter: TableAdapterprivate var headerList: List<String> = ArrayList()private val firstColumnList: MutableList<String> = ArrayList()private val itemList: MutableList<String> = ArrayList()// 樣式配置@ColorInt private var headerTextColor = Color.WHITE@ColorInt private var headerBackgroundColor = Color.parseColor("#3F51B5")@ColorInt private var firstColumnTextColor = Color.DKGRAY@ColorInt private var firstColumnBackgroundColor = Color.parseColor("#E8EAF6")@ColorInt private var contentTextColor = Color.BLACK@ColorInt private var contentBackgroundColor = Color.parseColor("#F5F5F5")@ColorInt private var gridLineColor = Color.parseColor("#9E9E9E")// 寬度配置private var firstColumnMinWidth = dpToPx(120) // 第一列最小寬度private var otherColumnMinWidth = dpToPx(100) // 其他列最小寬度private var equalColumnWidth = true // 是否等寬顯示// 滾動模式private var scrollMode = ScrollMode.FIXED_FIRST_COLUMN// 滾動位置緩存private var scrollX = 0private var scrollY = 0// 標題行可見性private var headerVisible = trueinit {initView()}private fun initView() {orientation = HORIZONTALremoveAllViews()when (scrollMode) {ScrollMode.FIXED_FIRST_COLUMN -> initFixedFirstColumnMode()ScrollMode.FULL_SCROLL -> initFullScrollMode()}}private fun initFixedFirstColumnMode() {// 固定第一列模式addView(createFixedColumnHeader())addView(createScrollableContentArea())setupAdapters()setupScrollSync()}private fun initFullScrollMode() {// 全滑動模式addView(createFullScrollContainer())setupAdapters()setupScrollSync()}private fun setupAdapters() {headerAdapter = TableAdapter(mContext)headerAdapter.isHeader(true)firstColumnAdapter = TableAdapter(mContext)itemAdapter = TableAdapter(mContext)if (::rvHeader.isInitialized) rvHeader.adapter = headerAdapterif (::rvFirstColumn.isInitialized) rvFirstColumn.adapter = firstColumnAdapterif (::rvItems.isInitialized) rvItems.adapter = itemAdapterif (::tvFirstHeader.isInitialized) {tvFirstHeader.setHeader(true)}}private fun setupScrollSync() {if (!::rvItems.isInitialized || !::rvFirstColumn.isInitialized) returnrvFirstColumn.addOnScrollListener(object : RecyclerView.OnScrollListener() {override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {super.onScrolled(recyclerView, dx, dy)if (recyclerView.scrollState != RecyclerView.SCROLL_STATE_IDLE) {rvItems.scrollBy(dx, dy)scrollY += dy}}})rvItems.addOnScrollListener(object : RecyclerView.OnScrollListener() {override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {super.onScrolled(recyclerView, dx, dy)if (recyclerView.scrollState != RecyclerView.SCROLL_STATE_IDLE) {rvFirstColumn.scrollBy(dx, dy)scrollY += dyscrollX += dx}}})}private fun createFixedColumnHeader(): LinearLayout {tvFirstHeader = TableCell(mContext, firstColumnMinWidth)tvFirstHeader.setGridLineColor(gridLineColor)tvFirstHeader.setTextColor(headerTextColor)tvFirstHeader.setHeaderBackgroundColor(headerBackgroundColor)tvFirstHeader.visibility = if (headerVisible) View.VISIBLE else View.GONEval lyHeader = LinearLayout(mContext)lyHeader.orientation = LinearLayout.VERTICALlyHeader.layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT,?LayoutParams.MATCH_PARENT)lyHeader.addView(tvFirstHeader)rvFirstColumn = RecyclerView(mContext)rvFirstColumn.layoutManager = LinearLayoutManager(mContext)lyHeader.addView(rvFirstColumn)return lyHeader}private fun createScrollableContentArea(): HorizontalScrollView {val layout = LinearLayout(mContext)layout.orientation = LinearLayout.VERTICALlayout.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT,?LayoutParams.MATCH_PARENT)// 標題行容器rvHeader = RecyclerView(mContext)rvHeader.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT,?LayoutParams.WRAP_CONTENT)rvHeader.visibility = if (headerVisible) View.VISIBLE else View.GONEval headerManager = LinearLayoutManager(mContext)headerManager.orientation = LinearLayoutManager.HORIZONTALrvHeader.layoutManager = headerManagerlayout.addView(rvHeader)// 內容行容器rvItems = RecyclerView(mContext)rvItems.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT,?LayoutParams.MATCH_PARENT)layout.addView(rvItems)val scrollView = HorizontalScrollView(mContext)scrollView.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT,?LayoutParams.MATCH_PARENT)scrollView.addView(layout)scrollView.isFillViewport = truescrollView.overScrollMode = View.OVER_SCROLL_NEVERscrollView.isHorizontalScrollBarEnabled = falsereturn scrollView}private fun createFullScrollContainer(): HorizontalScrollView {val container = LinearLayout(mContext)container.orientation = LinearLayout.VERTICALcontainer.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT,?LayoutParams.MATCH_PARENT)// 標題行(可滑動)rvHeader = RecyclerView(mContext)rvHeader.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT,?LayoutParams.WRAP_CONTENT)rvHeader.visibility = if (headerVisible) View.VISIBLE else View.GONEval headerManager = LinearLayoutManager(mContext)headerManager.orientation = LinearLayoutManager.HORIZONTALrvHeader.layoutManager = headerManagercontainer.addView(rvHeader)// 內容區域(包括第一列和其余列)val contentContainer = LinearLayout(mContext)contentContainer.orientation = LinearLayout.HORIZONTALcontentContainer.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT,?LayoutParams.MATCH_PARENT)// 第一列(在完整滑動模式下也包含在可滾動區域)val firstColumnContainer = LinearLayout(mContext)firstColumnContainer.orientation = LinearLayout.VERTICALfirstColumnContainer.layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT,?LayoutParams.MATCH_PARENT)tvFirstHeader = TableCell(mContext, firstColumnMinWidth)tvFirstHeader.setGridLineColor(gridLineColor)tvFirstHeader.setTextColor(headerTextColor)tvFirstHeader.setHeaderBackgroundColor(headerBackgroundColor)tvFirstHeader.visibility = if (headerVisible) View.VISIBLE else View.GONEfirstColumnContainer.addView(tvFirstHeader)rvFirstColumn = RecyclerView(mContext)rvFirstColumn.layoutManager = LinearLayoutManager(mContext)firstColumnContainer.addView(rvFirstColumn)contentContainer.addView(firstColumnContainer)// 其余列rvItems = RecyclerView(mContext)rvItems.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT,?LayoutParams.MATCH_PARENT)contentContainer.addView(rvItems)container.addView(contentContainer)val scrollView = HorizontalScrollView(mContext)scrollView.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT,?LayoutParams.MATCH_PARENT)scrollView.addView(container)scrollView.isFillViewport = truescrollView.overScrollMode = View.OVER_SCROLL_NEVERscrollView.isHorizontalScrollBarEnabled = falsescrollView.scrollTo(scrollX, 0)return scrollView}fun setHeaderData(headerData: List<String>?) {if (headerData == null || headerData.isEmpty()) {// 沒有標題行headerVisible = falseheaderList = emptyList()if (::tvFirstHeader.isInitialized) {tvFirstHeader.visibility = View.GONE}if (::rvHeader.isInitialized) {rvHeader.visibility = View.GONE}headerAdapter.setItemList(emptyList())return}// 有標題行headerVisible = trueheaderList = ArrayList(headerData)val headers = ArrayList(headerData)if (::tvFirstHeader.isInitialized) {tvFirstHeader.text = headers[0]tvFirstHeader.visibility = View.VISIBLE}headers.removeAt(0)headerAdapter.setItemList(headers)if (::rvHeader.isInitialized) {rvHeader.visibility = View.VISIBLE}if (::rvItems.isInitialized) {rvItems.layoutManager = GridLayoutManager(mContext, headerList.size - 1)}}fun setRowData(rowDataList: List<List<String>>) {if (rowDataList.isEmpty()) {// 清空數據firstColumnList.clear()itemList.clear()firstColumnAdapter.setItemList(emptyList())itemAdapter.setItemList(emptyList())return}// 確定列數:取第一行數據除去第一列后的列數val columnCount = rowDataList[0].size - 1// 設置GridLayoutManager的列數if (::rvItems.isInitialized) {rvItems.layoutManager = GridLayoutManager(mContext, columnCount)}// 處理數據firstColumnList.clear()itemList.clear()addRowData(rowDataList)}fun addRowData(rowDataList: List<List<String>>) {val list = ArrayList(rowDataList)for (rowData in list) {val row = ArrayList(rowData)if (row.isNotEmpty()) {firstColumnList.add(row[0])row.removeAt(0)itemList.addAll(row)}}firstColumnAdapter.setItemList(firstColumnList)itemAdapter.setItemList(itemList)if (::rvFirstColumn.isInitialized && ::rvItems.isInitialized) {rvFirstColumn.scrollTo(0, scrollY)rvItems.scrollTo(scrollX, scrollY)}calculateColumnWidths()}private fun calculateColumnWidths() {// 計算第一列寬度val firstColData = firstColumnList.toMutableList()if (headerVisible) {firstColData.add(tvFirstHeader.text.toString())}val firstColWidth = calculateColumnWidth(firstColData, firstColumnMinWidth)// 計算其他列寬度val otherColWidth = if (equalColumnWidth) {val maxOtherWidth = if (headerVisible) {maxOf(calculateColumnWidth(headerList, otherColumnMinWidth),calculateColumnWidth(itemList, otherColumnMinWidth))} else {calculateColumnWidth(itemList, otherColumnMinWidth)}maxOf(maxOtherWidth, otherColumnMinWidth)} else {if (headerVisible) {maxOf(calculateColumnWidth(headerList, otherColumnMinWidth),calculateColumnWidth(itemList, otherColumnMinWidth))} else {calculateColumnWidth(itemList, otherColumnMinWidth)}}// 設置寬度if (::tvFirstHeader.isInitialized) {tvFirstHeader.width = firstColWidth}firstColumnAdapter.setItemWidth(firstColWidth)headerAdapter.setItemWidth(otherColWidth)itemAdapter.setItemWidth(otherColWidth)}private fun calculateColumnWidth(data: List<String>, minWidth: Int): Int {if (data.isEmpty()) return minWidthvar maxWidth = minWidthval paint = Paint()paint.textSize = spToPx(14)for (text in data) {val textWidth = paint.measureText(text).toInt()val cellWidth = textWidth + dpToPx(20) // 加上內邊距if (cellWidth > maxWidth) {maxWidth = cellWidth}}return maxWidth}fun getItemCount(): Int = firstColumnList.size * (if (headerVisible) headerList.size - 1 else 0)// 樣式設置方法fun setHeaderTextColor(@ColorInt color: Int) {headerTextColor = colorif (::tvFirstHeader.isInitialized) {tvFirstHeader.setTextColor(color)}headerAdapter.setTextColor(color)}fun setHeaderBackgroundColor(@ColorInt color: Int) {headerBackgroundColor = colorif (::tvFirstHeader.isInitialized) {tvFirstHeader.setHeaderBackgroundColor(color)}headerAdapter.setBackgroundColor(color)}fun setFirstColumnTextColor(@ColorInt color: Int) {firstColumnTextColor = colorfirstColumnAdapter.setTextColor(color)}fun setFirstColumnBackgroundColor(@ColorInt color: Int) {firstColumnBackgroundColor = colorfirstColumnAdapter.setBackgroundColor(color)}fun setContentTextColor(@ColorInt color: Int) {contentTextColor = coloritemAdapter.setTextColor(color)}fun setContentBackgroundColor(@ColorInt color: Int) {contentBackgroundColor = coloritemAdapter.setBackgroundColor(color)}fun setGridLineColor(@ColorInt color: Int) {gridLineColor = colorif (::tvFirstHeader.isInitialized) {tvFirstHeader.setGridLineColor(color)}headerAdapter.setGridLineColor(color)firstColumnAdapter.setGridLineColor(color)itemAdapter.setGridLineColor(color)}// 寬度設置方法fun setEqualColumnWidth(enabled: Boolean) {equalColumnWidth = enabledcalculateColumnWidths()}fun setFirstColumnMinWidth(minWidthDp: Int) {firstColumnMinWidth = dpToPx(minWidthDp)calculateColumnWidths()}fun setOtherColumnMinWidth(minWidthDp: Int) {otherColumnMinWidth = dpToPx(minWidthDp)calculateColumnWidths()}// 滾動模式設置fun setScrollMode(mode: ScrollMode) {if (scrollMode != mode) {// 保存當前滾動位置scrollX = 0scrollY = 0scrollMode = modeinitView()// 重新應用數據if (headerList.isNotEmpty()) {setHeaderData(headerList)}if (firstColumnList.isNotEmpty()) {setRowData(firstColumnList.map { listOf(it) })}}}fun getScrollMode(): ScrollMode = scrollMode// 單位轉換工具private fun dpToPx(dp: Int): Int {return (dp * context.resources.displayMetrics.density).toInt()}private fun spToPx(sp: Int): Float {return sp * context.resources.displayMetrics.scaledDensity}
}
TableAdapter
@SuppressLint("NotifyDataSetChanged")
class TableAdapter(private val mContext: Context) : RecyclerView.Adapter<TableAdapter.MyViewHolder>() {private var mItemList: List<String> = ArrayList()private var itemWidth = 0private var isHeader = falseprivate var textColor = Color.BLACKprivate var backgroundColor = Color.WHITEprivate var gridLineColor = Color.GRAYfun setItemWidth(width: Int) {itemWidth = widthnotifyDataSetChanged()}fun setTextColor(color: Int) {textColor = colornotifyDataSetChanged()}fun setBackgroundColor(color: Int) {backgroundColor = colornotifyDataSetChanged()}fun setGridLineColor(color: Int) {gridLineColor = colornotifyDataSetChanged()}fun setItemList(itemList: List<String>) {mItemList = itemListnotifyDataSetChanged()}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {val cell = TableCell(mContext, itemWidth)cell.setHeader(isHeader)cell.setGridLineColor(gridLineColor)return MyViewHolder(cell)}override fun onBindViewHolder(holder: MyViewHolder, position: Int) {val item = mItemList[position]val tv = holder.itemView as TableCelltv.text = itemtv.setTextColor(textColor)tv.setCellBackgroundColor(backgroundColor)// 如果是表頭行,應用特殊樣式if (isHeader) {tv.setTextColor(textColor)tv.setHeaderBackgroundColor(backgroundColor)}}override fun getItemCount(): Int = mItemList.sizefun isHeader(isHeader: Boolean) {this.isHeader = isHeader}inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
}
TableCell
class TableCell @JvmOverloads constructor(context: Context,private var width: Int = ViewGroup.LayoutParams.WRAP_CONTENT
) : AppCompatTextView(context) {private var isHeader = falseprivate var gridLineColor = Color.GRAYprivate var headerBackgroundColor = Color.parseColor("#3F51B5")private var cellBackgroundColor = Color.WHITEinit {initView()}private fun initView() {setBackgroundColor(cellBackgroundColor)val params = LinearLayout.LayoutParams(width - 2, ViewGroup.LayoutParams.WRAP_CONTENT)params.setMargins(0, 0, 2, 2)layoutParams = paramstextSize = 14fgravity = Gravity.CENTERsetPadding(dpToPx(10), dpToPx(10), dpToPx(10), dpToPx(10))}fun setHeader(isHeader: Boolean) {this.isHeader = isHeadersetBackgroundColor(if (isHeader) headerBackgroundColor else cellBackgroundColor)setPadding(dpToPx(10),?dpToPx(if (isHeader) 15 else 10),?dpToPx(10),?dpToPx(if (isHeader) 15 else 10))}fun setHeaderBackgroundColor(color: Int) {headerBackgroundColor = colorif (isHeader) {setBackgroundColor(color)}}fun setCellBackgroundColor(color: Int) {cellBackgroundColor = colorif (!isHeader) {setBackgroundColor(color)}}fun setGridLineColor(color: Int) {gridLineColor = colorinvalidate()}override fun setWidth(pixels: Int) {width = pixelsrefreshWidth()}private fun refreshWidth() {val params = layoutParams as LinearLayout.LayoutParamsparams.width = width - 2params.setMargins(0, 0, 2, 2)layoutParams = params}override fun onDraw(canvas: Canvas) {// 繪制網格線val paint = Paint()paint.color = gridLineColorpaint.strokeWidth = 1f// 繪制右邊框canvas.drawLine(width.toFloat() - 2, 0f, width.toFloat() - 2, height.toFloat(), paint)// 繪制下邊框canvas.drawLine(0f, height.toFloat() - 2, width.toFloat(), height.toFloat() - 2, paint)// 表頭特殊樣式if (isHeader) {paint.style = Paint.Style.FILL_AND_STROKEpaint.strokeWidth = 1.5f}super.onDraw(canvas)}private fun dpToPx(dp: Int): Int {return (dp * context.resources.displayMetrics.density).toInt()}
}
在布局文件中添加表格視圖
?<com.yourpackage.FlexibleTableViewandroid:id="@+id/scrollTableView"android:layout_width="match_parent"android:layout_height="wrap_content" />

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/83844.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/83844.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/83844.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Python進階】元類編程

目錄 &#x1f31f; 前言&#x1f3d7;? 技術背景與價值&#x1fa79; 當前技術痛點&#x1f6e0;? 解決方案概述&#x1f465; 目標讀者說明 &#x1f9e0; 一、技術原理剖析&#x1f4ca; 核心概念圖解&#x1f4a1; 核心作用講解&#x1f527; 關鍵技術模塊說明?? 技術選…

DeepSeek模型性能優化:從推理加速到資源調度的全棧實踐

引言 在生產環境中部署DeepSeek模型時,性能優化直接關系到服務質量和運營成本。本文將深入探討從芯片級優化到分布式調度的全棧性能提升方案,涵蓋計算圖優化、內存管理、批處理策略等關鍵技術,并分享在千萬級QPS場景下的實戰經驗,幫助工程團隊突破性能瓶頸,實現成本與效能…

Ctrl+R 運行xxx.exe,發現有如下問題.

CtrlR 運行xxx.exe,發現有如下問題. (1)找不到Qt5Core.all,Qt5Cored.dll,Qt5Gui.dll,Qt5Guid.dll,Qt5Widgets.all,Qt5Widgetsd.dll? (2)之后找不到libwinpthread-1.dll 從這個目錄拷貝相應的庫到運行xx.exe目錄下 方法二:將庫路徑添加到系統PATH環境變量里: 在Path中添加路…

硅基計劃2.0 學習總結 陸 抽象類與接口

文章目錄 一、抽象類1. 定義2. 示例代碼3. 特性 二、接口初識1. 定義2. 命名與語法3. 示例代碼4. 常見特性5. 多接口實現6. 接口的繼承 三、Object類初識1. equals方法2. hascode方法 一、抽象類 1. 定義 請你假設這樣一個場景&#xff0c;我們定義一個人的類&#xff0c;這個…

Linux命令基礎(2)

su和exit命令 可以通過su命令切換到root賬戶 語法&#xff1a;su [-] 用戶名 -符號是可選的&#xff0c;表示是否在切換用戶后加載環境變量&#xff0c;建議帶上 參數&#xff1a;用戶名&#xff0c;表示要切換的用戶&#xff0c;用戶名可以省略&#xff0c;省略表示切換到ro…

C++算法訓練營 Day10 棧與隊列(1)

1.用棧實現隊列 LeetCode&#xff1a;232.用棧實現隊列 請你僅使用兩個棧實現先入先出隊列。隊列應當支持一般隊列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 實現 MyQueue 類&#xff1a; void push(int x)將元素x推到隊列的末尾 int pop(…

設計模式域——軟件設計模式全集

摘要 軟件設計模式是軟件工程領域中經過驗證的、可復用的解決方案&#xff0c;旨在解決常見的軟件設計問題。它們是軟件開發經驗的總結&#xff0c;能夠幫助開發人員在設計階段快速找到合適的解決方案&#xff0c;提高代碼的可維護性、可擴展性和可復用性。設計模式主要分為三…

【QT】自定義QWidget標題欄,可拖拽(拖拽時窗體變為normal大小),可最小/大化、關閉(圖文詳情)

目錄 0.背景 1.詳細實現 思路簡介 .h文件 .cpp文件 0.背景 Qt Linux&#xff1b;項目遇到問題&#xff0c;解決后特此記錄 項目需要&#xff0c;個性化的標題欄&#xff08;是個widget&#xff09;&#xff0c;在傳統的三個按鈕&#xff08;最大化、最小化、關閉&#xf…

如何用 pnpm patch 給 element-plus 打補丁修復線上 bug(以 2.4.4 修復 PR#15197 為例)

背景 在實際項目開發中&#xff0c;依賴的三方庫&#xff08;如 element-plus&#xff09;難免會遇到 bug。有時候官方雖然已經修復&#xff0c;但新版本升級成本高&#xff0c;或者有兼容性風險。這時&#xff0c;給依賴打補丁是最優雅的解決方案之一。 本文以 element-plus…

Spring AI 入門:Java 開發者的生成式 AI 實踐之路

一、Spring AI 簡介 在人工智能技術快速迭代的今天&#xff0c;Spring AI 作為 Spring 生態系統的新生力量&#xff0c;正在成為 Java 開發者擁抱生成式 AI 的最佳選擇。該框架通過模塊化設計實現了與主流 AI 服務&#xff08;如 OpenAI、Anthropic&#xff09;的無縫對接&…

優化電腦的磁盤和驅動器提高電腦性能和延長硬盤壽命?

磁盤優化 磁盤清理&#xff1a; 使用系統自帶的磁盤清理工具&#xff08;如Windows的“磁盤清理”&#xff09;刪除不必要的文件。清空回收站。刪除臨時文件和緩存。 磁盤碎片整理&#xff08;針對機械硬盤&#xff09;&#xff1a; 定期進行磁盤碎片整理&#xff0c;以提高文…

EDA斷供危機下的冷思考:中國芯片設計軟件的破局之道優雅草卓伊凡

EDA斷供危機下的冷思考&#xff1a;中國芯片設計軟件的破局之道優雅草卓伊凡 一、EDA是什么&#xff1f;芯片行業的”隱形基石” 1.1 EDA技術解析 EDA&#xff08;Electronic Design Automation&#xff0c;電子設計自動化&#xff09;是用于設計和驗證集成電路的軟件工具鏈…

Jpackage

簡介 jpackage - 用于打包自包含 Java 應用程序的工具&#xff0c;是 JDK 14 引入的一個工具。 該工具將 Java 應用程序和 Java 運行時映像作為輸入&#xff0c;并生成包含所有必要依賴項的 Java 應用程序映像。它將能夠生成特定于平臺的格式的本機包&#xff0c;例如包括打包 …

CRM管理軟件的數據可視化功能使用技巧:讓數據驅動決策

在當今數據驅動的商業環境中&#xff0c;CRM管理系統的數據可視化功能已成為企業優化客戶管理、提升銷售效率的核心工具。據企銷客研究顯示&#xff0c;具備優秀可視化能力的CRM系統&#xff0c;用戶決策效率可提升47%。本文將深入解析如何通過數據可視化功能最大化CRM管理軟件…

智慧充電:新能源汽車智慧充電樁的發展前景受哪些因素影響?

全球能源結構轉型與碳中和目標的推進&#xff0c;新能源汽車產業迎來爆發式增長&#xff0c;而智慧充電樁作為其核心基礎設施&#xff0c;發展前景備受關注。智慧充電不僅關乎用戶充電體驗的優化&#xff0c;更是電網平衡、能源效率提升的關鍵環節。 然而&#xff0c;其發展并…

ABAP設計模式之---“簡單設計原則(Simple Design)”

“Simple Design”&#xff08;簡單設計&#xff09;是軟件開發中的一個重要理念&#xff0c;倡導以最簡單的方式實現軟件功能&#xff0c;以確保代碼清晰易懂、易維護&#xff0c;并在項目需求變化時能夠快速適應。 其核心目標是避免復雜和過度設計&#xff0c;遵循“讓事情保…

多模態大語言模型arxiv論文略讀(105)

UnifiedMLLM: Enabling Unified Representation for Multi-modal Multi-tasks With Large Language Model ?? 論文標題&#xff1a;UnifiedMLLM: Enabling Unified Representation for Multi-modal Multi-tasks With Large Language Model ?? 論文作者&#xff1a;Zhaowei…

SQLServer中的存儲過程與事務

一、存儲過程的概念 1. 定義 存儲過程&#xff08;Stored Procedure&#xff09;是一組預編譯的 SQL 語句的集合&#xff0c;它們被存儲在數據庫中&#xff0c;可以通過指定存儲過程的名稱并執行來調用它們。存儲過程可以接受輸入參數、輸出參數&#xff0c;并且可以返回執行…

使用UDP連接ssh

使用UDP連接ssh mosh簡介兩端安裝moshWindows安裝mosh 放行端口使用mosh登錄Linuxdebug mosh簡介 Mosh最大的特點是基于UDP方式傳輸&#xff0c;支持在服務端創建一個臨時的Key供客戶端一次性連接&#xff0c;退出后失效&#xff1b;也支持通過SSH的配置進行認證&#xff0c;但…

軟件功能模塊歸屬論證方法

文章目錄 **一、核心設計原則****二、論證方法****三、常見決策模式****四、驗證方法****五、反模式警示****總結** 在討論軟件功能點應該歸屬哪些模塊時&#xff0c;并沒有放之四海而皆準的固定方法&#xff0c;但可以通過系統化的論證和設計原則來做出合理決策。以下是常見的…