Flutter选择组件插件select的使用

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

Flutter选择组件插件select的使用

概述

select 插件为类字段和枚举情况的选择器生成代码,帮助减少重复代码。它适用于Flutter和Dart项目中,特别是在需要频繁使用选择器的场景下,如 Iterable 转换、Stream 转换、Provider的 select 方法等。

安装

使用的包

Pubspec配置

pubspec.yaml 文件中添加以下依赖:

dependencies:
  select_annotation: ^latest_version

dev_dependencies:
  build_runner: ^latest_version
  select: ^latest_version

使用方法

Selectable Class

要为类生成选择器,需要满足两个条件:

  1. 类使用 @selectable 注解。
  2. 文件包含生成的代码,例如 part 'model.select.dart';

示例代码

import 'package:select_annotation/select_annotation.dart';

part 'user.select.dart';

@selectable
class User {
  final String name;
  final int age;

  const User(this.name, this.age);
}

生成的选择器方法如下:

abstract class User$ {
  User$._();

  static String name(User user) => user.name;
  static int age(User user) => user.age;
}

这些选择器可以像普通匿名函数一样使用。

Matchable Enum

为枚举生成匹配扩展的方法如下:

  1. 枚举使用 @matchable 注解。
  2. 文件包含生成的代码,例如 part 'enum.select.dart';

示例代码

@matchable
enum AppTheme {
  light,
  dark,
  system,
}

生成的扩展方法如下:

extension $AppThemeMatcherExtension on AppTheme {
  T when<T>({
    required T Function() light,
    required T Function() dark,
    required T Function() system,
  }) {
    switch (this) {
      case AppTheme.light:
        return light();
      case AppTheme.dark:
        return dark();
      case AppTheme.system:
        return system();
    }
  }

  T whenConst<T>({
    required T light,
    required T dark,
    required T system,
  }) {
    switch (this) {
      case AppTheme.light:
        return light;
      case AppTheme.dark:
        return dark;
      case AppTheme.system:
        return system;
    }
  }
}

示例应用

以下是一个完整的示例应用,展示了如何使用 select 插件:

// ignore_for_file: avoid_print

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:select_annotation/select_annotation.dart';

part 'main.freezed.dart';
part 'main.select.dart';

@selectable
abstract class Named {
  String get firstName;
  String get lastName;
}

@selectable
@immutable
class Directions {
  final String description;

  const Directions({
    required this.description,
  });
}

@selectable
@immutable
class Address {
  final String street;
  final int number;
  final Directions directions;

  const Address({
    required this.street,
    required this.number,
    required this.directions,
  });
}

@selectable
mixin F {
  int get a;
}

@freezed
@selectable
class User with _$User implements Named {
  const factory User({
    required String firstName,
    required String lastName,
    required Address address,
  }) = _User;
}

/// A helper extension that helps compose the selectors.
extension<A, B> on B Function(A) {
  C Function(A) d<C>(C Function(B c) selector) => (A a) => selector(this(a));
}

void selectableAnnotation() {
  const user = User(
    firstName: 'John',
    lastName: 'Doe',
    address: Address(
      street: 'Main Street',
      number: 123,
      directions: Directions(
        description: 'North',
      ),
    ),
  );

  print(Named$.firstName(user)); // 输出: John
  print(Named$.lastName(user));  // 输出: Doe

  print(Address$.street(user.address)); // 输出: Main Street
  print(Address$.number(user.address)); // 输出: 123

  final description =
      User$.address.d(Address$.directions).d(Directions$.description);

  final directions = const [user].map(description).toList();

  print(directions); // 输出: [North]
}

@matchable
enum AppTheme {
  light,
  dark,
  system,
}

void matchableAnnotation() {
  const currentTheme = AppTheme.light;

  final label = currentTheme.whenConst(
    light: 'To light',
    dark: 'To dark',
    system: 'To system',
  );
  print(label); // 输出: To light

  currentTheme.when(
    light: () => print('Theme is light!'),
    dark: () => print('Theme is dark!'),
    system: () => print('Theme is system!'),
  ); // 输出: Theme is light!
}

void main() {
  selectableAnnotation();
  matchableAnnotation();
}

通过上述代码,您可以了解如何在Flutter项目中使用 select 插件来简化选择器的编写,从而提高代码的可读性和维护性。


更多关于Flutter选择组件插件select的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter选择组件插件select的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter中使用select组件插件(通常指dropdown_search或类似的库,因为Flutter官方并没有直接名为select的组件)的示例。为了演示,我将使用dropdown_search库,这是一个非常流行的选择组件插件,支持搜索和选择功能。

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

dependencies:
  flutter:
    sdk: flutter
  dropdown_search: ^1.0.0  # 请检查最新版本号

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

接下来,在你的Flutter项目中,你可以按照以下方式使用DropdownSearch组件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Dropdown Search Example'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: MyDropdownSearch(),
        ),
      ),
    );
  }
}

class MyDropdownSearch extends StatefulWidget {
  @override
  _MyDropdownSearchState createState() => _MyDropdownSearchState();
}

class _MyDropdownSearchState extends State<MyDropdownSearch> {
  String? selectedItem;
  final List<String> items = List<String>.generate(20, (i) => "Item ${i + 1}");

  @override
  Widget build(BuildContext context) {
    return DropdownSearch<String>(
      mode: Mode.BOTTOM_SHEET,
      showSearchBox: true,
      label: "Select an item",
      hint: "Search...",
      searchInputDecoration: InputDecoration(
        prefixIcon: Icon(Icons.search),
        border: OutlineInputBorder(),
      ),
      popupItemBuilder: (context, item) {
        return ListTile(
          title: Text(item),
        );
      },
      onFind: (String? query) async {
        if (query == null || query.isEmpty) {
          return items;
        }
        return items.where((element) {
          final lowerCaseQuery = query!.toLowerCase();
          return element.toLowerCase().contains(lowerCaseQuery);
        }).toList();
      },
      onChanged: (newValue) {
        setState(() {
          selectedItem = newValue;
        });
      },
      selectedItem: selectedItem,
    );
  }
}

在这个示例中:

  1. DropdownSearch<String>:泛型<String>表示这个下拉列表中的项是字符串类型。
  2. mode: Mode.BOTTOM_SHEET:设置下拉列表的模式为底部表单(Bottom Sheet)。
  3. showSearchBox: true:显示搜索框。
  4. labelhint:分别设置标签和提示文本。
  5. searchInputDecoration:用于自定义搜索框的外观。
  6. popupItemBuilder:用于构建下拉列表中的每一项。
  7. onFind:一个异步函数,用于根据查询字符串过滤项。
  8. onChanged:当选中项改变时触发的回调函数。
  9. selectedItem:当前选中的项。

这个示例演示了如何使用dropdown_search库来创建一个支持搜索和选择功能的下拉列表。你可以根据实际需求进一步自定义和扩展这个组件。

回到顶部