Flutter常用组件的使用

Widget简介

Flutter中的组件Widget,它类似于Android中View的概念。其中Widget又包括StatefulWidget和StatelessWidegt,有状态的和无状态的。为了避免初学Flutter的JY不知道什么是状态,我简单提一嘴。你可以理解为使用变量来保存视图的参数,通过改变变量值,也就是我们所说的状态,来达到修改界面的目的。

dart 复制代码
class MyCounter extends StatefulWidget {
  @override
  _MyCounterState createState() => _MyCounterState();
}

class _MyCounterState extends State<MyCounter> {
  int count = 0;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Count: $count'),
        ElevatedButton(
          onPressed: () {
            setState(() {
              count++;
            });
          },
          child: Text('Add'),
        ),
      ],
    );
  }
}

比如以上就是一个简单的官方Demo来演示带状态组件的使用。那么无状态组件就更简洁了。

dart 复制代码
class MyText extends StatelessWidget {
  final String title;

  MyText(this.title);

  @override
  Widget build(BuildContext context) {
    return Text(title);
  }
}

常用的组件

学习完基础的常用组件,就可以开发大部分的界面了,所以下面的内容非常重要,基础中的基础。

我会介绍以下组件。

  • 布局类ContainerRowColumnStackExpandedPositionedPaddingSizedBox
  • 交互类GestureDetectorInkWellElevatedButtonIconButtonTextField
  • 显示类TextRichTextImageListViewScaffold

建议按照我给的顺序,循序渐进学习。

Scaffold

Scaffold翻译成脚手架,你可以理解成一个界面大致的组成部分,即页面大体框架。

dart 复制代码
Scaffold(
  appBar: AppBar(title: Text('Home')),
  body: Center(child: Text('Welcome to Flutter')),
  floatingActionButton: FloatingActionButton(
    onPressed: () {},
    child: Icon(Icons.add),
  ),
)

这里提供了AppBar、Drawer、BottomNavigationBar等标准页面结构。整体是通过嵌套方式进行布局。

dart 复制代码
BottomNavigationBar(
  items: [
    BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
    BottomNavigationBarItem(icon: Icon(Icons.settings), label: 'Settings'),
  ],
  currentIndex: 0,
  onTap: (index) {
    // Handle tab switch
  },
)

再简单了解下BottomNavigationBar。

Container

Container 是最常用的布局容器,支持设置宽高、边距、边框、背景颜色等。

dart 复制代码
Container(
  width: 200,
  height: 100,
  padding: EdgeInsets.all(16),
  margin: EdgeInsets.symmetric(vertical: 10),
  decoration: BoxDecoration(
    color: Colors.blue,
    borderRadius: BorderRadius.circular(10),
  ),
  child: Text('Hello Flutter', style: TextStyle(color: Colors.white)),
)

EdgeInsets用于设置margin和padding。 常用的构造方法有:

dart 复制代码
EdgeInsets.all(double value)
EdgeInsets.symmetric({horizontal, vertical})
EdgeInsets.only({left, top, right, bottom})
EdgeInsets.fromLTRB(left, top, right, bottom)

使用方式如下:

dart 复制代码
padding: EdgeInsets.all(16) // 所有值相同
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10) // 水平或垂直相同
padding: EdgeInsets.only(left: 10, top: 5) // 可以指定特定的一个或多个
padding: EdgeInsets.fromLTRB(10, 20, 10, 5) // 完整指定

SizedBox

它是一个固定尺寸/占位组件,常用于设置固定宽高,或者作为空白间距。

dart 复制代码
SizedBox(height: 20), // 垂直间距
SizedBox(width: 10),  // 水平间距

SizedBox(
  width: 100,
  height: 50,
  child: ElevatedButton(onPressed: () {}, child: Text('Button')),
)

Column、Row和Stack

这几个我为什么会放在一起来讲,因为这样比较好类比理解。Column代表垂直排列组件,Row代表水平排列组件,类似于我们Android中的LinearLayout。

dart 复制代码
Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    Text('Title', style: TextStyle(fontSize: 20)),
    Text('Subtitle'),
  ],
)

