Flutter自适应选择器插件adaptive_selector的使用

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

Flutter自适应选择器插件adaptive_selector的使用


adaptive_selector


简单且健壮的选择器,适用于所有平台。


开始使用


基本用法
// 创建选项列表
final options = SelectorType.values
  .map((e) => AdaptiveSelectorOption(label: e.name, value: e))
  .toList();

// 应用选项到自适应选择器
AdaptiveSelector(
  options: options,
  initialOption: options.first,
  type: SelectorType.menu,
  allowClear: false,
),
异步选择器
AdaptiveSelector(
  options: asyncOptions,
  decoration: const InputDecoration(
    hintText: 'Select school',
  ),
  loading: loading,
  onSearch: handleSearch,
  hasMoreData: hasMore,
  onLoadMore: handleLoadMore,
),

完整示例

以下是完整的示例代码:

import 'package:adaptive_selector/adaptive_selector.dart';
import 'package:example/selectors/basic_selector.dart';
import 'package:flutter/material.dart';

import 'selectors/custom_selector.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        scaffoldBackgroundColor: Colors.white,
        tabBarTheme: TabBarTheme(
          unselectedLabelColor: Colors.grey[600]!,
          labelColor: Colors.grey[900]!,
          labelStyle: const TextStyle(fontWeight: FontWeight.w700),
        ),
        inputDecorationTheme: InputDecorationTheme(
          isDense: true,
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(10),
            borderSide: const BorderSide(
              color: Colors.grey,
            ),
          ),
          enabledBorder: OutlineInputBorder(
            borderRadius: BorderRadius.circular(10),
            borderSide: const BorderSide(
              color: Colors.grey,
            ),
          ),
          disabledBorder: OutlineInputBorder(
            borderRadius: BorderRadius.circular(10),
            borderSide: BorderSide(
              color: Colors.grey[300]!,
            ),
          ),
          focusedErrorBorder: OutlineInputBorder(
            borderSide: const BorderSide(color: Colors.blue),
            borderRadius: BorderRadius.circular(10),
          ),
          focusedBorder: OutlineInputBorder(
            borderSide: const BorderSide(color: Colors.blue),
            borderRadius: BorderRadius.circular(10),
          ),
        ),
      ),
      home: const Demo(),
    );
  }
}

class Demo extends StatefulWidget {
  const Demo({Key? key}) : super(key: key);

  [@override](/user/override)
  State<Demo> createState() => _DemoState();
}

class _DemoState extends State<Demo> {
  SelectorType selectorType = SelectorType.menu;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: Center(
          child: Container(
            padding: const EdgeInsets.symmetric(horizontal: 16),
            constraints: const BoxConstraints(maxWidth: 800),
            alignment: Alignment.center,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Builder(
                  builder: (context) {
                    return SizedBox(
                      height: MediaQuery.of(context).padding.top + 12,
                    );
                  },
                ),
                Text(
                  'Adaptive selector',
                  style: Theme.of(context)
                      .textTheme
                      .headlineMedium
                      ?.copyWith(color: Colors.grey[800]),
                ),
                const SizedBox(height: 12),
                const Label('Selector type'),
                AdaptiveSelector<SelectorType>(
                  options: SelectorType.values
                      .map(
                        (e) => AdaptiveSelectorOption(
                          label: e.name,
                          value: e,
                        ),
                      )
                      .toList(),
                  type: SelectorType.menu,
                  initial: [
                    AdaptiveSelectorOption(
                      label: SelectorType.menu.name,
                      value: SelectorType.menu,
                    ),
                  ],
                  decoration: const InputDecoration(hintText: 'Select type'),
                  allowClear: false,
                  onChanged: (options) {
                    setState(() {
                      selectorType = options.first.value;
                    });
                  },
                ),
                const Label('Basic'),
                BasicUsage(
                  selectorType: selectorType,
                ),
                CustomSelector(
                  selectorType: selectorType,
                ),
                const SizedBox(height: 32),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class SelectorTile<T> extends StatelessWidget {
  const SelectorTile({
    Key? key,
    required this.option,
    required this.isSelected,
  }) : super(key: key);

  final AdaptiveSelectorOption<T> option;
  final bool isSelected;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Container(
      height: 46,
      alignment: Alignment.centerLeft,
      color: isSelected
          ? Theme.of(context).colorScheme.primary.withOpacity(0.1)
          : null,
      padding: const EdgeInsets.symmetric(horizontal: 16),
      child: Text(
        option.label,
      ),
    );
  }
}

class Label extends StatelessWidget {
  const Label(
    this.data, {
    Key? key,
  }) : super(key: key);

  final String data;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(top: 14, bottom: 6),
      child: Text(
        data,
        style: TextStyle(
          color: Theme.of(context).primaryColor,
          fontSize: 18,
        ),
      ),
    );
  }
}

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

1 回复

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


当然,以下是如何在Flutter中使用adaptive_selector插件的一个简单示例。adaptive_selector插件允许开发者创建一个自适应的选择器,它可以在桌面和移动设备上以不同的方式呈现。

首先,确保你已经在pubspec.yaml文件中添加了adaptive_selector依赖:

dependencies:
  flutter:
    sdk: flutter
  adaptive_selector: ^x.y.z  # 请替换为最新版本号

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

接下来,在你的Flutter应用中,你可以使用AdaptiveSelector组件。下面是一个完整的示例,展示如何在Flutter中使用adaptive_selector

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Adaptive Selector Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Adaptive Selector Example'),
        ),
        body: Center(
          child: AdaptiveSelectorExample(),
        ),
      ),
    );
  }
}

class AdaptiveSelectorExample extends StatefulWidget {
  @override
  _AdaptiveSelectorExampleState createState() => _AdaptiveSelectorExampleState();
}

class _AdaptiveSelectorExampleState extends State<AdaptiveSelectorExample> {
  String selectedValue = 'Option 1';

  @override
  Widget build(BuildContext context) {
    return AdaptiveSelector<String>(
      options: [
        AdaptiveSelectorOption<String>(
          value: 'Option 1',
          child: Text('Option 1'),
        ),
        AdaptiveSelectorOption<String>(
          value: 'Option 2',
          child: Text('Option 2'),
        ),
        AdaptiveSelectorOption<String>(
          value: 'Option 3',
          child: Text('Option 3'),
        ),
      ],
      selectedValue: selectedValue,
      onChanged: (newValue) {
        setState(() {
          selectedValue = newValue;
        });
      },
      isDesktop: MediaQuery.of(context).size.width > 600, // 简单判断是否为桌面设备
    );
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,并在主页面中使用AdaptiveSelector组件。AdaptiveSelector接收以下参数:

  • options:一个AdaptiveSelectorOption列表,每个选项包含一个值和一个子组件。
  • selectedValue:当前选中的值。
  • onChanged:当选中值改变时的回调函数。
  • isDesktop:一个布尔值,用于指示当前设备是否为桌面设备。这里我们使用MediaQuery.of(context).size.width > 600作为简单判断,你可以根据实际需求调整这个逻辑。

AdaptiveSelectorOption是每个选项的配置,包含选项的值和显示的子组件。

运行这个示例,你会看到一个自适应的选择器,它在桌面和移动设备上会以不同的方式呈现。在移动设备上,它可能呈现为一个下拉菜单,而在桌面设备上,它可能呈现为一个弹出菜单或下拉菜单,具体取决于插件的实现和设备的特性。

回到顶部