添加到收藏夹是许多应用程序中的普遍功能。它使用户能够标记或保存图像、地址、链接或其他内容,以便日后参考。在本文中,我们将看到如何实现收藏夹 或在flutter应用程序中添加到收藏夹功能。本文列出了两种方法。在第一种方法中,我们将添加一个简单的(无状态小部件)图标,该图标可在点击时更改颜色,以标记卡片以供将来参考。在第二个示例中,我们将实现一个相对复杂的收藏功能,该功能将涉及StateFul 小部件,将数据保存在一个集合中,然后将其显示在另一个屏幕上。
1.在第一种方法中,我们将在卡片上添加心形按钮,点击后会改变颜色,以将卡片标记为收藏或不收藏。
在主屏幕上制作卡片:
我们要做的第一件事就是制作一张漂亮的卡片。你可以看看这篇文章,了解如何使用flutter Card 小部件。
Dart
//Code snippet of a card widget//
/** Card Widget **/
child: Card(
elevation: 50,
shadowColor: Colors.black,
color: Colors.greenAccent[100],
child: SizedBox(
width: 300,
height: 500,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
CircleAvatar(
backgroundColor: Colors.green[500],
radius: 108,
child: CircleAvatar(
backgroundImage: NetworkImage(
"https://pbs.twimg.com/profile_images/1304985167476523008/QNHrwL2q_400x400.jpg"),
//NetworkImage
radius: 100,
), //CircleAvatar
), //CirclAvatar
SizedBox(
height: 10,
), //SizedBox
Text(
'GeeksforGeeks',
style: TextStyle(
fontSize: 30,
color: Colors.green[900],
fontWeight: FontWeight.w500,
), //Textstyle
), //Text
SizedBox(
height: 10,
), //SizedBox
Text(
'GeeksforGeeks is a computer science portal
for geeks at geeksforgeeks.org. It contains
well written, well thought and well explained
computer science and programming articles,
quizzes, projects, interview experienxes
and much more!!',
style: TextStyle(
fontSize: 15,
color: Colors.green[900],
), //Textstyle
), //Text
SizedBox(
height: 10,
), //SizedBox
SizedBox(
width: 80,
child: RaisedButton(
onPressed: () => null,
color: Colors.green,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Row(
children: [
Icon(Icons.touch_app),
Text('Visit'),
],
), //Row
), //Padding
), //RaisedButton
) //SizedBox
],
), //Column
), //Padding
), //SizedBox
), //Card
Dart
//*Code sinpet of the body*//
body: SingleChildScrollView(
padding: EdgeInsets.only(left: 0, right: 0, top: 20, bottom: 20),
child: Center(
/** Card Widget **/
child: Column(
children: [
//Card 1
Card(
...
),//Card 1
SizedBox(
height: 20,
),
Card(
...
),//Card
), //Center
), //Scaffold
Dart
import 'package:flutter/material.dart';
import 'package:favorite_button/favorite_button.dart';
// importing dependencies
void main() {
runApp(
/**Our App Widget Tree Starts Here**/
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('GeeksforGeeks'),
backgroundColor: Colors.greenAccent[400],
centerTitle: true,
), //AppBar
body: SingleChildScrollView(
padding: EdgeInsets.only(left: 0, right: 0, top: 20, bottom: 20),
child: Center(
/** Card Widget **/
child: Column(
children: [
//Card 1
Card(
elevation: 50,
shadowColor: Colors.black,
color: Colors.greenAccent[100],
child: SizedBox(
width: 310,
height: 510,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
CircleAvatar(
backgroundColor: Colors.green[500],
radius: 108,
child: CircleAvatar(
backgroundImage: NetworkImage(
"https://pbs.twimg.com/profile_images/1304985167476523008/QNHrwL2q_400x400.jpg"),
//NetworkImage
radius: 100,
), //CircleAvatar
), //CirclAvatar
SizedBox(
height: 10,
), //SizedBox
Text(
'GeeksforGeeks',
style: TextStyle(
fontSize: 30,
color: Colors.green[900],
fontWeight: FontWeight.w500,
), //Textstyle
), //Text
SizedBox(
height: 10,
), //SizedBox
Text(
'GeeksforGeeks is a computer science portalfor geeks
at geeksforgeeks.org. It contains well written,
well thought and well explained computer science
and programming articles, quizzes, projects,
interview experienxes and much more!!',
style: TextStyle(
fontSize: 15,
color: Colors.green[900],
), //Textstyle
), //Text
SizedBox(
height: 10,
), //SizedBox
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 100,
child: RaisedButton(
onPressed: () => null,
color: Colors.green,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Row(
children: [
Icon(Icons.touch_app),
Text('Visit'),
],
), //Row
), //Padding
), //RaisedButton
),
// Favourite Button
FavoriteButton(
isFavorite: false,
valueChanged: (_isFavorite) {
print('Is Favorite : $_isFavorite');
},
),
],
), //SizedBox
],
), //Column
), //Padding
), //SizedBox
),
SizedBox(
height: 20,
),
// Card 2
Card(
elevation: 50,
shadowColor: Colors.black,
color: Colors.yellowAccent[100],
child: SizedBox(
width: 310,
height: 510,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
CircleAvatar(
backgroundColor: Colors.yellow[700],
radius: 108,
child: CircleAvatar(
backgroundImage: NetworkImage(
"https://pbs.twimg.com/profile_images/1304985167476523008/QNHrwL2q_400x400.jpg"),
//NetworkImage
radius: 100,
), //CircleAvatar
), //CirclAvatar
SizedBox(
height: 10,
), //SizedBox
Text(
'GeeksforGeeks',
style: TextStyle(
fontSize: 30,
color: Colors.yellow[900],
fontWeight: FontWeight.w500,
), //Textstyle
), //Text
SizedBox(
height: 10,
), //SizedBox
Text(
'GeeksforGeeks is a computer science portalfor geeks
at geeksforgeeks.org. It contains well written,
well thought and well explained computer science
and programming articles, quizzes, projects,
interview experienxes and much more!!',
style: TextStyle(
fontSize: 15,
color: Colors.yellow[900],
), //Textstyle
), //Text
SizedBox(
height: 10,
), //SizedBox
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 100,
child: RaisedButton(
onPressed: () => null,
color: Colors.yellow[600],
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Row(
children: [
Icon(Icons.touch_app),
Text('Visit'),
],
), //Row
), //Padding
), //RaisedButton
),
// Favourite Button
FavoriteButton(
isFavorite: true,
valueChanged: (_isFavorite) {
print('Is Favorite : $_isFavorite');
},
),
],
), //SizedBox
],
), //Column
), //Padding
), //SizedBox
),
],
), //Card
),
), //Center
), //Scaffold
) //MaterialApp
);
}
Dart
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
//importing dependencies
void main() => runApp(MyApp());
//inictating app build
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(primaryColor: Colors.green),
home: RandWords(),
debugShowCheckedModeBanner: false,
);
}
}
Dart
class RandWords extends StatefulWidget {
@override
RandWordsState createState() => RandWordsState();
}
class RandWordsState extends State {
final _randomWordPairs = [];
final _addWordPairs = Set();
Widget _buildList() {
return ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (context, item) {
if (item.isEven) return Divider();
final index = item ~/ 2;
if (index >= _randomWordPairs.length) {
_randomWordPairs.addAll(generateWordPairs().take(10));
}
return _buildRow(_randomWordPairs[index]);
},
);
}
Dart
Widget _buildRow(WordPair pair) {
final alreadyadd = _addWordPairs.contains(pair);
// word-pair tile
return ListTile(
title: Text(pair.asPascalCase, style: TextStyle(fontSize: 18.0)),
trailing: Icon(alreadyadd ? Icons.check : Icons.add,
color: alreadyadd ? Colors.green : null),
onTap: () {
setState(() {
if (alreadyadd) {
_addWordPairs.remove(pair);
} else {
_addWordPairs.add(pair);
}
});
});
}
Dart
void _pushadd() => Navigator.of(context)
.push(MaterialPageRoute(builder: (BuildContext context) {
final Iterable tiles = _addWordPairs.map((WordPair pair) {
return ListTile(
title: Text(pair.asPascalCase, style: TextStyle(fontSize: 16.0)));
});
final List divided =
ListTile.divideTiles(context: context, tiles: tiles).toList();
// saved word-pair page
return Scaffold(
appBar: AppBar(title: Text('Saved Word-Pairs')),
body: ListView(children: divided));
}));//MaterialPageRoute
Dart
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
// importing dependencies
void main() => runApp(MyApp());
// inictating app build
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(primaryColor: Colors.green),
home: RandWords(),
debugShowCheckedModeBanner: false,
);
}
}
class RandWords extends StatefulWidget {
@override
RandWordsState createState() => RandWordsState();
}
class RandWordsState extends State {
final _randomWordPairs = [];
final _addWordPairs = Set();
Widget _buildList() {
return ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (context, item) {
if (item.isEven) return Divider();
final index = item ~/ 2;
if (index >= _randomWordPairs.length) {
_randomWordPairs.addAll(generateWordPairs().take(10));
}
return _buildRow(_randomWordPairs[index]);
},
);
}
Widget _buildRow(WordPair pair) {
final alreadyadd = _addWordPairs.contains(pair);
// word-pair tile
return ListTile(
title: Text(pair.asPascalCase, style: TextStyle(fontSize: 18.0)),
trailing: Icon(alreadyadd ? Icons.check : Icons.add,
color: alreadyadd ? Colors.green : null),
onTap: () {
setState(() {
if (alreadyadd) {
_addWordPairs.remove(pair);
} else {
_addWordPairs.add(pair);
}
});
});
}
void _pushadd() => Navigator.of(context)
.push(MaterialPageRoute(builder: (BuildContext context) {
final Iterable tiles = _addWordPairs.map((WordPair pair) {
return ListTile(
title: Text(pair.asPascalCase, style: TextStyle(fontSize: 16.0)));
});
final List divided =
ListTile.divideTiles(context: context, tiles: tiles).toList();
// saved word-pair page
return Scaffold(
appBar: AppBar(title: Text('Saved Word-Pairs')),
body: ListView(children: divided));
}));
// home page
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text('GeeksforGeeks Word-Pair Generator'),
actions: [
IconButton(icon: Icon(Icons.menu_book), onPressed: _pushadd)
],
),
body: _buildList());
}
这是卡片小部件的代码片段,看起来像这样。有关相同的完整更多信息,请参阅本文。
使屏幕可滚动:
现在我们将通过用SingleChild ScrollView包裹flutter应用程序的主体来使屏幕可滚动,并在由SizedBox分隔的第一个卡片下方创建另一张卡片。
Dart
//*Code sinpet of the body*//
body: SingleChildScrollView(
padding: EdgeInsets.only(left: 0, right: 0, top: 20, bottom: 20),
child: Center(
/** Card Widget **/
child: Column(
children: [
//Card 1
Card(
...
),//Card 1
SizedBox(
height: 20,
),
Card(
...
),//Card
), //Center
), //Scaffold
在完成我们需要的所有这些之后,实现最喜欢的功能。
添加最喜欢的功能:
上述应用程序的主体在SingleChildScrollView 中包含两张卡片。现在要应用上面显示的最喜欢的功能,我们需要在pubspec 中添加以下代码。 yaml文件。
dependencies:
favorite_button: ^0.0.3
这会将收藏按钮包添加到我们的应用程序中。这个包是一个库,它允许开发人员在flutter应用程序中实现带有动画的心形或星形收藏夹按钮。
使用这个包非常简单,心形按钮的代码是这样的:
FavouriteButton(
isFavorite: true,
valueChanged: (_isFavourite) {
print('Is Favourite $_isFavourite)');
},
),
如果我们想要取消选择按钮,我们可以将isFavourite参数设置为 false。
这是应用程序的最终代码。
Dart
import 'package:flutter/material.dart';
import 'package:favorite_button/favorite_button.dart';
// importing dependencies
void main() {
runApp(
/**Our App Widget Tree Starts Here**/
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('GeeksforGeeks'),
backgroundColor: Colors.greenAccent[400],
centerTitle: true,
), //AppBar
body: SingleChildScrollView(
padding: EdgeInsets.only(left: 0, right: 0, top: 20, bottom: 20),
child: Center(
/** Card Widget **/
child: Column(
children: [
//Card 1
Card(
elevation: 50,
shadowColor: Colors.black,
color: Colors.greenAccent[100],
child: SizedBox(
width: 310,
height: 510,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
CircleAvatar(
backgroundColor: Colors.green[500],
radius: 108,
child: CircleAvatar(
backgroundImage: NetworkImage(
"https://pbs.twimg.com/profile_images/1304985167476523008/QNHrwL2q_400x400.jpg"),
//NetworkImage
radius: 100,
), //CircleAvatar
), //CirclAvatar
SizedBox(
height: 10,
), //SizedBox
Text(
'GeeksforGeeks',
style: TextStyle(
fontSize: 30,
color: Colors.green[900],
fontWeight: FontWeight.w500,
), //Textstyle
), //Text
SizedBox(
height: 10,
), //SizedBox
Text(
'GeeksforGeeks is a computer science portalfor geeks
at geeksforgeeks.org. It contains well written,
well thought and well explained computer science
and programming articles, quizzes, projects,
interview experienxes and much more!!',
style: TextStyle(
fontSize: 15,
color: Colors.green[900],
), //Textstyle
), //Text
SizedBox(
height: 10,
), //SizedBox
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 100,
child: RaisedButton(
onPressed: () => null,
color: Colors.green,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Row(
children: [
Icon(Icons.touch_app),
Text('Visit'),
],
), //Row
), //Padding
), //RaisedButton
),
// Favourite Button
FavoriteButton(
isFavorite: false,
valueChanged: (_isFavorite) {
print('Is Favorite : $_isFavorite');
},
),
],
), //SizedBox
],
), //Column
), //Padding
), //SizedBox
),
SizedBox(
height: 20,
),
// Card 2
Card(
elevation: 50,
shadowColor: Colors.black,
color: Colors.yellowAccent[100],
child: SizedBox(
width: 310,
height: 510,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
CircleAvatar(
backgroundColor: Colors.yellow[700],
radius: 108,
child: CircleAvatar(
backgroundImage: NetworkImage(
"https://pbs.twimg.com/profile_images/1304985167476523008/QNHrwL2q_400x400.jpg"),
//NetworkImage
radius: 100,
), //CircleAvatar
), //CirclAvatar
SizedBox(
height: 10,
), //SizedBox
Text(
'GeeksforGeeks',
style: TextStyle(
fontSize: 30,
color: Colors.yellow[900],
fontWeight: FontWeight.w500,
), //Textstyle
), //Text
SizedBox(
height: 10,
), //SizedBox
Text(
'GeeksforGeeks is a computer science portalfor geeks
at geeksforgeeks.org. It contains well written,
well thought and well explained computer science
and programming articles, quizzes, projects,
interview experienxes and much more!!',
style: TextStyle(
fontSize: 15,
color: Colors.yellow[900],
), //Textstyle
), //Text
SizedBox(
height: 10,
), //SizedBox
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 100,
child: RaisedButton(
onPressed: () => null,
color: Colors.yellow[600],
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Row(
children: [
Icon(Icons.touch_app),
Text('Visit'),
],
), //Row
), //Padding
), //RaisedButton
),
// Favourite Button
FavoriteButton(
isFavorite: true,
valueChanged: (_isFavorite) {
print('Is Favorite : $_isFavorite');
},
),
],
), //SizedBox
],
), //Column
), //Padding
), //SizedBox
),
],
), //Card
),
), //Center
), //Scaffold
) //MaterialApp
);
}
输出:
2 .与前一个示例相比,第二个示例稍微复杂一些。在这个应用程序中是一个词对生成器。在每个单词对的前面,有一个添加图标,每次点击时都会变成绿色的复选图标,此外,单词对还会保存在另一个屏幕中。
获取依赖:
在这个flutter应用程序中,我们在列表磁贴上生成随机词对。下面给出了我们用来获取随机英文单词的flutter包。下面给出的代码需要添加到依赖项部分的pubspec.yaml文件中。
english_words: ^3.1.5
入门:
Dart
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
//importing dependencies
void main() => runApp(MyApp());
//inictating app build
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(primaryColor: Colors.green),
home: RandWords(),
debugShowCheckedModeBanner: false,
);
}
}
上面的代码片段将在我们的 main.js 文件中导入依赖项(材料设计库和英文单词库) 。 dart文件并启动应用程序构建。将构建的应用程序是一个材料应用程序,在最后一行中,调试横幅设置为消失。
创建 StateFul 小部件:
Dart
class RandWords extends StatefulWidget {
@override
RandWordsState createState() => RandWordsState();
}
class RandWordsState extends State {
final _randomWordPairs = [];
final _addWordPairs = Set();
Widget _buildList() {
return ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (context, item) {
if (item.isEven) return Divider();
final index = item ~/ 2;
if (index >= _randomWordPairs.length) {
_randomWordPairs.addAll(generateWordPairs().take(10));
}
return _buildRow(_randomWordPairs[index]);
},
);
}
在上面的代码中,类RandWordsState正在维护RandWords类的状态。现在RandWordsState类将负责大部分应用程序逻辑。在RandWordsState类中,我们有两个列表,第一个用于随机词对,第二个用于保存词对。之后在 build 方法中,我们将生成一个ListView小部件。 itemBuilder函数为生成的每个单词调用,如果是的话, ListView小部件也被分隔符分隔。之后,我们将两个随机单词配对形成一个单词对,当我们到达单词的末尾时,每次都会生成十个新的单词对。
最喜欢的功能:
让我们看看最喜欢的功能是如何工作的。
Dart
Widget _buildRow(WordPair pair) {
final alreadyadd = _addWordPairs.contains(pair);
// word-pair tile
return ListTile(
title: Text(pair.asPascalCase, style: TextStyle(fontSize: 18.0)),
trailing: Icon(alreadyadd ? Icons.check : Icons.add,
color: alreadyadd ? Colors.green : null),
onTap: () {
setState(() {
if (alreadyadd) {
_addWordPairs.remove(pair);
} else {
_addWordPairs.add(pair);
}
});
});
}
上面的代码片段生成了单词对的列表图块,检查单词是否已保存在列表中以指定图标。并且有一个点击函数,可以从集合中添加或删除单词对,并将图标更改为绿色检查是否已经从苍白的添加图标中保存。
生成新屏幕:
Dart
void _pushadd() => Navigator.of(context)
.push(MaterialPageRoute(builder: (BuildContext context) {
final Iterable tiles = _addWordPairs.map((WordPair pair) {
return ListTile(
title: Text(pair.asPascalCase, style: TextStyle(fontSize: 16.0)));
});
final List divided =
ListTile.divideTiles(context: context, tiles: tiles).toList();
// saved word-pair page
return Scaffold(
appBar: AppBar(title: Text('Saved Word-Pairs')),
body: ListView(children: divided));
}));//MaterialPageRoute
上面的代码片段生成的屏幕中列出了单词对和ListTile ,取自之前添加的集合。
完整的源代码:
Dart
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
// importing dependencies
void main() => runApp(MyApp());
// inictating app build
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(primaryColor: Colors.green),
home: RandWords(),
debugShowCheckedModeBanner: false,
);
}
}
class RandWords extends StatefulWidget {
@override
RandWordsState createState() => RandWordsState();
}
class RandWordsState extends State {
final _randomWordPairs = [];
final _addWordPairs = Set();
Widget _buildList() {
return ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (context, item) {
if (item.isEven) return Divider();
final index = item ~/ 2;
if (index >= _randomWordPairs.length) {
_randomWordPairs.addAll(generateWordPairs().take(10));
}
return _buildRow(_randomWordPairs[index]);
},
);
}
Widget _buildRow(WordPair pair) {
final alreadyadd = _addWordPairs.contains(pair);
// word-pair tile
return ListTile(
title: Text(pair.asPascalCase, style: TextStyle(fontSize: 18.0)),
trailing: Icon(alreadyadd ? Icons.check : Icons.add,
color: alreadyadd ? Colors.green : null),
onTap: () {
setState(() {
if (alreadyadd) {
_addWordPairs.remove(pair);
} else {
_addWordPairs.add(pair);
}
});
});
}
void _pushadd() => Navigator.of(context)
.push(MaterialPageRoute(builder: (BuildContext context) {
final Iterable tiles = _addWordPairs.map((WordPair pair) {
return ListTile(
title: Text(pair.asPascalCase, style: TextStyle(fontSize: 16.0)));
});
final List divided =
ListTile.divideTiles(context: context, tiles: tiles).toList();
// saved word-pair page
return Scaffold(
appBar: AppBar(title: Text('Saved Word-Pairs')),
body: ListView(children: divided));
}));
// home page
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text('GeeksforGeeks Word-Pair Generator'),
actions: [
IconButton(icon: Icon(Icons.menu_book), onPressed: _pushadd)
],
),
body: _buildList());
}
输出: