《Flutter UI》

xuanxuan 2026-08-04 22:10 1



[!tip]-前言

本人近期在自学flutter,文章纯手敲,自己有Obsidian整理,内容太多先更新一部分,后续会继续更新。

接受各位佬批评,可自行修改错误或补充。

鼓励佬友共建,每次可赏10 ldc。

本文章如有问题,请联系我。



Flutter UI


​Flutter widget 采用受React启发的现代框架构建。核心思想是用 widget 构建 UI。 Widget 根据当前配置和状态描述其视图应有的外观。当 widget 的状态改变时,widget 会重建其描述,框架将其与先前的描述进行 diff,以确定底层渲染树从一种状态过渡到另一种状态所需的最小变更。



[!info] Flutter官方文档



1. Flutter


1.1 Flutter 是什么


Flutter 是 Google 开发的开源 UI 框架,使用 Dart 语言编写。它的核心设计理念是一切皆 Widget。不同于其他跨平台框架依赖原生组件渲染,Flutter 自带高性能的渲染引擎 Skia(Impeller 在 iOS 上替代 Skia),直接在屏幕上绘制像素,从而实现真正的跨平台一致性。


Flutter 的目标平台覆盖极广:iOS、Android、Web、Windows、macOS、Linux。一套代码可以在六个平台上运行,这是它最吸引人的地方。


1.2 三层架构




























层级 组成 职责
Framework Dart 编写的 Widget 层、渲染层、动画层、手势层 开发者直接交互的 API 层
Engine C/C++ 编写的 Skia/Impeller、Dart VM、文本渲染 负责渲染、线程管理、平台通信
Embedder 平台特定的代码(Java/Kotlin、Swift/Objective-C、C++) 将 Engine 嵌入到各个操作系统中

1.3 热重载与热重启


​ Flutter 的开发体验很大程度上归功于热重载(Hot Reload)。它借助 Dart 的 JIT 编译器,在代码修改后毫秒级地将变更注入到运行中的应用,同时保持应用状态。


# 在终端中按 r 执行热重载(保留状态)
# 按 R 执行热重启(重新初始化状态)
# 按 q 退出


热重载的局限


热重载不会重新执行 main()initState()。如果你修改了全局变量初始化、枚举定义、类的静态字段,或者遇到编译错误,热重载会失败,需要使用热重启。



1.4 项目结构


my_app/
├── android/ # Android 原生工程
├── ios/ # iOS 原生工程
├── lib/ # Dart 代码(核心开发目录)
│ └── main.dart # 应用入口
├── test/ # 单元测试和 Widget 测试
├── pubspec.yaml # 依赖管理和资源配置
└── assets/ # 图片、字体等资源

1.5 pubspec.yaml 详解


name: demo
description: "A new Flutter project."
publish_to: 'none'
version: 0.1.0+1

environment:
sdk: ^3.12.2

dependencies:
flutter:
sdk: flutter

dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^6.0.0

flutter:
uses-material-design: true

2. Widget 基础


2.1 Widget 了解


在 Flutter 中,Widget 是构建 UI 的基本单位。按钮是 Widget,布局是 Widget,手势是 Widget,甚至是应用本身也是 Widget。Widget 描述的是 UI 的配置信息(即"长什么样"),而不是可变的 UI 实例。


Widget 的核心特点:



  • 不可变(immutable):Widget 的字段都是 final

  • 轻量级:Widget 本身不直接绘制,只是配置描述

  • 可嵌套:通过组合多个 Widget 构建复杂 UI


2.1.1 启动


void main() {
runApp(const MainApp());
}

runApp() 函数接收给定的 Widget 并将其设为 widget 树的根。


2.1.2 Material 组件


​ Flutter 提供多种 widget,帮助你构建符合 Material Design 的应用。 Material 应用以MaterialApp widget 开头,它在应用根节点构建多种实用 widget,包括Navigator——管理以字符串标识的 widget 栈,即「路由」。


class MainApp extends StatelessWidget {
const MainApp({super.key});

@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: Center(
child: Text('Hello World!'),
),
),
);
}
}

MainApp根 widget,因为它是传入 runApp 的 widget。在这个 widget 内部,有一个 build 方法,它返回名为 MaterialApp 的另一个 widget。


MaterialApp



  • title:用来展示窗口标题内容。

  • theme:用来展示整个应用的主题。

  • home:用来展示窗口的主题。


@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'My First App',
theme: ThemeData(scaffoldBackgroundColor: Colors.deepPurple),
home: Scaffold(
body: Text("hello world"),
),
);

2.1.2 Scaffold 组件


