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():释放资源
相关推荐
Sugobet4 小时前
【安卓][Mac/Windows】永久理论免费 无限ip代理池 - 适合临时快速作战
android·tcp/ip·macos·网络安全·渗透测试·ip代理池·接入点
fatiaozhang95278 小时前
创维智能融合终端SK-M424_S905L3芯片_2+8G_安卓9_线刷固件包
android·电视盒子·刷机固件·机顶盒刷机
来来走走9 小时前
Flutter开发 了解Scaffold
android·开发语言·flutter
哆啦A梦的口袋呀10 小时前
Android 底层实现基础
android
闻道且行之10 小时前
Android Studio下载及安装配置
android·ide·android studio
alexhilton11 小时前
初探Compose中的着色器RuntimeShader
android·kotlin·android jetpack
小墙程序员11 小时前
kotlin元编程(二)使用 Kotlin 来生成源代码
android·kotlin·android studio
小墙程序员11 小时前
kotlin元编程(一)一文理解 Kotlin 反射
android·kotlin·android studio
fatiaozhang952712 小时前
创维智能融合终端DT741_移动版_S905L3芯片_安卓9_线刷固件包
android·电视盒子·刷机固件·机顶盒刷机
zeqinjie14 小时前
Flutter 使用 AI Cursor 快速完成一个图表封装【提效】
前端·flutter