Flutter原生分段控件集成插件native_segments的使用

Flutter 原生分段控件集成插件 native_segments 的使用

可访问的分段控件(iOS)和“顶部”标签栏(Android)用于 Flutter

该插件提供了在 iOS 上可访问的原生 UISegmentedControl 和在 Android 上的 TabLayout(与我的 native_tab_bar 插件不同,后者提供了底部导航标签栏)。

此组件通常用于页面顶部的导航。Flutter 中的“等效”组件是 CupertinoSegmentedControlTabBar 组件。

解决的可访问性问题

由于 Apple 和 Google 在其可访问性 API 中施加的限制,当前 Flutter 引擎无法完全复制这些组件中的原生可访问性行为,因为它们的“特征”仅通过原生视图类可用(Flutter 有自己的渲染引擎,并不会为每种类型的组件实例化原生视图类)。

例如,Flutter 组件试图通过将“按钮”一词和段落索引(如“1/3”等)添加到可访问性标签中来模仿原生组件的行为,但这是一种不正确的做法,因为:

  • 盲文显示器用户期望简短的特征描述,如“按钮”和列表项编号,因为盲文显示器价格昂贵且列数有限(通常是 40 列或更少)。
  • 使用语音控制/语音访问的用户需要能够只用按钮标签进行语音操作,而无需说出标题加上“按钮 2/3”。
  • 当逐字导航时,VoiceOver 和 TalkBack 用户希望只读取按钮标题,而不是“按钮”或“2/3”等。

安装

flutter pub add native_segments

依赖项

  • flutter
  • plugin_platform_interface
  • uuid

使用示例

请参阅 example/lib/main.dart 获取完整的使用示例。

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:native_segments/native_segments.dart';

const Color kPrimaryBlue = Color(0xff0073d1);

void main() => runApp(const MyApp());

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Segments Test',
      theme: ThemeData(
        brightness: Brightness.light,
      ),
      darkTheme: ThemeData(
        brightness: Brightness.dark,
      ),
      debugShowCheckedModeBanner: false,
      home: const HomePage(),
    );
  }
}

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

  [@override](/user/override)
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<NativeSegment> segments = [
    NativeSegment(title: 'first'),
    NativeSegment(title: 'second segment long text'),
    NativeSegment(title: 'third segment'),
  ];

  List<NativeSegment> segments2 = [
    NativeSegment(title: 'another item'),
    NativeSegment(title: 'something else'),
    NativeSegment(title: 'final segment'),
  ];

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Segments Example')),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        children: [
          const Divider(height: 2),
          NativeSegments(
            onValueChanged: (value) {
              print("#1 CHANGED VALUE: ${value}");
            },
            segments: segments,
            style: NativeSegmentsStyle(
              backgroundColor: Colors.transparent,
              isDarkTheme: false,
              selectedSegmentColor: kPrimaryBlue,
            ),
          ),
          const Divider(height: 2),
          NativeSegments(
            onValueChanged: (value) {
              print("#2 CHANGED VALUE: ${value}");
            },
            segments: segments,
            style: NativeSegmentsStyle(
              backgroundColor: Colors.transparent,
              isDarkTheme: true,
              selectedSegmentColor: kPrimaryBlue,
            ),
          ),
          const Divider(height: 2),
          NativeSegments(
            onValueChanged: (value) {
              print("#3 CHANGED VALUE: ${value}");
            },
            segments: segments2,
            style: NativeSegmentsStyle(
              selectedSegmentColor: kPrimaryBlue,
              backgroundColor: Colors.transparent,
            ),
          ),
        ],
      ),
    );
  }
}

更多关于Flutter原生分段控件集成插件native_segments的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter原生分段控件集成插件native_segments的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


native_segments 是一个 Flutter 插件,用于在应用中集成原生的分段控件(Segmented Control)。它允许你在 Flutter 应用中使用 iOS 的 UISegmentedControl 和 Android 的 RadioGroup 等原生控件,以提供更一致的原生用户体验。

安装

首先,你需要在 pubspec.yaml 文件中添加 native_segments 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  native_segments: ^1.0.0  # 请使用最新版本

然后,运行 flutter pub get 来安装依赖。

基本用法

native_segments 提供了一个 NativeSegments 小部件,你可以像使用其他 Flutter 小部件一样使用它。以下是一个简单的示例:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Native Segments Example'),
        ),
        body: Center(
          child: NativeSegments(
            items: ['Option 1', 'Option 2', 'Option 3'],
            onValueChanged: (int index) {
              print('Selected index: $index');
            },
          ),
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个包含三个选项的分段控件。当用户选择一个选项时,onValueChanged 回调会触发,并返回所选选项的索引。

自定义样式

你可以通过 NativeSegmentsstyle 参数来自定义分段控件的外观。例如:

NativeSegments(
  items: ['Option 1', 'Option 2', 'Option 3'],
  onValueChanged: (int index) {
    print('Selected index: $index');
  },
  style: NativeSegmentsStyle(
    selectedColor: Colors.blue,
    unselectedColor: Colors.grey,
    textStyle: TextStyle(fontSize: 16, color: Colors.white),
  ),
)

NativeSegmentsStyle 类允许你设置选中和未选中选项的颜色、文本样式等。

设置默认选项

你可以通过 initialIndex 参数来设置默认选中的选项:

NativeSegments(
  items: ['Option 1', 'Option 2', 'Option 3'],
  onValueChanged: (int index) {
    print('Selected index: $index');
  },
  initialIndex: 1,  // 默认选中第二个选项
)

处理选项变化

onValueChanged 回调函数会在用户选择不同的选项时触发。你可以在这个回调中处理选项变化,例如更新应用的状态或执行其他逻辑。

NativeSegments(
  items: ['Option 1', 'Option 2', 'Option 3'],
  onValueChanged: (int index) {
    print('Selected index: $index');
    // 在这里处理选项变化
  },
)
回到顶部