You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter技术咨询:实现同屏按钮切换展示不同帖子的Widget推荐

Flutter实现按钮切换帖子分类的方案

当然有,Flutter提供了多种原生Widget可以实现这种按钮切换内容的效果,以下是几种贴合需求的常用方案:

1. TabBar + TabBarView(Material设计风格)

这是最经典的Material风格切换组件,完全匹配你要的"按钮切换展示不同帖子列表"的需求,自带选中状态高亮、滑动切换等特性。

示例代码:

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

  @override
  State<PostTabPage> createState() => _PostTabPageState();
}

class _PostTabPageState extends State<PostTabPage> with SingleTickerProviderStateMixin {
  late TabController _tabController;

  @override
  void initState() {
    super.initState();
    // 初始化控制器,长度对应分类数量
    _tabController = TabController(length: 2, vsync: this);
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        bottom: TabBar(
          controller: _tabController,
          tabs: const [
            Tab(text: "热门帖子"),
            Tab(text: "最新帖子"),
          ],
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: [
          // 第一类帖子列表
          ListView.builder(
            itemCount: 15,
            itemBuilder: (context, index) => ListTile(title: Text("热门帖子 $index")),
          ),
          // 第二类帖子列表
          ListView.builder(
            itemCount: 15,
            itemBuilder: (context, index) => ListTile(title: Text("最新帖子 $index")),
          ),
        ],
      ),
    );
  }
}

2. SegmentedButton(Material 3风格,Flutter 3.10+)

如果你想用Material 3的一体化分段按钮样式,SegmentedButton是更贴合的选择,按钮组视觉上是一个整体,点击切换后展示对应内容。

示例代码:

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

  @override
  State<PostSegmentPage> createState() => _PostSegmentPageState();
}

class _PostSegmentPageState extends State<PostSegmentPage> {
  // 管理选中的按钮,单选模式下集合只存一个值
  final Set<int> _selectedTab = {0};

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: SegmentedButton<int>(
              segments: const [
                ButtonSegment(value: 0, label: Text("热门帖子")),
                ButtonSegment(value: 1, label: Text("最新帖子")),
              ],
              selected: _selectedTab,
              onSelectionChanged: (newSelection) {
                setState(() {
                  _selectedTab.clear();
                  _selectedTab.addAll(newSelection);
                });
              },
            ),
          ),
          Expanded(
            child: _selectedTab.first == 0
                ? ListView.builder(
                    itemCount: 15,
                    itemBuilder: (context, index) => ListTile(title: Text("热门帖子 $index")),
                  )
                : ListView.builder(
                    itemCount: 15,
                    itemBuilder: (context, index) => ListTile(title: Text("最新帖子 $index")),
                  ),
          ),
        ],
      ),
    );
  }
}

3. CupertinoSegmentedControl(iOS设计风格)

如果你的应用需要适配iOS原生风格,可以用CupertinoSegmentedControl实现类似iOS的分段切换效果。

示例代码:

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

  @override
  State<CupertinoPostPage> createState() => _CupertinoPostPageState();
}

class _CupertinoPostPageState extends State<CupertinoPostPage> {
  int _selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: const CupertinoNavigationBar(middle: Text("帖子分类")),
      child: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: CupertinoSegmentedControl<int>(
              children: const {
                0: Text("热门帖子"),
                1: Text("最新帖子"),
              },
              groupValue: _selectedIndex,
              onValueChanged: (value) => setState(() => _selectedIndex = value),
            ),
          ),
          Expanded(
            child: _selectedIndex == 0
                ? ListView.builder(
                    itemCount: 15,
                    itemBuilder: (context, index) => CupertinoListTile(title: Text("热门帖子 $index")),
                  )
                : ListView.builder(
                    itemCount: 15,
                    itemBuilder: (context, index) => CupertinoListTile(title: Text("最新帖子 $index")),
                  ),
          ),
        ],
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者Dande132

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 04:39:25