Scaffold 提供标准、灵活配置的页面骨架。




































属性 作用
appBar 页面顶部的应用栏,常用于显示标题、导航按钮和操作菜单
body 页面主题内容,可以放置任何其他组件
bottomNavigationBar 底部导航栏,方便用户在不同核心页面切换
backgroundColor 设置整个Scaffold 的背景色
flotingActionButtom 悬浮操作按钮,常用于触发页面主要动作
其他

      home: Scaffold(
appBar: AppBar(
title: Text('appbar'),
centerTitle: true,
),
body: Text("body"),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Search',
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
},
child: Icon(Icons.add),
),
),

2.1.3 两种核心 Widget 类型




























组件名称 类型 描述
StatelessWidget 无状态组件 StatelessWidget 一旦构建完成内部内容就不会再改变。它适用于纯展示型 UI,如文本、图标、静态图片等。
StatefulWidget 有状态组件 StatefulWidget 由两部分组成:Widget 本身(不可变)和 State(可变)。当状态变化时,调用 setState() 触发重建。
(1)StatelessWidget 生命周期


  • StatelessWidget 非常简单:构造函数 → build()。没有额外的生命周期回调。

  • 当组件被创建或父组件状态变化导致需要重新构建时,build()会被调用。


class MainApp extends StatelessWidget {
const MainApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Text('Hello World!'),
),
),
);
}
}


总是使用 const 构造函数


StatelessWidget 的所有字段都是编译期常量时,使用 const 构造函数可以让 Flutter 在重建时复用同一个 Widget 实例,大幅提升性能。Flutter 官方推荐==尽可能使用 const==。



(2)StatefulWidget 生命周期
























































生命周期阶段 函数 描述 使用场景
创建阶段 createState() widget初始化调用,创建state对象
创建阶段 initState() state对象插入widget树立刻执行,仅执行一次 订阅流、初始化动画控制器、获取初始数据
创建阶段 didChangeDependencies()
initState()后立刻执行,当所依赖的InheritedsWidget更新时调用,可能多次 主题、本地化
构建阶段 build() 构建UI,初始化或更新后多次调用
更新阶段 didUpdateWidget()
父组件传入新配置时调用,用于比较新旧配置 父 Widget 重建时,传入新配置
销毁阶段 deactivate()
当state对象从widget树暂时移除时调用
销毁阶段 dispose() 当state对象从widget树永久移除时调用,释放资源,仅执行一次 取消订阅、释放动画控制器、关闭资源

// 第一个类继承StatefulWidget,主要接受和定义最终参数,核心作用创建State对象
class Counter extends StatefulWidget {
const Counter({super.key});

@override
State<Counter> createState() => _CounterState();
}

// 第二个类继承State<第一个类类名>,负责管理可变数据和业务逻辑,并实现build方法来渲染视图。
class _CounterState extends State<Counter> {
int _count = 0;

void _increment() {
setState(() {
_count++;
});
}

@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: _increment,
child: Text('Count: $_count'),
);
}
}

生命周期函数


补充

2.2 布局组件


Flutter 布局的核心机制是 widget。在 Flutter 中,几乎所有东西都是 widget — 甚至布局模型都是 widget。


所有布局 widget 都具有以下任一项:



  • 一个 child 属性,如果它们只包含一个子项 — 例如 CenterContainer

  • 一个 children 属性,如果它们包含多个子项 — 例如 RowColumnListViewStack


2.2.1 布局组件


Container



  • 组合容器,整合尺寸(width/height)、装饰(decoration/color)、边距(padding/margin)、对齐(alignment)、变换(transform);




  • decoration属性:装饰器,可实现复杂背景效果,不能与color同时使用;




  • SizeBox区别:SizeBox只能设置尺寸,无其他属性。

    特性:




  • 不设宽高时,会尽可能占满父空间;




  • padding 内部留白,margin 外部留白;




  • child 才会渲染内部内容。




        body: Center(
child: Container(
width: 200, // 宽
height: 100, // 高
padding: EdgeInsets.all(10), // 内边距
margin: EdgeInsets.symmetric(vertical: 20), // 外边距
decoration: BoxDecoration(
// 背景装饰
color: Colors.blue,
borderRadius: BorderRadius.circular(8),
boxShadow: [BoxShadow(color: Colors.grey, blurRadius: 4)],
),
alignment: Alignment.center, // 内部子控件对齐
transform: Matrix4.rotationZ(0.1), // 旋转/平移
child: Text("Container"),
),
),