Row(
  mainAxisAlignment: MainAxisAlignment.spaceAround,
  children: [
    Icon(Icons.star, color: Colors.orange),
    Icon(Icons.star, color: Colors.orange),
    Icon(Icons.star, color: Colors.orange),
  ],
)

mainAxisAlignment和crossAxisAlignment,代表主轴和交叉轴的对齐方式。顾名思义,如果为Column,即垂直排列,那么主轴的方向就是y轴,即垂直方向。它的交叉轴就是水平方向,CrossAxisAlignment.start表示水平方向左对齐。其它的类似,我这里就不多赘述。

dart 复制代码
Stack(
  alignment: Alignment.center,
  children: [
    Image.asset('assets/images/bg.png'),
    Text('Overlay Text', style: TextStyle(fontSize: 24, color: Colors.white)),
  ],
)

另外,Stack也是一个常用的布局方式,类似于我们Android中的FrameLayout,即允许多个子组件堆叠显示,适合用于浮层、背景叠加等场景。

Text

Text是一个文本显示组件,类似于我们Android中的TextView

dart 复制代码
Text(
  'Hello, Flutter!',
  style: TextStyle(
    fontSize: 24,
    color: Colors.black87,
    fontWeight: FontWeight.bold,
  ),
)

Image

Image是一个图片显示组件,类似于我们Android中的ImageView,它支持加载网络图片、本地资源图片。

dart 复制代码
Image.network('https://example.com/image.png')
Image.asset('assets/images/logo.png')

my_flutter_project/

├── assets/

│ ├── images/

│ │ ├── logo.png

│ │ ├── bg.jpg

├── pubspec.yaml

你可以随便命名文件夹,常见的命名有 assets/, assets/images/, images/ 等。需要注意的是,图片添加到对应文件夹还不够,还需要在pubspec.yaml文件中注册。

yaml 复制代码
flutter:
  assets:
    - assets/images/logo.png
    - assets/images/bg.jpg

或者你省略成

yaml 复制代码
flutter:
  assets:
    - assets/images/

缩进采用两字符缩进。

ElevatedButton

按钮组件,类似于我们Android中的Button

dart 复制代码
ElevatedButton(
  onPressed: () {
    print('Button pressed');
  },
  child: Text('Click Me'),
)

IconButton

带图标的按钮组件,类似于我们Android中的ImageButton,在Icons中提供了很多系统的icon,常用的icon有很多。

dart 复制代码
IconButton(
  icon: Icon(Icons.favorite),
  color: Colors.red,
  onPressed: () {
    print('Favorited');
  },
)

TextField

输入框组件,类似于我们Android中的EditText

dart 复制代码
TextField(
  decoration: InputDecoration(
    labelText: 'Enter your name',
    border: OutlineInputBorder(),
  ),
)

它的输入监听就需要结合状态了。

dart 复制代码
class MyTextInputPage extends StatefulWidget {
  @override
  _MyTextInputPageState createState() => _MyTextInputPageState();
}

class _MyTextInputPageState extends State<MyTextInputPage> {
  final TextEditingController _controller = TextEditingController();

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('TextEditingController 示例')),
      body: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          children: [
            TextField(
              controller: _controller,
              decoration: InputDecoration(labelText: '请输入'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                print('你输入的是:${_controller.text}');
              },
              child: Text('打印输入内容'),
            )
          ],
        ),
      ),
    );
  }
}

GestureDetector

慢慢的,我们开始有交互了。使用GestureDetector手势探测器可以给组件添加点击、长按事件。

dart 复制代码
GestureDetector(
  onTap: () {
    print('Container tapped');
  },
  child: Container(
    color: Colors.red,
    padding: EdgeInsets.all(20),
    child: Text('Tap me'),
  ),
)

InkWell

点击反馈组件,带有水波纹效果。

dart 复制代码
InkWell(
  onTap: () {
    print('Tapped');
  },
  child: Padding(
    padding: EdgeInsets.all(12),
    child: Text('Click Me'),
  ),
)

Android中的实现为给布局容器添加以下属性。

xml 复制代码
android:clickable="true"
android:foreground="?selectableItemBackground"

Expanded

弹性填充组件。常用于 RowColumn 中,自动填满剩余空间。

