前言

Flutter 的系统接口是与框架核心能力直接相关的 API,不依赖平台通道或三方库。其中框架核心接口覆盖组件生命周期、状态管理、上下文、应用入口、路由、控制器、主题与布局等,是日常开发中最常接触的一类。本文对框架核心接口做归纳总结,并配以最小粒度代码示例,便于查阅与实战。


一、框架核心接口总览

接口 / 类 功能领域 核心方法 / 属性
StatefulWidget / StatelessWidget 组件生命周期 createState()build()initState()dispose()didUpdateWidget()
State 状态管理 setState()mountedcontextwidget
BuildContext 上下文 findAncestorWidgetOfExactType()dependOnInheritedWidgetOfExactType()sizeorientation
MaterialApp 应用入口 homeroutesthemelocalenavigatorKeyonGenerateRoute
Navigator 路由导航 push()pop()pushNamed()popUntil()replace()
Route 路由对象 MaterialPageRouteCupertinoPageRoutePageRouteBuilder
TextEditingController 文本控制 textclear()addListener()selection
ScrollController 滚动控制 offsetjumpTo()animateTo()addListener()position
PageController 页面控制 initialPagejumpToPage()animateToPage()page
AnimationController 动画控制 durationforward()reverse()repeat()value
TickerProvider 帧回调 SingleTickerProviderStateMixinTickerProviderStateMixin
ThemeData 主题配置 primaryColorcolorSchemetextThemeappBarTheme
MediaQuery 设备信息 sizepaddingdevicePixelRatioorientationtextScaleFactor
OrientationBuilder 方向监听 builder(回调返回当前屏幕方向)
LayoutBuilder 布局监听 builder(回调返回父容器约束)
DefaultAssetBundle 资源加载 of()load()loadString()loadImage()

二、组件生命周期:StatefulWidget / StatelessWidget

StatelessWidget 无内部状态,仅依赖传入的配置与父级数据;StatefulWidget 通过 createState() 创建 State,在 State 中维护可变状态并调用 build()

示例:StatefulWidget + setState

class CounterWidget extends StatefulWidget {
  const CounterWidget({super.key});

  
  State<CounterWidget> createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _count = 0;

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

  
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Text('Count: $_count', style: TextStyle(fontSize: 18)),
        SizedBox(height: 8),
        ElevatedButton(onPressed: _increment, child: Text('Increment')),
      ],
    );
  }
}

image-20260202171032197


三、状态管理:State

State 持有可变数据,通过 setState() 触发重建;可访问 contextwidget(对应 StatefulWidget 实例),在 initState() / dispose() 中做初始化和释放。

示例:setState 与 widget 属性

class MyWidget extends StatefulWidget {
  final String title;
  const MyWidget({super.key, required this.title});

  
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  int _value = 0;

  
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Text('${widget.title}: $_value'),
        ElevatedButton(
          onPressed: () => setState(() => _value++),
          child: Text('+1'),
        ),
      ],
    );
  }
}

image-20260202171127591


四、上下文:BuildContext

BuildContext 代表在树中的位置,用于查找祖先、依赖 InheritedWidget(如 Theme.of(context)MediaQuery.of(context))、以及参与定位与尺寸信息。

示例:Theme.of(context) 与 MediaQuery.of(context)

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

  
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final mediaQuery = MediaQuery.of(context);
    return Container(
      padding: EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: theme.colorScheme.primaryContainer,
        borderRadius: BorderRadius.circular(8),
      ),
      child: Text(
        '宽度: ${mediaQuery.size.width.toStringAsFixed(0)}',
        style: theme.textTheme.titleMedium,
      ),
    );
  }
}

image-20260202171154578


五、应用入口:MaterialApp

MaterialApp 提供 Material 风格根配置:homeroutesthemedarkThemelocalenavigatorKeyonGenerateRoute 等,是应用级入口。

示例:home + theme

MaterialApp(
  title: '框架核心接口示例',
  theme: ThemeData(
    colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
    useMaterial3: true,
  ),
  home: Scaffold(
    appBar: AppBar(title: Text('首页')),
    body: Center(child: Text('Hello, Flutter!')),
  ),
)

image-20260202171213174


六、路由导航:Navigator