Center


  • 将子组件在父容器空间内水平居中和垂直居中;

  • Center = Align(alignment: Alignment.center),简化版居中;

  • 不能设置宽高,会尽可能占满父空间;


 body: Center(
child: Container(
width: 200,
height: 200,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(8),
boxShadow: [BoxShadow(color: Colors.grey, blurRadius: 4)],
),
alignment: Alignment.center,
child: Text("center"),
),
),

Align


  • 精确控制子控件在父容器内的位置,可设置宽高因子。


body: Container(
width: 300,
height: 200,
color: Colors.grey,
child: Align(
alignment: Alignment.bottomRight, // 右下角
widthFactor: 0.5, // 自身宽度=父宽度*0.5
heightFactor: 0.5, // 自身高度=父高度*0.5
child: Text("右下角文字"),
),
),

Padding


  • 控制子控件的内边距


body: Container(
color: Colors.amber,
child: Padding(
padding: EdgeInsets.all(20),
child: Container(
color: Colors.blue,
),
),
),

Column & Row

Column



  • 线性布局,垂直排列子控件




























属性 描述

mainAxisAlignment
控制子控件在主轴(垂直方向)的排列方式,顶部对齐、居中。均匀分布
crossAxisAlignment 控制子控件在交叉轴(水平方向)的排列方式,左/右对齐、拉伸填满
mainAxisSize 决定Column在垂直方向上的尺寸策略。沾满所有空间(max),仅仅包裹子控件内容(min)
children 垂直排列子控件列表

body: Container(
width: double.infinity,
height: double.infinity,
color: Colors.amber,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Container(
color: Colors.blue,
width: 200,
height: 200,
alignment: Alignment.center,
child: Text('111'),
),
Container(
width: 200,
height: 200,
alignment: Alignment.center,
color: Colors.green,
child: Text('222'),
),
],
),
),

Row



  • 线性布局,水平排列子控件




























属性 描述

mainAxisAlignment
控制子控件在主轴(水平方向)的排列方式,顶部对齐、居中。均匀分布
crossAxisAlignment 控制子控件在交叉轴(垂直方向)的排列方式,左/右对齐、拉伸填满
mainAxisSize 决定Row在水平方向上的尺寸策略。沾满所有空间(max),仅仅包裹子控件内容(min)
children 垂直排列子控件列表

body: Container(
width: double.infinity,
height: double.infinity,
color: Colors.amber,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Container(
color: Colors.blue,
width: 200,
height: 200,
alignment: Alignment.center,
child: Text('111'),
),
Container(
width: 200,
height: 200,
alignment: Alignment.center,
color: Colors.green,
child: Text('222'),
),
],
),
),

Flex & Expended

Flex



  • 弹性布局,允许沿着一个主轴(水平或垂直)排列子控件,灵活控制子控件在主轴上的尺寸比例和空间分配。相当于是Row和Column结合




































属性 描述
direction 主轴方向Axis.horizontal水平,`Axis.vertical垂直

mainAxisAlignment
控制子控件在主轴(水平/垂直方向)的排列方式
crossAxisAlignment 控制子控件在交叉轴(垂直/水平方向)的排列方式
mainAxisSize 决定Row在水平方向上的尺寸策略。沾满所有空间(max),仅仅包裹子控件内容(min)
children 垂直排列子控件列表
Expended


  • Expended/Flexible 作为Flex的子控件通过flex属性来分配Flex组件的空间。




















属性 描述
flex 分配子控件在Flex组件的空间
child
子控件

       body: Container(
width: double.infinity,
height: double.infinity,
color: Colors.amber,
child: Flex(
direction: Axis.horizontal,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
flex: 2,
child: Container(
alignment: Alignment.center,
color: Colors.red,
width: 200,
height: 200,
child: Text('111'),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.center,
color: Colors.green,
width: 200,
height: 200,
child: Text('222'),
),
),
],
),
),

Wrap


  • 流式布局,当子控件在主轴上排列不下时,它会自动换行(或换列)。

  • flex/row/column的内容超出不会自动换行
































属性 描述
direction 主轴方向Axis.horizontal水平,`Axis.vertical垂直

spacing
控制子控件在主轴的间距
runSpacing 控制子控件在交叉轴的间距
alignment 控制子控件在主轴的对齐方式
runAlignment 控制子控件在交叉轴的对齐方式

        body: Container(
width: double.infinity,
height: double.infinity,
color: Colors.amber,
child: Wrap(
direction: Axis.horizontal,
spacing: 20,
runSpacing: 20,
alignment: WrapAlignment.spaceBetween,
runAlignment: WrapAlignment.center,
children: [
Container(
alignment: Alignment.center,
color: Colors.red,
width: 200,
height: 200,
child: Text('111'),
),
Container(
alignment: Alignment.center,
width: 200,
height: 200,
color: Colors.green,
child: Text('222'),
),
],
),
),

