当前位置: 首页 > news >正文

Flutter富文本实现学习

Flutter 代码如何实现一个带有富文本显示和交互的页面。

前置知识点学习

RealRichText

`RealRichText` 和 `ImageSpan` 不是 Flutter 框架中内置的组件,而是自定义的组件或来自第三方库。这些组件的实现可以提供比标准 `RichText` 更丰富的功能,比如在富文本中插入图片、处理点击事件等。由于这些组件在标准 Flutter 中不存在,我将解释如何可能实现类似的功能。

TextSpan

`TextSpan` 是 Flutter 中用于构建富文本的基本组件之一。它允许你在同一个文本组件中混合和匹配不同的文本样式和手势识别功能。`TextSpan` 通常与 `RichText` 组件一起使用,以显示复杂的文本布局。

`TextSpan` 的基本结构

`TextSpan` 是一个不可变的、递归的数据结构,可以包含其他 `TextSpan`,从而允许嵌套不同的文本样式。

TextSpan({TextStyle? style,String? text,List<InlineSpan>? children,GestureRecognizer? recognizer,String? semanticsLabel,
})

关键属性

`style`:

  • 指定文本的样式,例如字体大小、颜色、粗细等。
  • 类型为 `TextStyle`。

`text`:

  • 要显示的文本字符串。
  • `text` 和 `children` 之间是互斥的,如果需要在一个 `TextSpan` 中显示多个文本片段,通常使用 `children`。

`children`:

  • 一个 `InlineSpan`(通常为 `TextSpan`)的列表,用于嵌套子文本。
  • 允许创建复杂的文本结构,如不同样式的文本段落。

`recognizer`:

  • 用于处理文本的手势识别,例如点击事件。
  • 通常使用 `TapGestureRecognizer` 来处理点击事件。

`semanticsLabel`:

  • 为文本提供一个可供屏幕阅读器使用的标签,帮助无障碍访问。

使用示例

下面是一个简单的例子,展示如何使用 `TextSpan` 来创建一个包含多种样式和交互的文本。

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';class RichTextExample extends StatelessWidget {const RichTextExample({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("Rich Text Example")),body: Center(child: RichText(text: TextSpan(text: 'Hello ',style: const TextStyle(color: Colors.black, fontSize: 18),children: <TextSpan>[const TextSpan(text: 'bold', style: TextStyle(fontWeight: FontWeight.bold)),const TextSpan(text: ' and ',),const TextSpan(text: 'italic',style: TextStyle(fontStyle: FontStyle.italic),),TextSpan(text: ' clickable ',style: const TextStyle(color: Colors.blue),recognizer: TapGestureRecognizer()..onTap = () {ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Clickable text clicked!')),);},),const TextSpan(text: 'text.',),],),),),);}
}

ImageSpan

`ImageSpan` 是一种在富文本中嵌入图片的技术。在 Flutter 中,虽然没有直接提供一个名为 `ImageSpan` 的组件,但你可以通过使用 `WidgetSpan` 来实现类似的功能。`WidgetSpan` 允许你在 `RichText` 中插入任意的 Flutter 小部件,包括图片。

使用 `WidgetSpan` 实现 `ImageSpan` 的功能

`WidgetSpan` 是 `InlineSpan` 的子类,可以在 `TextSpan` 列表中使用来嵌入小部件。通过这种方式,你可以在文本段落中插入图片或者其他小部件。

示例代码

import 'package:flutter/material.dart';class RichTextWithImageExample extends StatelessWidget {const RichTextWithImageExample({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("Rich Text with Image Example")),body: Center(child: RichText(text: TextSpan(style: const TextStyle(color: Colors.black, fontSize: 18),children: <InlineSpan>[const TextSpan(text: 'This is an example of '),WidgetSpan(child: Image.asset("static/demo.png",width: 24,height: 24,)),const TextSpan(text: ' in a rich text widget.'),]),),),);}
}

解释