Navigator 管理路由栈,常用 push()pop()pushNamed()pushReplacement() 等;通过 Navigator.of(context) 获取当前导航器。

示例:push 与 pop

// 跳转
ElevatedButton(
  onPressed: () {
    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) => Scaffold(
          appBar: AppBar(title: Text('详情')),
          body: Center(child: Text('新页面')),
        ),
      ),
    );
  },
  child: Text('跳转到新页面'),
)

// 返回
ElevatedButton(
  onPressed: () => Navigator.of(context).pop(),
  child: Text('返回'),
)

image-20260202171255675


七、路由对象:Route

具体路由由 Route 子类表示:MaterialPageRouteCupertinoPageRoutePageRouteBuilder 等,用于配置转场与页面构建。

示例:MaterialPageRoute

Navigator.of(context).push(
  MaterialPageRoute<void>(
    builder: (context) => Scaffold(
      appBar: AppBar(title: Text('Route 示例')),
      body: Center(child: Text('通过 MaterialPageRoute 打开')),
    ),
    settings: RouteSettings(name: '/demo'),
  ),
);

image-20260202171332502


八、文本控制:TextEditingController

TextEditingController 绑定到 TextField,提供 textselectionclear(),并通过 addListener() 监听内容变化。

示例:绑定与监听

final controller = TextEditingController();

// 监听
controller.addListener(() {
  print('当前文本: ${controller.text}');
});

TextField(
  controller: controller,
  decoration: InputDecoration(
    labelText: '输入',
    border: OutlineInputBorder(),
  ),
)

// 代码中设置
controller.text = 'Hello';
controller.clear();

image-20260202171418632


九、滚动控制:ScrollController

ScrollController 绑定到 ListViewGridViewSingleChildScrollView 等,可读 offsetposition,并调用 jumpTo()animateTo() 控制滚动位置。

示例:jumpTo 与 animateTo

final scrollController = ScrollController();

ListView.builder(
  controller: scrollController,
  itemCount: 50,
  itemBuilder: (context, index) => ListTile(title: Text('Item $index')),
)

// 滚动到指定位置
scrollController.jumpTo(100.0);
scrollController.animateTo(200.0, duration: Duration(milliseconds: 300), curve: Curves.easeOut);

image-20260202171504497


十、页面控制:PageController

PageController 用于 PageView,支持 initialPagejumpToPage()animateToPage()page(当前页),常配合 PageView.builder 做轮播或分页。

示例:PageView + PageController

final pageController = PageController(initialPage: 0);

PageView(
  controller: pageController,
  children: [
    Center(child: Text('第 1 页', style: TextStyle(fontSize: 24))),
    Center(child: Text('第 2 页', style: TextStyle(fontSize: 24))),
    Center(child: Text('第 3 页', style: TextStyle(fontSize: 24))),
  ],
)

// 切换页
pageController.animateToPage(1, duration: Duration(milliseconds: 300), curve: Curves.easeInOut);

image-20260202171543722


十一、动画控制:AnimationController

AnimationControllervsync(需 TickerProvider)下驱动动画,通过 forward()reverse()repeat() 控制播放,value 在 0.0~1.0 之间变化。

示例:forward / reverse + value

class AnimationExample extends StatefulWidget {
  const AnimationExample({super.key});

  
  State<AnimationExample> createState() => _AnimationExampleState();
}

class _AnimationExampleState extends State<AnimationExample>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 1),
    );
  }

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

  
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        AnimatedBuilder(
          animation: _controller,
          builder: (context, child) => Container(
            width: 50 + 100 * _controller.value,
            height: 50,
            color: Colors.blue,
          ),
        ),
        SizedBox(height: 16),
        Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            ElevatedButton(onPressed: () => _controller.forward(), child: Text('播放')),
            SizedBox(width: 8),
            ElevatedButton(onPressed: () => _controller.reverse(), child: Text('倒放')),
          ],
        ),
      ],
    );
  }
}

image-20260202171624987


十二、帧回调:TickerProvider

TickerProviderAnimationController 提供 vsync,避免在不可见时仍驱动动画。常用 mixin:SingleTickerProviderStateMixin(单控制器)、TickerProviderStateMixin(多控制器)。

示例:SingleTickerProviderStateMixin

class TickerExample extends StatefulWidget {
  const TickerExample({super.key});

  
  State<TickerExample> createState() => _TickerExampleState();
}