Stack & Positioned

Stack



  • 层叠布局,允许将多个子控件按Z轴方向进行叠加排序。
































属性 描述
alignment 控制非定位的子控件在Stack内的对齐方式,默认左上角
fit 控制非定位的子控件如何适应Stack的尺寸
clipBehavor 控制非定位的子控件在Stack超出部分的裁剪方式
children 需要叠层子控件列表
Positioned


  • 层叠布局,必须作为Stack的子控件,




















属性 描述
top/bottom/left/right 控制子控件在Stack的位置
child 子控件

 body: Container(
width: double.infinity,
height: double.infinity,
color: Colors.amber,
child: Stack(
alignment: Alignment.center,
children: [
Container(
alignment: Alignment.center,
color: Colors.red,
width: 200,
height: 200,
),
Positioned(
top: 10,
left: 10,
child: Container(
height: 100,
width: 100,
color: Colors.green
),
),
Positioned(
bottom: 10,
right: 10,
child: Container(
height: 100,
width: 100,
color: Colors.blue
),
),
],
),
),

2.2.2 滚动 & 列表 & 网格






































widget 特征 使用场景
SingleChildScrollView 让单个子控件可以用滚动,所有内容一次性渲染 长表单,设置页、内容不固定但是总量不多的页面
ListView 线性列表,通过builder可实现懒加载,性能优异 聊天记录、新闻、常见单列滚动数据列表
GridView 网格列表,支持懒加载,可固定列数 图片墙、商品网格、应用图标列表
CustomScrollView 复杂布局方案,通过组合多个Sliver组件实现滚动 电商首页、社交app个人主页多个滚动紧密联动
PageView 整页滚动,支持横向和纵向滚动 应用引导页、图片轮播、书籍翻页

SingleChildScrollView


  • 让单个子控件可以用滚动,所有内容一次性渲染




















属性 描述
controller 控制滚动,绑定一个ScrollController对象给controller对象,通过animateTo/jumpTo方法实现控制滚动
scrollDirection 滚动方向,Axis.horizontal水平滚动,Axis.vertical垂直滚动

class _TestAppState extends State<TestApp> {
ScrollController _scrollController = ScrollController();

@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Stack(
children: [
SingleChildScrollView(
controller: _scrollController,
child: Column(
children: List.generate(
10,
(index) => Container(
height: 200,
width: double.infinity,
margin: EdgeInsets.all(10),
color: Colors.red,
alignment: Alignment.center,
child: Text('$index'),
),
),
),
),

Positioned(
top: 10,
right: 10,
child: GestureDetector(
onTap: () {
_scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 500),
curve: Curves.ease,
);
},
child: Container(
height: 100,
width: 100,
alignment: Alignment.center,
color: Colors.blue,
child: Text('去底部'),
),
),
),

Positioned(
bottom: 10,
right: 10,
child: GestureDetector(
onTap: () {
_scrollController.animateTo(
0,
duration: const Duration(milliseconds: 500),
curve: Curves.ease,
);
},
child: Container(
height: 100,
width: 100,
alignment: Alignment.center,
color: Colors.blue,
child: Text('去顶部'),
),
),
),
],
),
),
);
}
}

ListView


  • 线性列表,通过builder可实现懒加载,性能优异

  • 提供多种构造函数,如默认构造函数、ListView.builderListView.separated

  • 采用按需渲染懒加载,只构建当前可见区域的列表项,极大提高长列表性能
































属性 描述
controller 控制滚动,绑定一个ScrollController对象给controller对象,通过animateTo/jumpTo方法实现控制滚动
scrollDirection 滚动方向,Axis.horizontal水平滚动,Axis.vertical垂直滚动
itemCount itemCount控制列表长度
itemBuilder itemBuilder回调函数按需构建列表项
separatorbuilder 需在ListView.separated使用,为列表提供分割线

// ListView.builder
class _TestAppState extends State<TestApp> {
final ScrollController _scrollController = ScrollController();

@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Stack(
children: [
ListView.builder(
controller: _scrollController,
itemCount: 10,
itemBuilder: (context, index) => Container(
height: 200,
width: double.infinity,
margin: EdgeInsets.all(10),
color: Colors.red,
alignment: Alignment.center,
child: Text('$index'),
),
),
],
),
),
);
}
}

