Flutter分页下拉选择插件high_q_paginated_drop_down的使用

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

Flutter分页下拉选择插件high_q_paginated_drop_down的使用

high_q_paginated_drop_down 包中,有三种类型的下拉选择控件:

  1. BasicPaginatedSearchDropdown
  2. PaginatedSearchDropdownFormField
  3. MultiSelectDropDown

注意:不要在多个下拉选择控件中使用相同的控制器。每种类型都包括分页和未来请求。

如果你需要实现分页功能,请使用 BasicPaginatedSearchDropdown.paginated 方法。

示例代码

HighQPaginatedDropdown<int>.paginated(
  requestItemCount: 25, // 每页显示的项目数量
  backgroundDecoration: (child) => InputDecorator(
    decoration: InputDecoration(
      border: OutlineInputBorder(
        borderRadius: BorderRadius.circular(15.0),
      ),
      contentPadding: const EdgeInsets.symmetric(horizontal: 8),
      labelText: 'Pokemons', // 标签文本
    ),
    child: child,
  ),
  hintText: const Text('Search Anime'), // 提示文本
  paginatedRequest: (int page, String? searchText) async {
    final paginatedList = await getAnimeList(page: page, key: searchText);
    return paginatedList?.animeList?.map((e) {
      return MenuItemModel(
        value: e.malId,
        label: e.title ?? '',
        child: Text(
          e.title ?? '',
        ),
      );
    }).toList();
  },
  padding: const EdgeInsets.all(0), // 内边距
  onChanged: (int? value) {
    debugPrint('$value'); // 打印选中的值
  },
  hasTrailingClearIcon: false, // 是否显示清除图标
  trailingIcon: const Icon(
    Icons.arrow_circle_down_outlined,
    color: Colors.red,
  ), // 下拉箭头图标
);

如果你需要同时实现分页和表单验证,请使用 PaginatedSearchDropdownFormField.paginated 方法。

示例代码

HighQPaginatedDropdown<int>.paginated(
  controller: searchableDropdownController, // 控制器
  backgroundDecoration: (child) => InputDecorator(
    decoration: InputDecoration(
      border: OutlineInputBorder(
        borderRadius: BorderRadius.circular(15.0),
      ),
      contentPadding: const EdgeInsets.symmetric(horizontal: 8),
      labelText: 'Pokemons', // 标签文本
    ),
    child: child,
  ),
  hintText: const Text('Search Anime'), // 提示文本
  padding: const EdgeInsets.all(0), // 内边距
  paginatedRequest: (int page, String? searchText) async {
    final paginatedList = await getAnimeList(page: page, key: searchText);
    return paginatedList?.animeList
        ?.map((e) => MenuItemModel(
              value: e.malId,
              label: e.title ?? '',
              child: Text(e.title ?? ''),
            ))
        .toList();
  },
  validator: (val) {
    if (val == null) return 'Can\'t be empty'; // 验证逻辑
    return null;
  },
  onSaved: (val) {
    debugPrint('On save: $val'); // 保存时打印选中的值
  },
);

完整示例

