Flutter标签页同步插件flutter_tab_sync的使用

发布于 1周前 作者 nodeper 来自 Flutter

Flutter标签页同步插件flutter_tab_sync的使用

flutter_tab_sync 是一个简化在不同高度的小部件列表中滚动到特定索引的Flutter包。它提供了三种不同的小部件来实现标签页同步功能:LabeledTabViewSyncIndicatedTabViewSyncIndexedListSync

使用方法

1. LabeledTabViewSync

LabeledTabViewSync 用于提供带有标签的标签栏。

LabeledTabViewSync<DepartmentModel>(
  items: departments,
  itemBuilder: (department, isSelected) => Column(
    crossAxisAlignment: CrossAxisAlignment.stretch,
    children: [
      Text(department.name,
          style: TextStyle(
            fontSize: 20,
            color: isSelected ? Colors.white : Colors.black38,
          )),
      const SizedBox(
        height: 8,
      ),
      ...department.employees.map((employee) => ListTile(
            title: Text(
              employee,
              style: TextStyle(
                color: isSelected ? Colors.white : Colors.black38,
              ),
            ),
          ))
    ],
  ),
  tabBuilder: (DepartmentModel item, bool isSelected) => SizedBox(
    height: 24,
    child: Text(
      item.name,
      style: TextStyle(
        fontSize: 12,
        color: isSelected ? Colors.white : Colors.black38,
      ),
    ),
  ),
  labelStyle: LabelStyle(
    color: Colors.deepPurple,
    height: 24,
  ),
  barStyle: const BarStyle(height: 32, padding: EdgeInsets.zero),
)

2. IndicatedTabViewSync

IndicatedTabViewSync 用于提供带有指示器的标签栏。

IndicatedTabViewSync<DepartmentModel>(
  items: departments,
  itemBuilder: (department, isSelected) => Column(
    crossAxisAlignment: CrossAxisAlignment.stretch,
    children: [
      Text(department.name,
          style: TextStyle(
            fontSize: 20,
            color: isSelected ? Colors.white : Colors.black38,
          )),
      const SizedBox(
        height: 8,
      ),
      ...department.employees.map((employee) => ListTile(
            title: Text(
              employee,
              style: TextStyle(
                color: isSelected ? Colors.white : Colors.black38,
              ),
            ),
          ))
    ],
  ),
  tabBuilder: (DepartmentModel item, bool isSelected) => SizedBox(
    height: 24,
    child: Text(
      item.name,
      style: TextStyle(
        fontSize: 12,
        color: isSelected ? Colors.white : Colors.black38,
      ),
    ),
  ),
  indicatorStyle: IndicatorStyle(
    indicatorColor: Colors.deepPurple,
    overlayColor: Colors.deepPurple.shade200,
    indicatorThickness: 2,
    indicatorPadding: const EdgeInsets.symmetric(horizontal: 4),
    indicatorSize: TabBarIndicatorSize.label,
  ),
  barStyle: const BarStyle(height: 32, padding: EdgeInsets.zero),
)

3. IndexedListSync

IndexedListSync 用于通过传递选定的索引来滚动到特定索引。

ValueNotifier<int> selectedIndex = ValueNotifier(0);

ValueListenableBuilder<int>(
  valueListenable: selectedIndex,
  builder: (_, value, __) => IndexedListSync<DepartmentModel>(
    selectedIndex: value,
    items: departments,
    itemBuilder: (department, isSelected) => Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        Text(department.name,
            style: TextStyle(
              fontSize: 20,
              color: isSelected ? Colors.white : Colors.black38,
            )),
        const SizedBox(
          height: 8,
        ),
        ...department.employees.map((employee) => ListTile(
              title: Text(
                employee,
                style: TextStyle(
                  color: isSelected ? Colors.white : Colors.black38,
                ),
              ),
            ))
      ],
    ),
  ),
);

完整示例 Demo

以下是一个完整的示例,展示了如何使用 flutter_tab_sync 包:

