首页 > 解决方案 > 为什么 Dismissible 小部件在 MaterialPageRoute 下的工作方式不同?

问题描述

我正在阅读 Flutter 的写你的第一个应用程序,我想我会添加一些额外的东西。所以我开始玩Dismissible小部件,类似于在cookbook中的做法。但是我注意到该小部件放置在MaterialPageRoute. 问题是,itemBuilder一旦我关闭该项目,索引就不会更新,它会在任何删除之前引用旧位置。但是,从主视图中删除项目确实会更新索引。有人能够解释这种行为吗?

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Startup Name Generator',
      home: RandomWords(),
    );
  }
}

class RandomWordsState extends State<RandomWords> {
  final _suggestions = generateWordPairs()
      .map((WordPair pair) => pair.asCamelCase)
      .take(10)
      .toList();
  final _biggerFont = const TextStyle(fontSize: 18.0);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Startup Name Generator'),
        actions: <Widget>[
          IconButton(icon: Icon(Icons.list), onPressed: _pushSaved),
        ],
      ),
      body: _buildSuggestions(),
    );
  }

  Widget _buildSuggestions() {
    return ListView.builder(
        padding: const EdgeInsets.all(16.0),
        itemCount: _suggestions.length,
        itemBuilder: (context, index) {
          final item = _suggestions[index];
          return Dismissible(
              key: Key(item),
              onDismissed: (direction) {
                setState(() {
                  print("MaterialApp index: $index");
                  _suggestions.remove(item);
                });
              },
              background: Container(color: Colors.red),
              child: ListTile(
                title: Text(
                  item,
                  style: _biggerFont,
                ),
              ));
        });
  }

  void _pushSaved() {
    Navigator.of(context).push(
      MaterialPageRoute<void>(
        builder: (BuildContext context) {
          return Scaffold(
              appBar: AppBar(
                title: Text('Saved Suggestions'),
              ),
              body: ListView.builder(
                itemCount: _suggestions.length,
                itemBuilder: (context, index) {
                  final item = _suggestions[index];
                  return Dismissible(
                    key: Key(item),
                    onDismissed: (direction) {
                      setState(() {
                        print("MaterialPageRoute index: $index");
                        _suggestions.remove(item);
                      });
                    },
                    background: Container(color: Colors.red),
                    child: ListTile(title: Text('$item')),
                  );
                },
              ));
        },
      ),
    );
  }
}

class RandomWords extends StatefulWidget {
  @override
  RandomWordsState createState() => RandomWordsState();
}

从主视图中删除项目,从顶部开始,索引反映删除。每次关闭后,顶部项目的索引为 0:

I/flutter ( 8176): MaterialApp index: 0
I/flutter ( 8176): MaterialApp index: 0
I/flutter ( 8176): MaterialApp index: 0

从 MaterialPageRoute 中删除项目,从顶部开始,为所有项目保留索引。每次关闭后,顶部项目都有其原始索引:

I/flutter ( 8176): MaterialPageRoute index: 0
I/flutter ( 8176): MaterialPageRoute index: 1
I/flutter ( 8176): MaterialPageRoute index: 2

标签: flutter

解决方案


即使您明确调用inside ,在您解除项目后,第二个Route也不会重建,并且项目已从. 因此,内存保留原始长度和从主视图传递的项目位置。这就是为什么尽管当您关闭第一项(原始索引为 3)时,您会得到:setState()onDismiss()_saved_suggestions


MaterialPageRoute index: 3


setState您可以通过从主屏幕上删除Dismissible.


推荐阅读