`RichText` 和 `TextSpan`:

  • `RichText` 用于显示复杂的文本布局,`TextSpan` 用于定义文本的样式和内容。

`WidgetSpan`:

  • `WidgetSpan` 可以嵌入任何小部件。在这个例子中,它用于插入一个图片。
  • `child` 属性接受一个 `Widget`,这里使用 `Image.asset` 来加载本地图片。

图片资源:

  • 确保图片路径正确,并在 `pubspec.yaml` 中声明图片资源。
  • 例如:
flutter:assets:- assets/demo.png

 使用场景

  • 图文混排: 当需要在同一个文本段落中展示图片和文本,比如图标、表情符号或其他装饰性元素。
  • 动态内容: 在文章或聊天应用中以富文本形式展示内容,图片作为内嵌元素。
  • 自定义格式: 创建带有图片的复杂格式文本,比如新闻应用中的插图或注释。

通过 `WidgetSpan`,你可以在 Flutter 的文本组件中灵活地插入图片和其他小部件,实现更复杂的文本布局和丰富的用户界面体验。

TapGestureRecognizer

`TapGestureRecognizer` 是 Flutter 中用于检测点击手势的一个手势识别器。它通常用于处理文本中的点击事件,特别是在 `TextSpan` 中,使得文本中的某些部分可以响应用户的点击操作。

基本使用

`TapGestureRecognizer` 是 `GestureRecognizer` 的一个子类,它专门用于处理点击(tap)事件。通常情况下,它与 `RichText` 和 `TextSpan` 结合使用,以实现文本的可点击功能。

如何使用 `TapGestureRecognizer`

