如何在 Flutter Cupertino 应用程序中制作可重新排序的列表?

问题描述 投票:0回答:1

我需要的是 iOS 风格的 cupertino Flutter 应用程序中的可重新排序列表,非常类似于 iPhone 的提醒应用程序中的列表。

更具体地说,假设我们有以下 flutter 应用程序(也可以在 DartPad 上使用,网址为 https://dartpad.dev/?id=747cba524c081a54a5e36fb2ff5790c8):

import 'package:flutter/cupertino.dart';

void main() {
  runApp(
    CupertinoApp(
      title: 'Cupertino App',
      theme: const CupertinoThemeData(brightness: Brightness.light),
      home: CupertinoPageScaffold(
        navigationBar: const CupertinoNavigationBar(
          middle: Text('Cupertino List'),
        ),
        child: SafeArea(
          child: CupertinoListSection(
            header: const Text('Cupertino Items'),
            children: [
              for (var i = 1; i < 6; i++)
                CupertinoListTile(
                  key: Key('$i'),
                  title: Text('Item $i'),
                ),
            ],
          ),
        ),
      ),
    ),
  );
}

这将创建一个包含 5 个项目的静态列表,名称为项目 1 到项目 6。我希望能够长按一个项目并将其拖动到新位置——就像材料的 ReorderableListView 完成的那样。

ios flutter flutter-cupertino
1个回答
0
投票

感谢您让我在很长一段时间后继续开发 Cupertino 应用程序 :).

这是我的解决方案:

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

  @override
  State<ReorderableListIos> createState() => _ReorderableListIosState();
}

class _ReorderableListIosState extends State<ReorderableListIos> {
  final List<int> generatedIntList =
      List<int>.generate(10, (int index) => index);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ReorderableListView(
        children: [
          for (int currentIndex = 0;
              currentIndex < generatedIntList.length;
              currentIndex += 1)
            ListTile(
                key: Key('$currentIndex'),
                title: Text(' ${generatedIntList[currentIndex]}')),
        ],
        onReorder: (int oldIndex, int newIndex) {
          setState(() {
            if (oldIndex < newIndex) {
              newIndex -= 1;
            }
            final int itemToRemove = generatedIntList.removeAt(oldIndex);
            generatedIntList.insert(newIndex, itemToRemove);
          });
        },
      ),
    );
  }
}

如果你得到一个错误告诉你:

未找到 MaterialLocalizations。

ReorderableListView widgets require MaterialLocalizations to be provided by a Localizations widget ancestor.
The material library uses Localizations to generate messages, labels, and abbreviations.

To introduce a MaterialLocalizations, either use a MaterialApp at the root of your application to include them automatically, or add a Localization widget with a MaterialLocalizations delegate.

尝试将

localizations
添加到您的
CupertinoApp
中,如下所示:

localizationsDelegates: [
      DefaultMaterialLocalizations.delegate,
      DefaultCupertinoLocalizations.delegate,
      DefaultWidgetsLocalizations.delegate,
 ],

将你的主要功能变成这样:

void main() {
  runApp(const CupertinoApp(
    home: ReorderableListIos(),
    localizationsDelegates: [
      DefaultMaterialLocalizations.delegate,
      DefaultCupertinoLocalizations.delegate,
      DefaultWidgetsLocalizations.delegate,
    ],
  ));
}

希望这有帮助!

编辑:为了一些创意,让我们更改拖动手柄的图标: 首先改变

ReorderableListView

ReorderableListView(
  buildDefaultDragHandles: false,
  ...

然后添加尾随

ReorderableDragStartListener
以更改图标:

ListTile(
  key: Key('$currentIndex'),
  title: Text(' ${generatedIntList[currentIndex]}'),
  trailing: ReorderableDragStartListener(
  key: ValueKey<int>(generatedIntList[currentIndex]),
    index: currentIndex,
    child: const Icon(CupertinoIcons.bars),
  ),
)

最终版本:

© www.soinside.com 2019 - 2024. All rights reserved.