我试着做
编写您的第一个 Flutter 应用程序,第 2 部分 Flutter 应用程序第 5 页
我现在有一个关于这个应用程序的问题。我想从该列表 onLongPress 中删除一个条目,如下所示:
onLongPress: () {
setState(() {
_saved.remove(pair);
});
},
Run Code Online (Sandbox Code Playgroud)
这将从列表中删除该项目,但不会更新屏幕。在返回家中并重新打开这条路线时,新项目没有被删除。但是如何在没有用户重新打开页面的情况下触发此页面上的更新。
onLongPress: () {
setState(() {
_saved.remove(pair);
});
},
Run Code Online (Sandbox Code Playgroud)
那是因为您正在创建一个新的 MaterialPageRoute。
尝试这个:
onLongPress: () {
_saved.remove(pair);
Navigator.of(context).pop();
_pushSaved();
},
Run Code Online (Sandbox Code Playgroud)
使用此解决方案,您仍会看到视图发生变化。如果你想防止这种情况发生,你需要一个新的有状态页面,并进行一些重构:
_saved项目成为全球性的(仅针对此示例)_pushSaved方法onPressed用于调用该_pushSaved函数的函数DetailPage而不是_pushSaved方法像这样:
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() => runApp(new MyApp());
// create a global saved set
Set<WordPair> savedGlobal = new Set<WordPair>();
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Startup Name Generator',
home: new RandomWords(),
);
}
}
class RandomWords extends StatefulWidget {
@override
RandomWordsState createState() => new RandomWordsState();
}
class RandomWordsState extends State<RandomWords> {
final List<WordPair> _suggestions = <WordPair>[];
final TextStyle _biggerFont = const TextStyle(fontSize: 18.0);
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: const Text('Startup Name Generator'),
actions: <Widget>[
// change the onPressed function
new IconButton(icon: const Icon(Icons.list), onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPage()
)
);
}),
],
),
body: _buildSuggestions(),
);
}
Widget _buildSuggestions() {
return new ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (BuildContext _context, int i) {
if (i.isOdd) {
return const Divider();
}
final int index = i ~/ 2;
if (index >= _suggestions.length) {
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
});
}
Widget _buildRow(WordPair pair) {
final bool alreadySaved = savedGlobal.contains(pair);
return new ListTile(
title: new Text(
pair.asPascalCase,
style: _biggerFont,
),
trailing: new Icon(
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
),
onTap: () {
setState(() {
if (alreadySaved) {
savedGlobal.remove(pair);
} else {
savedGlobal.add(pair);
}
});
},
);
}
}
// add a new stateful page
class DetailPage extends StatefulWidget {
@override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
final TextStyle _biggerFont = const TextStyle(fontSize: 18.0);
@override
Widget build(BuildContext context) {
Iterable<ListTile> tiles = savedGlobal.map((WordPair pair) {
return new ListTile(
onLongPress: () {
setState(() {
savedGlobal.remove(pair);
});
},
title: new Text(
pair.asPascalCase,
style: _biggerFont,
),
);
});
final List<Widget> divided = ListTile.divideTiles(
context: context,
tiles: tiles,
).toList();
return new Scaffold(
appBar: new AppBar(
title: const Text('Saved Suggestions'),
),
body: new ListView(children: divided),
);
}
}
Run Code Online (Sandbox Code Playgroud)
2019-11月最新方式
更多信息https://www.youtube.com/watch?v=iEMgjrfuc58
ListView.builder/GridView.builder(
itemBuilder: (BuildContext context, int index){
return Dismissible(
key: Key(selectServiceLocations[index].toString()),
onDismissed: (direction) {
setState(() {
selectServiceLocations.removeAt(index);
});
},
child: Container(...)
}
)
Run Code Online (Sandbox Code Playgroud)
小智 6
虽然有点晚了,但我发现如果你想操作 ListView 或 GridView,最重要的是为 List/GridView 的每个子 Widget 分配一个 Key
简而言之,Flutter 仅按类型而不是状态来比较小部件。因此,当 List/GridView 中表示的列表的状态发生更改时,Flutter 不知道应该删除哪些子项,因为它们的类型仍然相同并进行检查。Flutter 遇到的唯一问题是项目数量,这就是为什么它只删除 List/GridView 中的最后一个小部件。
因此,如果您想在 Flutter 中操作列表,请为每个子组件的顶级组件分配一个 Key。本文提供了更详细的解释。
这可以通过添加来实现
return GridView.count(
shrinkWrap: true,
crossAxisCount: 2,
crossAxisSpacing: 5.0,
mainAxisSpacing: 5.0,
children: List.generate(urls.length, (index) {
//generating tiles with from list
return GestureDetector(
key: UniqueKey(), //This made all the difference for me
onTap: () => {
setState(() {
currentUrls.removeAt(index);
})
},
child: FadeInImage( // A custom widget I made to display an Image from
image: NetworkImage(urls[index]),
placeholder: AssetImage('assets/error_loading.png')
),
);
}),
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
28140 次 |
| 最近记录: |