dart 复制代码
Row(
  children: [
    Icon(Icons.star),
    Expanded(
      child: Text('This is a very long text that will expand.'),
    ),
  ],
)

Positioned

Positioned 通常配合 Stack 使用,允许你指定子组件在父容器中的精确位置。

dart 复制代码
Stack(
  children: [
    Container(width: 200, height: 200, color: Colors.grey),
    Positioned(
      top: 10,
      left: 10,
      child: Text('Top Left', style: TextStyle(color: Colors.white)),
    ),
  ],
)

Padding

内边距组件。

dart 复制代码
Padding(
  padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
  child: Text('With Padding'),
)

RichText

常用的还有富文本组件,Android中类似的概念有Spannable

dart 复制代码
RichText(
  text: TextSpan(
    text: 'Hello ',
    style: TextStyle(fontSize: 18, color: Colors.black),
    children: [
      TextSpan(
        text: 'Flutter',
        style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),
      ),
      TextSpan(text: '!'),
    ],
  ),
)

ListView

列表组件,类似于我们Android中的RecyclerViewListView

dart 复制代码
ListView(
  children: List.generate(10, (index) => ListTile(title: Text('Item $index'))),
)

或者使用ListView.builder

dart 复制代码
ListView.builder(
  itemCount: 20,
  itemBuilder: (context, index) {
    return ListTile(title: Text('Item $index'));
  },
)

总结

我们复习下刚才讲过的内容,来对知识点进行梳理,以加深印象。复习完后,趁热打铁,动手实践一下学习效果更佳哦。

✅ Flutter Widget 简介

  • Widget 是 Flutter 的基本构建单位,一切UI都是Widget。

  • 分为两类:

    • StatelessWidget:无状态(固定不变的 UI)
    • StatefulWidget:有状态(可以随用户操作更新)

✅ 常用 Widget 简要汇总

组件名 作用说明
Container 万能容器(可设置大小、颜色、边框等)
Text 显示文字
Row / Column 横向 / 纵向布局
ListView 可滚动列表
Scaffold 页面基础结构(AppBar、body 等)
Padding 添加内边距
SizedBox 固定宽高 / 空白间隔
Stack 子组件重叠显示
Positioned Stack 中定位子组件
Expanded 撑满剩余空间
IconButton 带图标的按钮
InkWell 带水波纹点击效果
RichText 富文本(多样式文字组合)

✅ EdgeInsets(边距设置)

用于设置 padding(内边距)或 margin(外边距) 的类:

  • EdgeInsets.all(10):四边都是 10
  • EdgeInsets.symmetric(horizontal: 20, vertical: 10):左右 20,上下 10
  • EdgeInsets.only(left: 5, top: 10):单独设置某几边

✅ Image 资源注册

  1. 图片放入 assets/images/ 文件夹
  2. pubspec.yaml 注册:
yaml 复制代码
flutter:
  assets:
    - assets/images/
  1. 使用图片:
dart 复制代码
Image.asset('assets/images/logo.png')

✅ TextEditingController(输入框控制器)

  • 用于控制、监听 TextField 的内容

  • 常用方法:

    • .text:获取或设置值
    • .addListener():监听变化
    • .dispose():释放资源
相关推荐
_一条咸鱼_2 小时前
Android ARouter 处理器模块深度剖析(三)
android·面试·android jetpack
_一条咸鱼_2 小时前
Android ARouter 基础库模块深度剖析(四)
android·面试·android jetpack
_一条咸鱼_2 小时前
Android ARouter 核心路由模块原理深度剖析(一)
android·面试·android jetpack
火柴就是我2 小时前
android 基于 PhotoEditor 这个库 开发类似于dlabel的功能
android
_一条咸鱼_2 小时前
Android ARouter 编译器模块深度剖析(二)
android·面试·android jetpack
Gracker3 小时前
Android Weekly #202515
android
getapi3 小时前
flutter app实现分辨率自适应的图片资源加载
前端·javascript·flutter
鸿蒙布道师4 小时前
鸿蒙NEXT开发键盘工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
小龙在山东4 小时前
利用 Deepseek 和 Mermaid 画流程图
android·流程图
大风起兮云飞扬丶5 小时前
Android——动画
android