import 'package:flutter/material.dart';
import 'package:flutter_tab_sync/flutter_tab_sync.dart';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({
    super.key,
  });

  final List<DepartmentModel> departments = [
    DepartmentModel(
      name: 'Department1',
      employees: ['Wissam', 'Mohammad', 'Mikel', 'Ahmad'],
    ),
    DepartmentModel(
      name: 'Department2',
      employees: ['Max', 'Robin', 'Kareem', 'Toni', 'Lubna'],
    ),
    DepartmentModel(
      name: 'Department3',
      employees: ['Leen', 'Nour'],
    ),
    DepartmentModel(
      name: 'Department4',
      employees: ['Jessica', 'Luka', 'Antonio'],
    ),
    DepartmentModel(
      name: 'Department5',
      employees: ['Dani', 'Lora', 'Mariam'],
    ),
    DepartmentModel(
      name: 'Department6',
      employees: ['Jessica', 'Luka', 'Antonio'],
    ),
  ];

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blueAccent.shade100,
      appBar: AppBar(
        title: const Text('Flutter Tab Async'),
        surfaceTintColor: Colors.transparent,
        shadowColor: Colors.transparent,
        elevation: 0,
      ),
      body: LabeledTabViewSync<DepartmentModel>(
        items: departments,
        itemBuilder: (department, isSelected) => Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Text(department.name,
                style: TextStyle(
                  fontSize: 20,
                  color: isSelected ? Colors.white : Colors.black38,
                )),
            const SizedBox(
              height: 8,
            ),
            ...department.employees.map((employee) => ListTile(
                  title: Text(
                    employee,
                    style: TextStyle(
                      color: isSelected ? Colors.white : Colors.black38,
                    ),
                  ),
                ))
          ],
        ),
        tabBuilder: (DepartmentModel item, bool isSelected) => SizedBox(
          height: 24,
          child: Text(
            item.name,
            style: TextStyle(
              fontSize: 12,
              color: isSelected ? Colors.white : Colors.black38,
            ),
          ),
        ),
        labelStyle: LabelStyle(
          color: Colors.deepPurple,
          height: 24,
        ),
        barStyle: const BarStyle(height: 32, padding: EdgeInsets.zero),
      ),
    );
  }
}

class DepartmentModel {
  final String name;
  final List<String> employees;

  DepartmentModel({required this.name, required this.employees});
}

更多关于Flutter标签页同步插件flutter_tab_sync的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter标签页同步插件flutter_tab_sync的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用flutter_tab_sync插件的一个简单示例。这个插件主要用于在多个标签页之间同步状态。假设你已经添加了flutter_tab_sync依赖到你的pubspec.yaml文件中,并且已经运行了flutter pub get

1. 添加依赖

首先,确保你的pubspec.yaml文件中包含以下依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_tab_sync: ^latest_version  # 替换为最新的版本号

2. 导入包

在你的Dart文件中导入flutter_tab_sync包:

import 'package:flutter/material.dart';
import 'package:flutter_tab_sync/flutter_tab_sync.dart';

3. 创建同步状态管理

使用TabSyncController来管理标签页的同步状态。下面是一个简单的例子,展示如何在两个标签页之间同步一个整数值。

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Tab Sync Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: TabSyncDemo(),
    );
  }
}

class TabSyncDemo extends StatefulWidget {
  @override
  _TabSyncDemoState createState() => _TabSyncDemoState();
}

class _TabSyncDemoState extends State<TabSyncDemo> with SingleTickerProviderStateMixin {
  late TabController _tabController;
  late TabSyncController _tabSyncController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 2, vsync: this);
    _tabSyncController = TabSyncController(
      initialState: 0,  // 初始状态值
      tabController: _tabController,
    );

    // 监听同步状态的变化
    _tabSyncController.addListener(() {
      print('Current Sync State: ${_tabSyncController.state}');
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Tab Sync Demo'),
        bottom: TabBar(
          controller: _tabController,
          tabs: [
            Tab(icon: Icon(Icons.directions_car)),
            Tab(icon: Icon(Icons.directions_transit)),
          ],
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: [
          TabSyncPage(
            tabSyncController: _tabSyncController,
            tabIndex: 0,
          ),
          TabSyncPage(
            tabSyncController: _tabSyncController,
            tabIndex: 1,
          ),
        ],
      ),
    );
  }
}

class TabSyncPage extends StatefulWidget {
  final TabSyncController tabSyncController;
  final int tabIndex;

  const TabSyncPage({Key? key, required this.tabSyncController, required this.tabIndex}) : super(key: key);

  @override
  _TabSyncPageState createState() => _TabSyncPageState();
}

class _TabSyncPageState extends State<TabSyncPage> {
  TextEditingController _controller = TextEditingController();

  @override
  void initState() {
    super.initState();
    // 初始化时设置文本控制器内容为当前同步状态
    _controller.value = TextEditingValue(text: widget.tabSyncController.state.toString());

    // 监听同步状态的变化
    widget.tabSyncController.addListener(() {
      setState(() {
        _controller.value = TextEditingValue(text: widget.tabSyncController.state.toString());
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          TextField(
            controller: _controller,
            decoration: InputDecoration(labelText: 'Sync State'),
            keyboardType: TextInputType.number,
            onChanged: (value) {
              // 当文本变化时,更新同步状态
              int? newState = int.tryParse(value);
              if (newState != null) {
                widget.tabSyncController.setState(newState);
              }
            },
          ),
        ],
      ),
    );
  }

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

解释

  1. TabSyncController: 用于管理标签页之间的同步状态。
  2. TabController: 用于控制标签页的切换。
  3. TabSyncPage: 每个标签页的内容,包含一个TextField用于显示和修改同步状态。
  4. 监听和更新: 当TextField的内容变化时,通过widget.tabSyncController.setState(newState)更新同步状态;同时,通过监听widget.tabSyncController的变化来更新TextField的内容。

这个示例展示了如何在两个标签页之间同步一个简单的整数值。你可以根据需要扩展这个示例,同步更复杂的数据结构或状态。

回到顶部