以下是一个简单示例,展示如何在 `TextSpan` 中使用 `TapGestureRecognizer`,使得文本的一部分可以被点击并响应事件:

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
class TapGestureExample extends StatelessWidget {const TapGestureExample({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("Tap Gesture Recognizer Example")),body: Center(child: RichText(text: TextSpan(text: 'Click ',style: const TextStyle(color: Colors.black, fontSize: 18),children: <TextSpan>[TextSpan(text: 'here',style: const TextStyle(color: Colors.blue, decoration: TextDecoration.underline),recognizer: TapGestureRecognizer()..onTap = () {ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Text clicked!')),);},),const TextSpan(text: ' to see the effect.',),],),),),);}
}

 解释

`RichText` 和 `TextSpan`:

  • `RichText` 用于显示富文本。通过 `TextSpan`,你可以定义不同的文本样式和内容。

`TapGestureRecognizer`:

  • 创建一个 `TapGestureRecognizer` 实例并将其分配给 `TextSpan` 的 `recognizer` 属性。
  • 使用 `..onTap`(级联操作符)来定义 `onTap` 回调函数,当用户点击该文本时调用。

响应点击:

  • 在 `onTap` 回调中使用 `ScaffoldMessenger` 显示一个 `SnackBar`,以反馈用户的点击操作。

注意事项

释放资源:

  • 如果在有状态的小部件中使用 `TapGestureRecognizer`,请确保在 `dispose` 方法中调用 `dispose` 方法来释放手势识别器,以避免内存泄漏。

多手势识别:

  • `TapGestureRecognizer` 可以与其他类型的手势识别器一起使用。使用 `GestureDetector` 可以创建更复杂的手势识别场景。

用户体验:

  • 确保可点击的文本有视觉上的提示,如颜色变化或下划线,以便用户能够清楚地识别哪些文本是可交互的。

通过 `TapGestureRecognizer`,你可以为文本添加交互功能,使得应用的用户界面更加动态和响应用户操作。

富文本代码实现学习

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:gsy_flutter_demo/widget/rich/real_rich_text.dart';class RichTextDemoPage extends StatefulWidget {const RichTextDemoPage({super.key});@override_RichTextDemoState createState() => _RichTextDemoState();
}class _RichTextDemoState extends State<RichTextDemoPage> {@overrideWidget build(BuildContext mainContext) {return Scaffold(appBar: AppBar(title: const Text("RichTextDemoPage"),),body: Container(margin: const EdgeInsets.all(10),child: Builder(builder: (context) {return Center(child: RealRichText([TextSpan(text: "A Text Link",style: const TextStyle(color: Colors.red, fontSize: 14),recognizer: TapGestureRecognizer()..onTap = () {show(context, "Link Clicked.");},),ImageSpan(const AssetImage("static/demo.png"),imageWidth: 24,imageHeight: 24,),ImageSpan(const AssetImage("static/demo.png"),imageWidth: 24,imageHeight: 24,margin: const EdgeInsets.symmetric(horizontal: 10)),const TextSpan(text: "哈哈哈",style: TextStyle(color: Colors.yellow, fontSize: 14),),TextSpan(text: "@Somebody",style: const TextStyle(color: Colors.black,fontSize: 14,fontWeight: FontWeight.bold),recognizer: TapGestureRecognizer()..onTap = () {show(context, "Link Clicked.");},),TextSpan(text: " #RealRichText# ",style: const TextStyle(color: Colors.blue, fontSize: 14),recognizer: TapGestureRecognizer()..onTap = () {show(context, "Link Clicked.");},),const TextSpan(text: "showing a bigger image",style: TextStyle(color: Colors.black, fontSize: 14),),ImageSpan(const AssetImage("static/demo.png"),imageWidth: 24,imageHeight: 24,margin: const EdgeInsets.symmetric(horizontal: 5)),const TextSpan(text: "and seems working perfect……",style: TextStyle(color: Colors.black, fontSize: 14),),]),);}),),);}show(context, text) {ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(text),action: SnackBarAction(label: 'ACTION',onPressed: () {ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('You pressed snackbar\'s action.'),));},),));}
}

三方flutter库中的富文本实现源码

import 'dart:ui' as ui show Image;import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';/// According to the related Flutter Issues(#2022) ,
/// Inline-Image-In-Text is a long-time(2 years) missing feature since RichText(or the underlying Paragraph) does only support pure text.
/// But we can solve this problem in a simple/tricky way:
///
/// 1. Regarde the images as a particular blank TextSpan,
///   convert image's width and height to textspan's letterSpacing and fontSize.
///   the origin paragraph will do the layout operation and leave the desired image space for us.
/// 2. Override the paint function,
///   calculate the right offset via the getOffsetForCaret() api to draw the image over the space.
///
/// The only thing you have to do is converting your origin text to a TextSpan/ImageSpan List first.
///
/// {@tool sample}
///
/// ```dart
/// RealRichText([
///            TextSpan(
///              text: "showing a bigger image",
///              style: TextStyle(color: Colors.black, fontSize: 14),
///            ),
///            ImageSpan(
///              AssetImage("packages/real_rich_text/images/emoji_10.png"),
///              width: 40,
///              height: 40,
///            ),
///            TextSpan(
///              text: "and seems working perfect……",
///              style: TextStyle(color: Colors.black, fontSize: 14),
///            ),
///          ])
/// ```
/// {@end-tool}
///
class RealRichText extends Text {final List<TextSpan> textSpanList;const RealRichText(this.textSpanList, {super.key,TextStyle? style,TextAlign textAlign = TextAlign.start,TextDirection? textDirection,bool softWrap = true,TextOverflow overflow = TextOverflow.clip,TextScaler? textScaler,int? maxLines,Locale? locale,}) : super("",style: style,textAlign: textAlign,textDirection: textDirection,softWrap: softWrap,overflow: overflow,textScaler: textScaler,maxLines: maxLines,locale: locale);List<TextSpan> extractAllNestedChildren(TextSpan textSpan) {if (textSpan.children == null || textSpan.children!.isEmpty) {return [textSpan];}List<TextSpan> childrenSpan = [];for (var child in textSpan.children!) {childrenSpan.addAll(extractAllNestedChildren(child as TextSpan));}return childrenSpan;}@overrideWidget build(BuildContext context) {final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context);TextStyle? effectiveTextStyle = style;if (style == null || style!.inherit) {effectiveTextStyle = defaultTextStyle.style.merge(style);}if (MediaQuery.boldTextOf(context)) {effectiveTextStyle =effectiveTextStyle!.merge(const TextStyle(fontWeight: FontWeight.bold));}TextSpan textSpan = TextSpan(style: effectiveTextStyle,text: "",children: extractAllNestedChildren(TextSpan(style: effectiveTextStyle,text: "",children: textSpanList,)));// pass the context to ImageSpan to create a ImageConfigurationfor (var f in textSpan.children!) {if (f is ImageSpan) {f.updateImageConfiguration(context);}}Widget result = _RichTextWrapper(textAlign: textAlign ?? defaultTextStyle.textAlign ?? TextAlign.start,textDirection: textDirection,// RichText uses Directionality.of to obtain a default if this is null.locale: locale,// RichText uses Localizations.localeOf to obtain a default if this is nullsoftWrap: softWrap ?? defaultTextStyle.softWrap,overflow: overflow ?? defaultTextStyle.overflow,textScaler: textScaler ?? MediaQuery.textScalerOf(context),maxLines: maxLines ?? defaultTextStyle.maxLines,text: textSpan);if (semanticsLabel != null) {result = Semantics(textDirection: textDirection,label: semanticsLabel,child: ExcludeSemantics(child: result,));}return result;}
}/// Since flutter engine does not support inline-image for now, we have to support this feature via a tricky solution:
/// convert image to a particular TextSpan whose text always be \u200B(a zero-width-space).
/// set letterSpacing by the required image width
/// set fontSize by the required image height
class ImageSpan extends TextSpan {final double imageWidth;final double imageHeight;final EdgeInsets? margin;final ImageProvider imageProvider;final ImageResolver imageResolver;ImageSpan(this.imageProvider, {this.imageWidth = 14.0,this.imageHeight = 14.0,this.margin,super.recognizer,})  : imageResolver = ImageResolver(imageProvider),super(style: TextStyle(color: Colors.transparent,letterSpacing:imageWidth + (margin == null ? 0 : margin.horizontal),height: 1,fontSize: (imageHeight / 1.15) +(margin == null ? 0 : margin.vertical)),text: "\u200B",children: []);void updateImageConfiguration(BuildContext context) {imageResolver.updateImageConfiguration(context, imageWidth, imageHeight);}double get width => imageWidth + (margin == null ? 0 : margin!.horizontal);double get height => imageHeight + (margin == null ? 0 : margin!.vertical);
}typedef ImageResolverListener = void Function(ImageInfo imageInfo, bool synchronousCall);class ImageResolver {final ImageProvider imageProvider;ImageStream? _imageStream;ImageConfiguration? _imageConfiguration;ui.Image? image;ImageResolverListener? _listener;ImageResolver(this.imageProvider);/// set the ImageConfiguration from outsidevoid updateImageConfiguration(BuildContext context, double width, double height) {_imageConfiguration = createLocalImageConfiguration(context,size: Size(width, height),);}ImageStreamListener? imageStreamListener;void resolve(ImageResolverListener listener) {assert(_imageConfiguration != null);final ImageStream? oldImageStream = _imageStream;_imageStream = imageProvider.resolve(_imageConfiguration!);assert(_imageStream != null);_listener = listener;if (_imageStream!.key != oldImageStream?.key) {if (imageStreamListener != null) {oldImageStream?.removeListener(imageStreamListener!);}imageStreamListener ??= ImageStreamListener(_handleImageChanged);_imageStream!.addListener(imageStreamListener!);}}void _handleImageChanged(ImageInfo imageInfo, bool synchronousCall) {image = imageInfo.image;_listener?.call(imageInfo, synchronousCall);}void addListening() {if (_listener != null) {imageStreamListener ??= ImageStreamListener(_handleImageChanged);_imageStream?.addListener(imageStreamListener!);}}void stopListening() {if (imageStreamListener != null) {_imageStream?.removeListener(imageStreamListener!);}}
}/// Just a subclass of RichText for overriding createRenderObject
/// to return a [_RealRichRenderParagraph] object
///
/// No more special purpose.
class _RichTextWrapper extends RichText {_RichTextWrapper({required TextSpan super.text,super.textAlign,super.textDirection,super.softWrap,super.overflow,super.textScaler,super.maxLines,super.locale,})  : assert(maxLines == null || maxLines > 0);@overrideRenderParagraph createRenderObject(BuildContext context) {assert(textDirection != null || debugCheckHasDirectionality(context));return _RealRichRenderParagraph(text as TextSpan,textAlign: textAlign,textDirection: textDirection ?? Directionality.of(context),softWrap: softWrap,overflow: overflow,textScaler: textScaler,maxLines: maxLines,locale: locale ?? Localizations.localeOf(context),);}
}/// paint the image on the top of those ImageSpan's blank space
class _RealRichRenderParagraph extends RenderParagraph {_RealRichRenderParagraph(TextSpan super.text,{required super.textAlign,required super.textDirection,required super.softWrap,required super.overflow,required super.textScaler,super.maxLines,super.locale});@overridevoid paint(PaintingContext context, Offset offset) {super.paint(context, offset);// Here it is!paintImageSpan(context, offset);}@overridevoid attach(covariant Object owner) {super.attach(owner as PipelineOwner);for (var textSpan in (text as TextSpan).children!) {if (textSpan is ImageSpan) {textSpan.imageResolver.addListening();}}}@overridevoid detach() {super.detach();for (var textSpan in (text as TextSpan).children!) {if (textSpan is ImageSpan) {textSpan.imageResolver.stopListening();}}}@overridevoid performLayout() {super.performLayout();debugPrint("size = $size");}/// this method draws inline-image over blank text space.void paintImageSpan(PaintingContext context, Offset offset) {final Canvas canvas = context.canvas;final Rect bounds = offset & size;debugPrint("_RealRichRenderParagraph offset=$offset bounds=$bounds");canvas.save();int textOffset = 0;for (TextSpan textSpanin (text as TextSpan).children as Iterable<TextSpan>) {if (textSpan is ImageSpan) {// this is the top-center point of the ImageSpanOffset offsetForCaret = getOffsetForCaret(TextPosition(offset: textOffset),bounds,);// found this is a overflowed image. ignore itif (textOffset != 0 &&offsetForCaret.dx == 0 &&offsetForCaret.dy == 0) {return;}// this is the top-left point of the ImageSpan.// Usually, offsetForCaret indicates the top-center offset// except the first text which is always (0, 0)Offset topLeftOffset = Offset(offset.dx +offsetForCaret.dx -(textOffset == 0 ? 0 : textSpan.width / 2),offset.dy + offsetForCaret.dy);debugPrint("_RealRichRenderParagraph ImageSpan, textOffset = $textOffset, offsetForCaret=$offsetForCaret, topLeftOffset=$topLeftOffset");// if image is not ready: wait for async ImageInfoif (textSpan.imageResolver.image == null) {textSpan.imageResolver.resolve((imageInfo, synchronousCall) {if (synchronousCall) {paintImage(canvas: canvas,rect: topLeftOffset & Size(textSpan.width, textSpan.height),image: textSpan.imageResolver.image!,fit: BoxFit.scaleDown,alignment: Alignment.center);} else {if (owner == null || !owner!.debugDoingPaint) {markNeedsPaint();}}});textOffset += textSpan.toPlainText().length;continue;}// else: just paint it. bottomCenter Alignment seems better...paintImage(canvas: canvas,rect: topLeftOffset & Size(textSpan.width, textSpan.height),image: textSpan.imageResolver.image!,fit: BoxFit.scaleDown,alignment: Alignment.center);}textOffset += textSpan.toPlainText().length;}canvas.restore();}
}

相关文章:

Flutter富文本实现学习

Flutter 代码如何实现一个带有富文本显示和交互的页面。 前置知识点学习 RealRichText RealRichText 和 ImageSpan 不是 Flutter 框架中内置的组件&#xff0c;而是自定义的组件或来自第三方库。这些组件的实现可以提供比标准 RichText 更丰富的功能&#xff0c;比如在富文本…...

如何解决 OpenAI API 连接问题:降级 urllib3 版本

如何解决 OpenAI API 连接问题&#xff1a;降级 urllib3 版本 在使用 OpenAI API 时&#xff0c;很多开发者可能会遇到连接问题&#xff0c;特别是在使用 Python 代码与 OpenAI 进行交互时。常见的错误包括 ProxyError、SSLError 和 MaxRetryError&#xff0c;它们通常表示在通…...

【C语言】库函数常见的陷阱与缺陷(三):内存分配函数[4]--free

C语言中的free函数用于释放之前通过malloc、calloc或realloc动态分配的内存。然而,在使用free函数时,开发者可能会遇到一些陷阱和缺陷。 一、功能与用法 free 函数是 C 语言中用于释放动态分配内存的关键函数。在程序使用 malloc、calloc 或 realloc 等函数在堆上分配了内存…...

论文分享 | PromptFuzz:用于模糊测试驱动程序生成的提示模糊测试

大语言模型拥有的强大能力可以用来辅助多种工作&#xff0c;但如何有效的辅助仍然需要人的精巧设计。分享一篇发表于2024年CCS会议的论文PromptFuzz&#xff0c;它利用模型提示生成模糊测试驱动代码&#xff0c;并将代码片段嵌入到LLVM框架中执行模糊测试。 论文摘要 制作高质…...

AWS K8s 部署架构

Amazon Web Services&#xff08;AWS&#xff09;提供了一种简化的Kubernetes&#xff08;K8s&#xff09;部署架构&#xff0c;使得在云环境中管理和扩展容器化应用变得更加容易。这个架构的核心是AWS EKS&#xff08;Elastic Kubernetes Service&#xff09;&#xff0c;它是…...

JavaSE笔记(四)

Java泛型与集合类 在前面我们学习了最重要的类和对象,了解了面向对象编程的思想,注意,非常重要,面向对象是必须要深入理解和掌握的内容,不能草草结束。在本章节,我们会继续深入了解,从我们的泛型开始,再到我们的数据结构,最后再开始我们的集合类学习。 走进泛型 为…...

C语言基础——指针(5)

一&#xff0e; 函数指针变量 1. 函数指针变量的定义&#xff1a; 类比数组指针变量&#xff0c;数组指针变量是存放数组地址的变量&#xff0c;那么同理&#xff0c;函数指针变量就是存放函数地址的变量。 2. 创建函数指针变量&#xff1a; 函数是有地址的&#xff0…...

curl+openssl 踩坑笔记

curl编译&#xff1a;点击跳转 踩坑一 * SSL certificate problem: unable to get local issuer certificate * closing connection #0 curl: (60) SSL certificate problem: unable to get local issuer certificate More details here: https://curl.se/docs/sslcerts.html …...

Unity 实现Canvas显示3D物体

新建一个UI相机&#xff0c;选择渲染层为UI 将主相机的渲染层去掉UI层 、 将Canvas的RenderMode设置为Screen Space - Camera,将RenderCamera设置为UI相机 新建3D物体的UI父物体&#xff0c;并将3D物体的层级设置为UI层 适当的放缩3DObjParent&#xff0c;让3D物体能显示出来…...

【Docker命令】如何使用`docker exec`在容器内执行命令

大家好&#xff0c;今天我们来聊聊Docker容器管理中的一个非常有用的命令&#xff1a;docker exec。在日常工作中&#xff0c;我们经常需要在运行中的Docker容器内执行各种命令&#xff0c;docker exec正是帮助我们实现这一需求的利器。下面我将通过一个简单的例子&#xff0c;…...

NetSuite Formula(HTML)超链打开Transaction

当Saved Search作为Sublist应用在Form时&#xff0c;如果Document Number是Group过的&#xff0c;则会出现如下超链失效的情况。 解决办法&#xff1a; 可以利用Saved Search中的Formula&#xff08;HTML&#xff09;功能来构建超链&#xff0c;用于打开Transaction。 以下图…...

【React】- 跨域PDF预览、下载(改文件名)、打印

我们经常会碰到跨域来方位PDF&#xff0c;同时需要下载、打印的需求&#xff0c;通常由于浏览器的安全策略&#xff0c;可以预览&#xff0c;但是下载和打印可能会受限&#xff0c;这时候怎么办呢&#xff1f; 1.创建一个隐藏的标签 要下载 iframe 中的 PDF 文件&#xff0c;…...

git clone ssh 设置代理

Linux配置方法 编辑 ~/.ssh/config 文件 Host github.com Hostname github.com ProxyCommand nc -v -x 127.0.0.1:1080 %h %pwindows配置方法 编辑 C:\Users\当前用户名.ssh\config 文件 Host github.com Hostname github.com ProxyCommand connect -S 127.0.0.1:1080 %h %…...

RK3568平台(USB篇)USB网络共享

使用RK的USB网络共享,在内核里面已经有了,这不需要自己写驱动程序,只需要把内核自带的USB网络共享的驱动添加上去即可。 一.RNDIS 协议简介 RNDIS 是微软定义的一种协议,它允许通过 USB 接口实现网络连接。通过 RNDIS,USB 设备可以充当网络适配器,允许主机通过 USB 与设…...

vite 打包时:JavaScript heap out of memory(内存溢出)

出错原因分析&#xff1a; 执行命令 npm run build 时出现以下错误提示&#xff1a; vite v3.2.7 building for production... 11:22:34 transforming (3) src\main.tsWARN Browserslist: caniuse…...

【服务器学习专栏 1.2 -- 带外管理】

请阅读 嵌入式学习必备专栏 文章目录 Overview服务器带外管理BMC 介绍BMC 特点BMC 工作原理 Overview 从技术的角度&#xff0c;网络管理可分为带外管理&#xff08;out-of-band&#xff09;和带内管理&#xff08;in-band&#xff09;两种管理模式。 带内管理&#xff0c;是指…...

微服务のGeteWay

目录 概念&#xff1a; 三大核心&#xff1a; 工作流程&#xff1a; 9527网关如何做路由映射&#xff1a; GetWay高级特性&#xff1a; 按服务名动态路由服务&#xff1a; 断言Route Predicate Factories &#xff1a; 获取当前时区时间&#xff1a; After Route &…...

html+css+js网页设计 美食 美食家6个页面

htmlcssjs网页设计 美食 美食家6个页面 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&#xf…...

IntelliJ Idea常用快捷键详解

文章目录 IntelliJ Idea常用快捷键详解一、引言二、文本编辑与导航1、文本编辑2、代码折叠与展开 三、运行和调试四、代码编辑1、代码补全 五、重构与优化1、重构 六、使用示例代码注释示例代码补全示例 七、总结 IntelliJ Idea常用快捷键详解 一、引言 在Java开发中&#xff…...

服务器虚拟化:它是什么以及有什么好处?

运行虚拟服务器有助于创建更高效的 IT 基础架构。 随着业务每天收集的数据量逐年激增&#xff0c;传统的物理服务器已经无法单独满足业务需求。 相反&#xff0c;许多组织正在转向虚拟化的力量。 这是我们创建物理实体的虚拟版本的过程&#xff0c;在计算中&#xff0c;通常指…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...