import 'package:example/pagination_model.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:high_q_paginated_drop_down/high_q_paginated_drop_down.dart';

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

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

  final GlobalKey<FormState> formKey = GlobalKey<FormState>();
  final PaginatedSearchDropdownController<Anime> searchableDropdownController1 =
      PaginatedSearchDropdownController<Anime>();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Material App',
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text(
            'Example',
            style: TextStyle(
              color: Colors.white,
            ),
          ),
          backgroundColor: Colors.green,
          centerTitle: true,
        ),
        body: Form(
          key: formKey, // 分配表单键
          child: ListView(
            padding: const EdgeInsets.all(20),
            children: [
              const SizedBox(height: 20),
              FormField<Anime>(
                validator: (value) {
                  if (value == null) {
                    return 'Please select an anime'; // 验证逻辑
                  }
                  return null;
                },
                builder: (FormFieldState<Anime> state) {
                  return HighQPaginatedDropdown<Anime>.paginated(
                    controller: searchableDropdownController1,
                    requestItemCount: 25,
                    width: double.infinity,
                    loadingWidget: const CircularProgressIndicator(
                      color: Colors.green,
                    ),
                    backgroundDecoration: (child) {
                      return InputDecorator(
                        decoration: InputDecoration(
                          border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(15.0),
                          ),
                          contentPadding: const EdgeInsets.symmetric(horizontal: 8),
                          labelText: 'Anime', // 标签文本
                          errorText: state.errorText,
                        ),
                        child: child,
                      );
                    },
                    hintText: const Text('Search Anime'), // 提示文本
                    paginatedRequest: (
                        int page,
                        String? searchText,
                        ) async {
                      final AnimePaginatedList? paginatedList =
                      await getAnimeList(
                        page: page,
                        queryParameters: {
                          'page': page,
                          "q": searchText,
                        },
                      );
                      return paginatedList?.animeList?.map((e) {
                        return MenuItemModel<Anime>(
                          value: e,
                          label: e.title ?? '',
                          child: Text(
                            e.title ?? '',
                            style: const TextStyle(
                              color: Colors.black12,
                            ),
                          ),
                        );
                      }).toList();
                    },
                    padding: const EdgeInsets.all(0), // 内边距
                    onChanged: (Anime? value) {
                      debugPrint('$value'); // 打印选中的值
                      state.didChange(value); // 通知表单字段更改
                    },
                    hasTrailingClearIcon: true, // 是否显示清除图标
                    trailingIcon: const Icon(
                      Icons.arrow_circle_down_outlined,
                      color: Colors.green,
                    ), // 下拉箭头图标
                    searchHintText: 'Hi search for any thing', // 搜索提示文本
                    trailingClearIcon: const Icon(
                      Icons.delete,
                      color: Colors.green,
                    ), // 清除图标
                    searchDelayDuration: const Duration(milliseconds: 800), // 搜索延迟时间
                    leadingIcon: const Icon(
                      Icons.language,
                      color: Colors.green,
                    ), // 前置图标
                    spaceBetweenDropDownAndItemsDialog: 10, // 下拉框与项目对话框之间的间距
                    isEnabled: true, // 是否启用
                    onTapWhileDisableDropDown: () {}, // 点击禁用下拉框时的操作
                    isDialogExpanded: true, // 对话框是否展开
                    paddingValueWhileIsDialogExpanded: 16, // 展开对话框时的内边距值
                    noRecordText: const Text('HJKHJKHJKLJKJH'), // 无记录文本
                  );
                },
              ),
              const SizedBox(height: 50),
              ElevatedButton(
                onPressed: () {
                  if (formKey.currentState?.validate() ?? false) {
                    // 如果表单有效,则执行提交操作
                    if (kDebugMode) {
                      print('Form is valid!');
                    }
                  } else {
                    if (kDebugMode) {
                      print('Form is invalid!');
                    }
                  }
                },
                child: const Text('Submit'), // 提交按钮文本
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Future<AnimePaginatedList?> getAnimeList({
  required int page,
  Map<String, dynamic>? queryParameters,
}) async {
  try {
    String url = "https://api.jikan.moe/v4/anime"; // API URL

    Response<dynamic> response = await Dio()
        .get(
      url,
      queryParameters: queryParameters,
    ).then((value) {
      return value;
    });
    if (response.statusCode != 200) throw Exception(response.statusMessage);
    return AnimePaginatedList.fromJson(response.data);
  } catch (exception) {
    throw Exception(exception);
  }
}

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

1 回复

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


当然,以下是一个关于如何在Flutter中使用high_q_paginated_drop_down插件实现分页下拉选择的示例代码。high_q_paginated_drop_down是一个用于实现分页下拉选择的Flutter插件,特别适合用于处理大量选项的数据加载。

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

dependencies:
  flutter:
    sdk: flutter
  high_q_paginated_drop_down: ^最新版本号

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

接下来,是一个完整的示例代码,展示了如何使用high_q_paginated_drop_down插件:

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

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

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final PaginatedDropDownController<String> controller =
      PaginatedDropDownController();
  List<String> items = [];
  bool isLoading = false;

  @override
  void initState() {
    super.initState();
    controller.addListener(() {
      if (controller.selectedValue != null) {
        print("Selected Value: ${controller.selectedValue}");
      }
    });

    // Fetch initial data
    fetchItems(page: 1);
  }

  Future<void> fetchItems({int page = 1}) async {
    setState(() {
      isLoading = true;
    });

    // Simulate a network call with a delay
    await Future.delayed(Duration(seconds: 1));

    // Mock data fetching (In a real app, replace with actual data fetching logic)
    final newItems = List.generate(
      10, // Number of items per page
      (index) => "Item ${(page - 1) * 10 + index + 1}",
    );

    setState(() {
      if (page == 1) {
        items = newItems;
      } else {
        items = [...items, ...newItems];
      }
      isLoading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Paginated Drop Down Demo'),
      ),
      body: Center(
        child: PaginatedDropDown<String>(
          controller: controller,
          items: items,
          isLoading: isLoading,
          label: 'Select an item',
          hint: 'Please select',
          onPageChange: (page) {
            fetchItems(page: page);
          },
          onChanged: (value) {
            print("Value changed to: $value");
          },
        ),
      ),
    );
  }
}

解释

  1. 依赖添加:确保在pubspec.yaml中添加了high_q_paginated_drop_down依赖。

  2. 控制器PaginatedDropDownController<String>用于管理下拉列表的状态和选项。

  3. 数据加载fetchItems函数模拟了分页数据加载,每页加载10个项目。在实际应用中,你应该替换为从服务器获取数据的逻辑。

  4. UI构建

    • 使用PaginatedDropDown组件来显示分页下拉列表。
    • controller属性绑定到分页下拉控制器。
    • items属性绑定到当前加载的项目列表。
    • isLoading属性指示当前是否正在加载数据。
    • onPageChange回调用于在页码改变时加载新数据。
    • onChanged回调用于处理选项改变事件。

这个示例提供了一个基本的框架,你可以根据自己的需求进行扩展和修改。

回到顶部