// ListView.separated
class _TestAppState extends State<TestApp> {
final ScrollController _scrollController = ScrollController();

@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Stack(
children: [
ListView.separated(
controller: _scrollController,
itemCount: 10,
separatorBuilder: (context, index) => Container(
height: 10,
width: double.infinity,
color: Colors.grey,
),
itemBuilder: (context, index) => Container(
height: 200,
width: double.infinity,
color: Colors.red,
margin: EdgeInsets.all(10),
alignment: Alignment.center,
child: Text('$index'),
),
),
],
),
),
);
}
}

GridView


  • 二维网格列表,支持懒加载,可固定列数

  • 提供多种构造函数,GridView.count(固定列数的网格布局)、GridView.extent(固定子项最大宽度/高度的网格布局)、GridView.builder(网格数量巨大或动态生成、需接收girdDelegate布局委托属性),默认构造函数使用起来复杂,很少用。








































属性 描述
scrollDirection 滚动方向,Axis.horizontal水平滚动,Axis.vertical垂直滚动
controller 控制滚动,绑定一个ScrollController对象给controller对象,通过animateTo/jumpTo方法实现控制滚动
mainAxisSpacing 主轴间距
crossAxisSpacing 交叉轴间距
crossAxisCount 需在GridView.count下使用,固定列数
maxCrossAxisExtent 需在GridView.extent中使用,固定子项最大宽度/高度
girdDelegate crossAxisCount固定列数、mainAxisSpacing主轴间距、crossAxisSpacing交叉轴间距

// GridView.count
body: GridView.count(
crossAxisCount: 4,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
children: List.generate(
20,
(index) => Container(
color: Colors.green,
alignment: Alignment.center,
child: Text('$index'),
),
),
),

// GridView.extent
body: GridView.extent(
scrollDirection: Axis.horizontal,
maxCrossAxisExtent: 200,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
children: List.generate(
20,
(index) => Container(
color: Colors.green,
alignment: Alignment.center,
child: Text('$index'),
),
),
),

// GridView.builder
body: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
itemCount: 100,
itemBuilder: (context, index) {
return Container(
color: Colors.green,
alignment: Alignment.center,
child: Text('$index'),
);
},
),

CustomScrollView


  • 复杂布局方案,组合多个滚动组件(列表、网格),通过组合多个Sliver组件实现滚动

  • sliver是描述可滚动视图内的一部分内容的子控件,它是滚动视图的切片。
























属性 描述
controller 控制滚动,绑定一个ScrollController对象给controller对象,通过animateTo/jumpTo方法实现控制滚动
scrollDirection 滚动方向,Axis.horizontal水平滚动,Axis.vertical垂直滚动
slivers 用于接受Sliver组件列表。

slivers组件对应关系











































子控件名称 对应组件 作用
SliverAppBar AppBar 可折叠、悬浮、固定头部,嵌套在CustomScrollView
SliverPadding Padding 给 Sliver 子组件增加内边距(不能直接包裹普通 Widget
SliverToBoxAdapter 无直接对等组件 将普通 RenderBox Widget(Container/Text 等)转为 Sliver,混合布局必备
SlievrPersistentHeader 无直接对等组件 持久吸顶头部,滚动时可以固定在顶部(自定义伸缩头部核心)
SliverList ListView 列表懒加载,对应ListView.builder逻辑
SliverGird GridView 网格布局,对应GridView.builder

class _TestAppState extends State<TestApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(title: Text("123"), pinned: true),
SliverToBoxAdapter(
child: Container(height: 200.0, color: Colors.red),
),
SliverList.builder(
itemCount: 10,
itemBuilder: (context, index) => Container(
height: 100,
width: double.infinity,
color:Colors.blue,
margin: EdgeInsets.all(10),
child: Text("第"'$index'"个"),
),
),
],
),
),
);
}
}

PageView


  • 整页滚动,支持横向和纵向滚动,实现分页滚动视图。

  • 提供多种构造函数,默认构造函数、PageView.bulider(懒加载)




















属性 描述
controller 控制滚动,绑定一个ScrollController对象给controller对象,通过animateTo/jumpTo方法实现控制滚动
scrollDirection 滚动方向,Axis.horizontal水平滚动,Axis.vertical垂直滚动

class _TestAppState extends State<TestApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Container(
height: 200,
color: Colors.blue,
child: PageView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10,
itemBuilder: (BuildContext context, int index) => Container(
margin: EdgeInsets.all(10.0),
color: Colors.red,
alignment: Alignment.center,
child: Text('第${(index+1)}页'),
),
),
),
),
);
}
}




[!danger] ^-^启动


最新回复 (1)
  • qdd28 08-04 22:46
    1

    万物皆widget,套又又套去,大概就是这个意思。

* 帖子来源Linux.do
返回