Android电视项目焦点跨层级流转
1. 背景
在智家电视项目中,主要操作方式不是触摸,而是遥控器,通过Focus进行移动,确定点击进行的交互,所以在电视项目中焦点、选中、确定、返回这几个交互比较重要。由于电视屏比较大,在一些复杂页面中会存在一级Tab选择,二级选择,三级选择等,这就涉及到了焦点与选中的联动实现业务逻辑。这块的逻辑比较复杂,在做好了一个页面后,把这块的内容记录一下,同时提炼出了一个辅助类,MultiLevelFocusHelper,后续可进行复用。
2. 基本使用:遥控器+焦点控制
2.1 使用原则
Android原生就能比较好的支持Focus及切换,使用时只要按照它本身的逻辑使用就好,如果碰到不能很好支撑业务的时候再进行扩展,如下是我们小组实践过后,总结出来的几项原则,实际效果很好:
-
不进行过度控制,使用默认规则
-
使用focusable、descendantFocusability把XML中的控件按照父控件统一管控,如必须下放时再进行子控件控制
-
nextFocusUp、nextFocusDown、nextFocusLeft、nextFocusRight、nextFocusForward这几个属性不要轻易使用,只要在需要定制的复杂页面才有可能用到
2.2 View中涉及到焦点的几个属性
属性 | 使用场景说明 |
focusable | 物理按键时获得焦点的属性 android:focusable="false" android:focusable="true" |
descendantFocusability | 该属性是当一个view获取焦点时,定义viewGroup和其子控件两者之间的关系,属性的值有三种:
|
nextFocusUp nextFocusDown nextFocusLeft nextFocusRight | android:nextFocusUp-定义当点up键时,哪个控件将获得焦点 android:nextFocusDown-定义当点down键时,哪个控件将获得焦点 android:nextFocusLeft-定义当点left键时,哪个控件将获得焦点 android:nextFocusRight--定义当点right键时,哪个控件将获得焦点 |
nextFocusForward | 我是谁,我有什么用??? |
2.3 如何使用
1. XML中从顶到细,一层一层的看,如果此View及其子View不需要获得焦点,则直接把它的焦点屏蔽掉
android:focusable="false"
android:descendantFocusability="blocksDescendants"
2. 如果只有此ViewGroup需要获得焦点,它的子View不需要,则设置如下
android:focusable="true"
android:descendantFocusability="blocksDescendants"
3. RecyclerView或ListView,根据需要,如果是简单的能自动处理的则只修改XML即可,否则可以XML+代码进行控制
// 1. 第一种情况:recyclerView的 xml 设置 recyclerView 不获得焦点,子控件获得焦点
android:focusable="false"
android:descendantFocusability="afterDescendants"// recyclerView的item 布局中添加
android:focusable="true"
android:descendantFocusability="blocksDescendants"// 2. 第二种情况:代码控制时, recyclerView先获得焦点,然后根据需要,再在它的OnFocusChangeListener中进行焦点转移
android:focusable="true"
android:descendantFocusability="beforeDescendants"
4. 至此,如果没有特殊的需求,只是简单的焦点控制,通过XML配置属性+Android强大的默认功能即可完成
3. 高级用法:增加层级
3.1 层级是什么? 为什么要有三态?
如图,感兴趣的往下看,一切尽在图中,祭镇楼图
-
图中的设备列表与全屋节能信息构成了一级焦点,后边的节电数据范围是二级焦点,它俩是一个整体,这里暂且起名叫节能数据查看
-
其中全屋节能信息是一个ViewGroup,下边的设备列表是一个RecyclerView
-
图中的帮助按钮是另一个可欺获得焦点的控件,与上边的节能数据查看是并列关系
-
根据以上分析,得出:层级就是 完成同一个功能的多级多控件的可分别获得焦点的聚合体,特点如下:
-
焦点可在多级中的多个控件中自由流转,同时只有一个控件具备焦点
-
在同一级中,如果没有焦点,则需要有一个控件具备已选中状态,由此引出了三态:有焦点、无焦点选中、无焦点未选中
-
焦点在多级流转时有一定的规则,大部分情况下是从一级流向另一级时,优先流到已选中的控件上
-
多级具备方向性,比如1->2->3-4, 或 4->3->2->1, 在这个模型中,不可以跨级流转,如果后续有跨级流转的业务需求,再另说(产品经理不要搞太复杂呀...)
-
3.2 自定义的层级管理辅助类:MultiLevelFocusHelper
基于以上的层级焦点定义,我封装了一个辅助类,MultiLevelFocusHelper,可用于简化层级焦点的操作实现,它主要实现的功能有:
-
当某一层级的控件获得焦点时,通过它可记录最新的有焦点控件,并同时设置其中选中状态
-
设置当前层级有焦点的控件往下一级流转时的按键,并精准定位到下一级的选中控件上
-
获得所有层级的当前控件对应的附加数据
-
遵循了最小实现、不过渡设计的原则,当前只实现了两级,如果将来需要支持更多的级数,可扩展此类
代码如下:
class MultiLevelFocusHelper(private val totalLevel: Int) {private var mCurLevel1View: View? = nullprivate var mCurLevel1ViewId: Int? = nullprivate var mCurLevel1Data: Any? = nullprivate var mCurLevel2View: View? = nullprivate var mCurLevel2ViewId: Int? = nullprivate var mCurLevel2Data: Any? = null/*** 某一个控件得到了焦点* @param level: 得到焦点的控件的层级* @param view: 得到焦点的控件* @param viewId: 得到焦点的控件的Id,如果是recycleView,则设置它的父控件的Id,主要是为的是上下级Level切换* @param extraData: 得到焦点的控件对应的附属数据,暂存一下,后续业务需要时可直接get* @param nextLevelMoveDirect:*/fun receiveFocus(level: Int, view: View, viewId: Int, extraData: Any) {if (level > totalLevel) returnwhen(level) {1 -> {if (mCurLevel1View != null) {mCurLevel1View!!.isSelected = false}mCurLevel1View = viewmCurLevel1View!!.isSelected = truemCurLevel1ViewId = viewIdmCurLevel1Data = extraData}2 -> {if (mCurLevel2View != null) {mCurLevel2View!!.isSelected = false}mCurLevel2View = viewmCurLevel2View!!.isSelected = truemCurLevel2ViewId = viewIdmCurLevel2Data = extraData}else -> {// nothing}}}/*** 设置某一层级当前选中View的 nextFocusLeftId, nextFocusDownId 等* @param moveDirect, 移动方向,用于决定设置当前级Level的哪个属性 nextFocusLeftId 等。 传入值:使用本类中定义的四个常量值,多个方向时可进行&运算再传进来* @param moveCommander, 移动命令,是前进还是后退,用于确定要设置的Value是上一级还是下一步当前选中的View* 为 null,忽略,如果是头尾的,只有一个方向,直接设就行。 如果是中间的则忽略不进行设置了。*/fun setDirectToCurrentView(level: Int, moveDirect: Int, moveCommander: MoveCommander? = null) {if (level > totalLevel) returnwhen(level) {1 -> {// 第一层,只能往下移,不能回移setNextMoveTarget(mCurLevel1View, moveDirect, mCurLevel2ViewId)}2 -> {if (level < totalLevel) {if (moveCommander != null) {if (moveCommander == MoveCommander.forward) {// TODO, 当 totalLevel 大于等于 3 的时候,加上这一个分支, 它应该往 3 去移动了// setNextMoveTarget(mCurLevel2View, moveDirect, mCurLevel3ViewId)} else {setNextMoveTarget(mCurLevel2View, moveDirect, mCurLevel1ViewId)}}} else {// 这是最后一层, 只有一个方向setNextMoveTarget(mCurLevel2View, moveDirect, mCurLevel1ViewId)}}else -> {// nothing}}}/*** 所有控件失去焦点, 暂时应该没有场景调到它,如果有的话,需要考虑一下行为是否正确*/fun clearAllFocus() {if (mCurLevel1View != null) {mCurLevel1View!!.isSelected = false}mCurLevel1Data = nullif (mCurLevel2View != null) {mCurLevel2View!!.isSelected = false}mCurLevel2Data = null}/*** 获得某一层当前选中控件对应的 View*/fun getView(level: Int): View? {if (level > totalLevel) return nullreturn when(level) {1 -> {mCurLevel1View}2 -> {mCurLevel2View}else -> {null}}}/*** 获得某一层当前选中控件对应的数据*/fun getData(level: Int): Any? {if (level > totalLevel) return nullreturn when(level) {1 -> {mCurLevel1Data}2 -> {mCurLevel2Data}else -> {null}}}private fun setNextMoveTarget(view: View?, direct: Int?, nextViewId: Int?) {if (view == null || direct == null || nextViewId == null) {return}if (direct and Direct_Up > 0) {view.nextFocusUpId = nextViewId}if (direct and Direct_Right > 0) {view.nextFocusRightId = nextViewId}if (direct and Direct_Down > 0) {view.nextFocusDownId = nextViewIdview.nextFocusDownId}if (direct and Direct_Left > 0) {view.nextFocusLeftId = nextViewId}}
}
3.3 MultiLevelFocusHelper要点说明
-
构造函数中的参数 totalLevel
-
总级数,从1开始的, 比如totalLevel为3, 则所有级别即为1,2,3
-
目前 totalLevel 最大为 2,超过2 按 2 计算
-
-
对外函数receiveFocus(level: Int, view: View, viewId: Int, extraData: Any)
-
当层级中的某一个控件获得焦点时调用此函数
-
参数说明
-
@param level: 得到焦点的控件的层级
-
@param view: 得到焦点的控件
-
@param viewId: 得到焦点的控件的Id,如果是recycleView,则设置它的父控件的Id,主要是为的是上下级Level切换
-
@param extraData: 得到焦点的控件对应的附属数据,暂存一下,后续业务需要时可直接get
-
-
这里的 viewId 可以是 view 的Id,也可以不是, 基本用法是,如果是ListView或RecyclerView,则可以把viewId设置为 recyclerView 的Id,这样再在业务代码的 recyclerView 获得焦点事件中转一下即可
-
-
层级流转
-
level 移动顺序: 目前是一个约定,不能自定义。 1->2->3->4, 或 4->3->2->1。 如果后续有不同需求,可以再进行扩充
-
两个概念:MoveCommander, MoveDirect:
// 层级移动命令,向前进,还是后退,参考按照类说明了中的移动顺序 enum class MoveCommander {forward,back }// 焦点移动方向,比如按了遥控器上的上下左右, 使用Int值表示, 多个方向时可以进行&运算 val Direct_Up = 0x01 val Direct_Right = 0x02 val Direct_Down = 0x04 val Direct_Left = 0x08
-
对外函数:setDirectToCurrentView(level: Int, moveDirect: Int, moveCommander: MoveCommander? = null)
-
设置某一层级当前选中View的 nextFocusLeftId, nextFocusDownId 等,当某一个控件获得焦点后,再马上调用此函数设置一下
-
参数说明
-
moveDirect, 移动方向,用于决定设置当前级Level的哪个属性 nextFocusLeftId 等。 传入值:使用本类中定义的四个常量值,多个方向时可进行&运算再传进来
-
moveCommander, 移动命令,是前进还是后退,用于确定要设置的Value是上一级还是下一步当前选中的View为 null,忽略,如果是头尾的,只有一个方向,直接设就行。 如果是中间的则忽略不进行设置了
-
-
-
4. 使用实例
这里附上全屋节能的使用示例,它结合了 MultiLevelFocusHelper,并在Activity中实现了业务关联的一部分代码
4.1 相关控件的XML设置
-
设置所有没有焦点的控件中的属性, focusable 和 descendantFocusability
-
有焦点的控件属性设置上, focusable 和 descendantFocusability
-
recyclerView 设置为: android:focusable="true" android:descendantFocusability="beforeDescendants"
4.2 帮助按钮的Focus监听不必设置,使用系统默认的即可
4.3 初始化时,把默认的Focus给到 一级中的全屋信息
mMultiLevelFocusHelper.receiveFocus(1, mFullHouseSaveInfo, mFullHouseSaveInfo.id, "all") // 初始一化一下 mMultiLevelFocusChangeManager 中的状态
mMultiLevelFocusHelper.setDirectToCurrentView(1, MultiLevelFocusHelper.Direct_Right)
mMultiLevelFocusHelper.receiveFocus(2, mTextViewSaveElectricDurationLastMonth, mTextViewSaveElectricDurationLastMonth.id, ElectricIndexDateRange.LAST_MONTH)
mMultiLevelFocusHelper.setDirectToCurrentView(2, MultiLevelFocusHelper.Direct_Down)
mFullHouseSaveInfo.requestFocus()
4.4 RecyclerView 和 它的 item 设置 OnFocusChangeListener
mRecyclerViewDeviceDetailInfo.setOnFocusChangeListener(object : OnFocusChangeListener {override fun onFocusChange(v: View?, hasFocus: Boolean) {if (v == null) returnif (!hasFocus) returnval view = mMultiLevelFocusHelper.getView(1)val tag = view?.getTag() // 看它有没有存 tag 来判断它是不是 recyclerView 的 itemif (view == null || tag == null) {// 没有上一次的View 或 上一次的第一层View 不是 recyclerView的 item 时if (mRecyclerViewDeviceDetailInfo.getChildAt(0) != null) {mRecyclerViewDeviceDetailInfo.getChildAt(0).requestFocus()}} else {view.requestFocus()}}
})// 这里的最后一个参数 OnFocusChangeListener, 内部又传给了 item, 当它有 FocusChange事件时,再转调用此参数实例
mAdapterDeviceDetailInfo = SaveEnergyAdapterDeviceDetailInfo(mViewModal.getAllSavingDevice(),mViewModal.getAllSavingDeviceRank(),mViewModal.getAllSavingSwitchStatus(),object: OnFocusChangeListener {// 给 设备列表的 recycleview item 设置焦点移动回调override fun onFocusChange(v: View?, hasFocus: Boolean) {if (v == null) {return}if (!hasFocus) {return}val deviceId = v.getTag()mMultiLevelFocusHelper.receiveFocus(1, v, mRecyclerViewDeviceDetailInfo.id, deviceId)mMultiLevelFocusHelper.setDirectToCurrentView(1, MultiLevelFocusHelper.Direct_Right)initSavingElectricData()}})
这里啰嗦一下,RecyclerView拿到焦点时,把焦点转给它下边的之前具有焦点的控件;item中的view有一个tag,存的是业务数据(deviceId),当它拿到焦点时,取到此业务数据,传入到了 mMultiLevelFocusHelper 中
4.5 设置全屋信息 和 所有二级控件的 setOnFocusChangeListener,代码略
5. 总结
-
如果没有特殊的需求,只是简单的焦点控制,通过XML配置属性+Android强大的默认功能即可完成。
-
如果具有多个层级,焦点需要在多层级间进行流转并需要记忆功能,则可使用MultiLevelFocusHelper类,经过实践检验,可完美应用于此场景。
6. 团队介绍
「三翼鸟数字化技术平台-场景设计交互平台」主要负责设计工具的研发,包括营销设计工具、家电VR设计和展示、水电暖通前置设计能力,研发并沉淀素材库,构建家居家装素材库,集成户型库、全品类产品库、设计方案库、生产工艺模型,打造基于户型和风格的AI设计能力,快速生成算量和报价;同时研发了门店设计师中心和项目中心,包括设计师管理能力和项目经理管理能力。实现了场景全生命周期管理,同时为水,空气,厨房等产业提供商机管理工具,从而实现了以场景贯穿的B端C端全流程系统。
相关文章:
Android电视项目焦点跨层级流转
1. 背景 在智家电视项目中,主要操作方式不是触摸,而是遥控器,通过Focus进行移动,确定点击进行的交互,所以在电视项目中焦点、选中、确定、返回这几个交互比较重要。由于电视屏比较大,在一些复杂页面中会存…...
时频转换 | Matlab基于S变换S-transform一维数据转二维图像方法
目录 基本介绍程序设计参考资料获取方式基本介绍 时频转换 | Matlab基于S变换S-transform一维数据转二维图像方法 程序设计 clear clc % close all load x.mat % 导入数据 x =...
转载 为nautilus安装rabbitvcs
# 添加 rabbitvcs 的 ppa 源 sudo add-apt-repository ppa:rabbitvcs/ppa sudo apt update # 安装 rabbitvcs sudo apt install rabbitvcs-cli rabbitvcs-core rabbitvcs-gedit rabbitvcs-nautilus # 注销后重新登录,右键即可使用 # 解决 RabbitVCS 无法自动保存…...
OpenCV 模板匹配全解析:从单模板到多模板的实战指南
简介:本文深入探讨 OpenCV 中的模板匹配技术。详细介绍构建输入图像与模板图像的步骤,包括读取、截取、滤波与存储等操作。剖析 cv2.matchTemplate 语法及其参数含义,阐述不同匹配方法下结果值的意义。同时讲解 cv2.minMaxLoc 语法࿰…...
手机控制载货汽车一键启动无钥匙进入广泛应用
移动管家载货汽车一键启动无钥匙进入手机控车系统, 该系统广泛应用于物流运输、工程作业等货车场景,为车主提供了高效、便捷的启动和熄火解决方案,体现了科技进步对物流行业的积极影响 核心功能:简化启动流程,提…...
Springboot——SseEmitter流式输出
文章目录 前言SseEmitter 简介测试demo注意点异常一 ResponseBodyEmitter is already set complete 前言 最近做AI类的开发,看到各大AI模型的输出方式都是采取的一种EventStream的方式实现。 不是通常的等接口处理完成后,一次性返回。 而是片段式的处理…...
【人工智能数学基础篇】线性代数基础学习:深入解读矩阵及其运算
矩阵及其运算:人工智能入门数学基础的深入解读 引言 线性代数是人工智能(AI)和机器学习的数学基础,而矩阵作为其核心概念之一,承担着数据表示、变换和运算的重任。矩阵不仅在数据科学中广泛应用,更是神经…...
idea 自动导包,并且禁止自动导 *(java.io.*)
自动导包配置 进入 idea 设置,可以按下图所示寻找位置,也可以直接输入 auto import 快速定位到配置。 Add unambiguous imports on the fly:自动帮我们优化导入的包Optimize imports on the fly:自动去掉一些没有用到的包 禁止导…...
奇怪的编码2
1.当铺密码 当铺密码的标志是“田由中人工大王夫井羊” 口 0 田 0 由 1 中 2 人 3 工 4 大 5 王 6 夫 7 井 8 羊 9 解密脚本: s 田由中人工大王夫井羊 codeinput("请输入当铺密码:") code code.split(" ") w for i in code:k…...
AI服务器从HBM到CXL的技术变革
AI服务器从HBM到CXL变革 本文探讨了AI产业的新范式,特别是服务器变革。传统服务器价格通常在1万美金以内,而搭载8张H100算力卡的DGX H100AI服务器价值高达40万美金(约300万人民币)。这一变化将对AI产业产生深远影响。 自然语言和图形处理依赖大量存储器…...
将自定义 AWS S3 快照存储库连接到 Elastic Cloud
作者:来自 Elastic Annie Hansen, Stef Nestor 在本博客中,我们将介绍如何通过 Elasticsearch 的快照将我们已提交的集群数据备份到 AWS S3 存储桶中。在 Elastic Cloud(企业版)中,Elastic 在其 found-snapshots 存储…...
Java 多线程编程核心要点全解析:深度探秘关键方法与同步机制
1.Thread 类中的start() 和 run() 方法有什么区别? 在Java编程语言中,Thread 类的 start() 和 run() 方法有重要的区别: start() 方法: 当你调用 start() 方法时,它会启动一个新的线程,并且这个新线程会…...
个人博客接入github issue风格的评论,utteranc,gitment
在做个人博客的时候,如果你需要评论功能,但是又不想构建用户体系和评论模块,那么可以直接使用github的issue提供的接口,对应的开源项目有utteranc和gitment,尤其是前者。 它们的原理是一样的:在博客文章下…...
搞个项目之-esp32-cam ov2640模组搭建图像视频项目
开发版的介绍: 1、开发板使用的是:ESP32-CAM 2、摄像头模组:OV2640 3、烧录底座:ESP32-CAM开发板烧录座 4、mirco usb线,四线30cm 5、开发版的原理图像 项目前期的准备工作 一、安装arduino arduino官网地址地址…...
【FPGA开发】Vivado自定义封装IP核,绑定总线
支持单个文件的封装、整个工程的封装,这里用单个文件举例。 在文件工程目录下,自建一个文件夹,里面放上需要封装的verilog文件。 选择第三个,指定路径封装,找到文件所在目录 取个名,选择封装IP的路径 会…...
Leetcode51:N 皇后
题目描述: 按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回所有不同的 n 皇后问…...
C#面向对象之访问限制,类基础,继承
文章目录 1 访问限制1.1 简介 2 类基础讲解2.1 类定义2.2 构造函数2.2.1 构造函数2.2.2 静态构造函数2.2.3 初始化顺序2.2.4 对象初始化器 2.3 析构函数2.4 类的静态成员2.5 匿名对象2.5.1 定义2.5.2 匿名对象的创建 3 继承3.1 基类和派生类3.2 基类初始化3.3 Partial类3.3.1 定…...
科研小白成长记41——享受大起大落
一直内心对自己的定位是喜欢安安静静生活的人,但是朋友提醒我我的生活一直都是出于各种冒险之中,从GAP申博,到GAP找工作,都不是一个乐于安于现状的人会做出来的。仔细想想不无道理,既然如此,那就如享受安静…...
正则表达式笔记
一、基本正则 常见元字符 元字符说明^以某个字符开头$以某个字符结尾.匹配任意单字符*对前一项进行0次或者多次重复匹配{m,n}将前一项字符重复m-n次,{m,},{,n},{m,n}[]对方括号内的单字符进行匹配[^]不匹配方括号内的单字符^[]匹配以某个字符开头的行(…...
解决本地运行SuperPoint_SLAM报错ERROR: flag ‘flagfile‘ was defined more than once
解决本地运行SuperPoint_SLAM报错ERROR: flag flagfile was defined more than once 起因使用LD_DEBUG排查链接过程用ldd查看各自链接的库解决办法问题解决 起因 在之前本地编译了opencv-3.4.2,当时因为contrib模块需要gflags,重新下载了一个gflags在本…...
springboot信息化在线教学平台的设计与实现(代码+数据库+LW)
摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了信息化在线教学平台的开发全过程。通过分析信息化在线教学平台管理的不足,创建了一个计算机管理信息化在线教学平台的方案。文章介绍了信息化在线教…...
maxun爬虫工具docker搭建
思路来源开源无代码网络数据提取平台Maxun 先把代码克隆到本地(只有第一次需要) git clone https://github.com/getmaxun/maxun.git 转到maxun目录 cd maxun 启动容器 docker-compose --env-file .env up -d 成功启动六个容器 网址 http://local…...
高效 Python Web 开发:FastAPI 入门与实践
高效 Python Web 开发:FastAPI 入门与实践 目录 ✨ 1. 安装与环境配置 📦 安装 FastAPI 和 Uvicorn🗂️ 项目目录结构和初始化🚀 创建一个简单的 FastAPI 项目 🛠️ 2. FastAPI 路由与请求处理 🛣️ 基本…...
C++中的函数重载
函数重载是指在同一个作用域(通常是一个类或者一个命名空间)内,可以有多个同名函数,但是这些同名函数的参数列表(参数的个数、类型或者顺序)不同。当调用这个函数名时,编译器会根据传入的实际参…...
达梦数据库常用指令都是工作中常用的
达梦数据库连接配置文件名称 cd /etc/dm_svc.conf查询 sql 日志记录是否开启:0 关闭,1/2/3开启); select SF_GET_PARA_VALUE(1,SVR_LOG)union ALL select SF_GET_PARA_VALUE(2,SVR_LOG);关闭 sql 日志记录功能 call SP_SET_PARA_VALUE(1,SVR_LOG,0);开…...
【2024最新】基于Springboot+Vue的就业信息管理系统Lw+PPT
作者:计算机搬砖家 开发技术:SpringBoot、php、Python、小程序、SSM、Vue、MySQL、JSP、ElementUI等,“文末源码”。 专栏推荐:SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:Java精选实战项…...
linux一键部署apache脚本
分享一下自己制作的一键部署apache脚本: 脚本已和当前文章绑定,请移步下载(免费!免费!免费!) (单纯的分享!) 步骤: 将文件/内容上传到终端中 …...
修改MySQL数据库密码报1290
修改MySQL数据库密码报1290 错误 如下: alter user ‘root’‘localhost’ identified by ‘root’; ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement 需要刷新下配置 flush privileg…...
OpenCV4.8 开发实战系列专栏之 17 - 图像直方图
大家好,欢迎大家学习OpenCV4.8 开发实战专栏,长期更新,不断分享源码。 专栏代码全部基于C 与Python双语演示,领学习资料(Free) & 进专栏答疑群, VX: OpenCVXueTang_Asst 本文关键知识点:图…...
Linux下如何安装JDK
在Linux系统上安装JDK(Java Development Kit),通常包括下面步骤: 下载JDK安装包解压安装包配置环境变量等 在介绍安装之前,先厘清一些常用问题。 Linux 下Java 安装到哪个目录比较好? 在Linux系统下&am…...
实时数据开发|Flink如何实现不同数据源输入--DataSource模块
DataStream 编程模型 Flink定义DataStream API让用户灵活且高效的编写流式应用。主要分为3部分:DataSource模块,Transformation模块以及DataSink模块。 DataSource模块,主要定义了数据接入功能,将外部数据接入至flink࿰…...
使用Dify与BGE-M3搭建RAG(检索增强生成)应用-改进一,使用工作流代替Agnet
文章目录 前言Agent vs 工作流编写工作流 前言 在上一篇中,我们实现了一个基本的基于Dify的RAG的示范。 使用Dify与BGE-M3搭建RAG(检索增强生成)应用 这个效果确实很差。 我们一起来看看,该怎么改进。 今天我们就尝试一下&…...
GPT模型:改变世界的AI魔法师
目录 一、什么是GPT?它是怎么来的? 二、GPT能干啥?(它简直无所不能!) 三、想用GPT?这点开发技巧你一定要知道! 第一步:用OpenAI API搭建自己的GPT服务 第二步&#x…...
初识ProtoBuf以及环境搭建(Win和Ubuntu)
初始ProtoBuf 序列化和反序列化的概念 序列化:把对象转换为字节序列的过程 称为对象的序列化。 反序列化:把字节序列恢复为对象的过程 称为对象的反序列化。 什么情况下需要序列化和反序列化? 存储数据:当你想把的内存中的对象状…...
H3C OSPF实验
实验拓扑 实验需求 按照图示配置 IP 地址按照图示分区域配置 OSPF ,实现全网互通为了路由结构稳定,要求路由器使用环回口作为 Router-id,ABR 的环回口宣告进骨干区域 实验解法 一、配置IP地址 [R1]int l0 [R1-LoopBack0]ip add 1.1.1.1 32 […...
【Spark源码分析】基于Spark3.4.2源码分析SparkSQL执行过程
基于Spark3.4.2源码分析SparkSQL执行过程 文章目录 基于Spark3.4.2源码分析SparkSQL执行过程基本执行流程Unresolved逻辑计划树相关类RuleExector相关类 详细代码SparkSessionAbstractSqlParserDatasetQueryExecutionAnalyzerRuleExecutorCheckAnalysis 附录CTE简述SQL解析器Qu…...
centos8:Could not resolve host: mirrorlist.centos.org
【1】错误消息: [rootcentos211 redis-7.0.15]# yum update CentOS Stream 8 - AppStream …...
超详细ensp配置VRRP和MSTP协议
一、简介 1、什么是VRRP: (1)VRRP(Virtual Router Redundancy Protocol)的概念: VRRP(Virtual Router Redundancy Protocol)指的是一种实现路由器冗余备份的协议,常用于…...
聊聊Flink:这次把Flink的触发器(Trigger)、移除器(Evictor)讲透
一、触发器(Trigger) Trigger 决定了一个窗口(由 window assigner 定义)何时可以被 window function 处理。 每个 WindowAssigner 都有一个默认的 Trigger。 如果默认 trigger 无法满足你的需要,你可以在 trigger(…) 调用中指定自定义的 tr…...
为啥不推荐使用数据库外键
为啥不推荐使用数据库外键 前言 在阿里开发手册中写道:不得使用外键与级联,一切外键概念必须在应用层解决。 说明:(概念解释)学生表中的 student_id 是主键,那么成绩表中的 student_id 则为外键。如果更…...
C# 13 中的新增功能
C# 12 中的新增功能C# 11 中的新增功能C# 10 中的新增功能C# 9.0 中的新增功能C# 8.0 中的新增功能C#7.0中有哪些新特性?C#6.0中10大新特性的应用和总结C# 5.0五大新特性 将C#语言版本升级为预览版 C# 13 包括一些新增功能。 可以使用最新的 Visual Stu…...
sunshine+moonlight
参考自 b站视频 电脑端(发送端) 去 sunshine github 下载 https://github.com/LizardByte/Sunshine/releases/tag/v2024.1127.551下载后打开,创建用户名和密码修改配置选项,启用 UPnP,IP 地址族使用 IPv4IPv6 平板端…...
Python练习题合集
目录 一. 请编程输出其中 “超过平均身高” 的那些值。 二. 字典处理: 三. 求斐波那契数列的前若干项 四. 编程输出最长字符串的长度。 五. 去掉一个最高分,去掉一个最低分,其余分求平均作为最终分数。 六. 打印小九九乘法表 七.…...
frp 内网穿透
文章目录 前言使用自己的服务器搭建frp 这里服务器是linux centos 7 宝塔,client是 windows10 https://github.com/fatedier/frp/releases/tag/v0.53.2 版本下载分客户端与服务端 一、frp是什么?二、使用步骤1.部署服务器端2.客户端 前言 使用自己的服务…...
Vue3 子路由vue如何调用父路由vue中的方法?
1. router -> index.ts 文件: import { createRouter, createWebHistory } from vue-router import DefaultView from /views/default/index.vue import ParentView from /views/parent/index.vue import ChildView from /views/child/index.vueconst router …...
Docker 清理镜像策略详解
文章目录 前言一、删除 Docker 镜像1. 查看当前镜像2. 删除单个镜像3. 删除多个镜像4. 删除所有未使用的镜像5. 删除悬空的 Docker 镜像6. 根据模式删除镜像7. 删除所有镜像 二、删除 Docker 容器1. 查找容器2. 删除一个或多个特定容器3. 退出时删除容器4. 删除所有已退出的容器…...
Qt自定义 Qt Designer 插件
创建 Qt Designer 插件项目 Qt 提供两种设计插件的 API,可以用于扩展 Qt 的功能。高级 API 用于设计插件以扩展 Qt 的功能,例如定制数据库驱动、图像格式、文本编码、定制样式等。Qt Designer 里大量采用了插件,点击 Qt Creator 的“Help”-…...
【C语言】扫雷游戏(一)
我们先设计一个简单的9*9棋盘并有10个雷的扫雷游戏。 1,可以用数组存放,如果有雷就用1表示,没雷就用0表示。 2,排查(2,5)这个坐标时,我们访问周围的⼀圈8个位置黄色统计周围雷的个数是1。排查(8,6)这个坐标时…...
ESP32-S3模组上跑通ES8388(12)
接前一篇文章:ESP32-S3模组上跑通ES8388(11) 二、利用ESP-ADF操作ES8388 2. 详细解析 上一回解析了es8388_init函数中的第5段代码,本回继续往下解析。为了便于理解和回顾,再次贴出es8388_init函数源码,在…...
数据集-目标检测系列- 海边漫步锻炼人检测数据集 person >> DataBall
数据集-目标检测系列- 海边漫步锻炼人检测数据集 person >> DataBall DataBall 助力快速掌握数据集的信息和使用方式,会员享有 百种数据集,持续增加中。 需要更多数据资源和技术解决方案,知识星球: “DataBall - X 数据球…...