class _TickerExampleState extends State<TickerExample>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 2),
    )..repeat();
  }

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

  
  Widget build(BuildContext context) {
    return RotationTransition(
      turns: _controller,
      child: Icon(Icons.refresh, size: 48, color: Colors.blue),
    );
  }
}

image-20260202171651038


十三、主题配置:ThemeData

ThemeData 定义颜色、文字、组件主题等;通过 Theme.of(context)ThemeData.of(context) 在子树中获取。

示例:ThemeData 与 Theme.of(context)

Theme(
  data: ThemeData(
    colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
    textTheme: TextTheme(titleLarge: TextStyle(fontSize: 22, fontWeight: FontWeight.bold)),
  ),
  child: Builder(
    builder: (context) {
      final theme = Theme.of(context);
      return Container(
        padding: EdgeInsets.all(16),
        color: theme.colorScheme.surfaceContainerHighest,
        child: Text('标题', style: theme.textTheme.titleLarge),
      );
    },
  ),
)

image-20260202171713130


十四、设备信息:MediaQuery

MediaQuery 通过 MediaQuery.of(context) 提供屏幕尺寸、padding、像素比、方向、文字缩放等,用于适配与布局判断。

示例:size 与 orientation

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

  
  Widget build(BuildContext context) {
    final mq = MediaQuery.of(context);
    final size = mq.size;
    final orientation = mq.orientation;
    return Container(
      padding: EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.blue.shade100,
        borderRadius: BorderRadius.circular(8),
      ),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('宽度: ${size.width.toStringAsFixed(0)}'),
          Text('高度: ${size.height.toStringAsFixed(0)}'),
          Text('方向: ${orientation == Orientation.portrait ? "竖屏" : "横屏"}'),
        ],
      ),
    );
  }
}

image-20260202171729907


十五、方向监听:OrientationBuilder

OrientationBuilderbuilder 会随设备方向变化重建,可据此切换布局(如横竖屏不同列数)。

示例:根据方向显示不同布局

OrientationBuilder(
  builder: (context, orientation) {
    return orientation == Orientation.portrait
        ? Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Icon(Icons.phone_android, size: 48),
              SizedBox(height: 8),
              Text('竖屏布局'),
            ],
          )
        : Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              Icon(Icons.phone_android, size: 48),
              SizedBox(width: 8),
              Text('横屏布局'),
            ],
          );
  },
)

image-20260202171747436


十六、布局监听:LayoutBuilder

LayoutBuilderbuilder 能拿到父级传入的 BoxConstraints,可根据最大/最小宽高做响应式布局。

示例:根据约束调整子组件

LayoutBuilder(
  builder: (context, constraints) {
    final width = constraints.maxWidth;
    final isNarrow = width < 200;
    return Container(
      padding: EdgeInsets.all(16),
      color: Colors.green.shade100,
      child: isNarrow
          ? Text('窄屏', style: TextStyle(fontSize: 14))
          : Text('宽屏布局,当前宽度: ${width.toStringAsFixed(0)}', style: TextStyle(fontSize: 16)),
    );
  },
)

image-20260202171831746


十七、资源加载:DefaultAssetBundle

DefaultAssetBundle 通过 DefaultAssetBundle.of(context) 获取当前 AssetBundle,可调用 loadString()load()loadImage() 等加载资源。

示例:loadString 加载文本资源

FutureBuilder<String>(
  future: DefaultAssetBundle.of(context).loadString('assets/sample.txt'),
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.done) {
      if (snapshot.hasError) {
        return Text('加载失败: ${snapshot.error}');
      }
      return Padding(
        padding: EdgeInsets.all(16),
        child: Text(snapshot.data ?? '(空)'),
      );
    }
    return Padding(
      padding: EdgeInsets.all(16),
      child: CircularProgressIndicator(),
    );
  },
)

image-20260202172715708


小结

以上 16 类框架核心接口覆盖了 Flutter 应用从组件编写、状态更新、上下文使用、应用与路由配置,到各类控制器与主题、媒体、布局、资源的常用能力。掌握其最小粒度方法与典型用法,有助于在系统接口层面做归纳与扩展,同时验证了开发鸿蒙应用的可能性。

欢迎加入开源鸿蒙跨平台社区

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