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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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;但可以通过系统化的论证和设计原则来做出合理决策。以下是常见的…