Flutter图书馆管理插件open_library的使用
Flutter图书馆管理插件open_library的使用
open_library
一个实现了openlibrary.org API的Flutter库。
特性
- 使用ISBN从openlibrary.org API获取书籍信息。
- 支持10位和13位ISBN号码。
- 将作者和封面添加到书籍结果对象中。
- 可以轻松地在Flutter中使用内存图像(MemoryImage)作为封面,通过Uint8List传递。
- 支持按书名、作者、ISBN和统一查询进行搜索。
- 新的搜索模式包括主题、地点、人物、语言和出版商。
- 加载封面时可以选择小、中、大尺寸或禁用加载。
示例应用
安装
在你的Flutter项目的pubspec.yaml
文件中,添加以下依赖:
dependencies:
open_library: <latest_version>
在你的库中添加以下导入语句:
import 'package:open_library/open_library.dart';
入门指南
示例代码
import 'package:flutter/material.dart';
import 'package:open_library/open_library.dart';
import 'package:provider/provider.dart';
import 'screens/book_screen.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return Provider(
create: (_) => OpenLibrary(),
dispose: (_, OpenLibrary service) => service.dispose(),
child: MaterialApp(
title: '图书示例',
home: BookScreen()
));
}
}
import 'package:flutter/material.dart';
import 'package:open_library/models/ol_book_model.dart';
import 'package:open_library/models/ol_search_model.dart';
import 'package:open_library/open_library.dart';
import 'package:provider/provider.dart';
const ISBN1 = '9783608980806';
const ISBN2 = '0674995171';
const ISBN3 = '3596191130';
class BookScreen extends StatefulWidget {
BookScreen({Key? key}) : super(key: key);
final List<OLBook> books = [];
[@override](/user/override)
State<BookScreen> createState() => _BookScreenState();
}
class _BookScreenState extends State<BookScreen> {
final TextEditingController controller =
TextEditingController(text: "Lord of the Rings");
late bool isLoading = false;
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueGrey,
body: !isLoading
? Column(
children: [
const SizedBox(height: 50.0),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.6,
height: 60.0,
child: TextField(
controller: controller,
cursorColor: Colors.white,
style: const TextStyle(color: Colors.white),
decoration: const InputDecoration(
label: Text("书名:"),
labelStyle: TextStyle(color: Colors.white),
focusColor: Colors.white,
),
),
),
Padding(
padding: const EdgeInsets.only(left: 10.0),
child: GestureDetector(
onTap: () async {
setState(() {
isLoading = true;
});
final OLSearchBase search =
await Provider.of<OpenLibrary>(context,
listen: false)
.query(q: controller.text, limit: 4);
if (search is OLSearch) {
widget.books.clear();
print("搜索结果:\n$search");
for (var doc in search.docs) {
final OLBook book = OLBook(
title: doc.title,
authors: doc.authors,
covers: doc.covers,
);
widget.books.add(book);
}
}
setState(() {
isLoading = false;
});
},
child: const Icon(
Icons.search,
color: Colors.white,
),
),
),
],
),
const SizedBox(
height: 20.0,
),
const Center(
child: Text(
"点击按钮搜索这些ISBN",
style: TextStyle(color: Colors.white),
)),
const SizedBox(
height: 20.0,
),
const Center(
child: Text(
"ISBN1:$ISBN1",
style: TextStyle(color: Colors.white),
)),
const SizedBox(height: 20.0),
const Center(
child: Text(
"ISBN2:$ISBN2",
style: TextStyle(color: Colors.white),
)),
const SizedBox(height: 20.0),
const Center(
child: Text(
"ISBN3:$ISBN3",
style: TextStyle(color: Colors.white),
)),
const SizedBox(height: 20.0),
SingleChildScrollView(
child: ListView.builder(
shrinkWrap: true,
itemCount: widget.books.length,
itemBuilder: (context, index) {
return bookWidget(
book: widget.books[index], context: context);
},
),
)
],
)
: const Center(child: CircularProgressIndicator(color: Colors.white,)),
floatingActionButton: FloatingActionButton(
onPressed: () async {
setState(() {
isLoading = true;
});
widget.books.clear();
const bool loadCovers = true;
const CoverSize size = CoverSize.S;
final OLBookBase book1 =
await Provider.of<OpenLibrary>(context, listen: false)
.getBookByISBN(
isbn: ISBN1, loadCover: loadCovers, coverSize: size);
print(book1.toString());
if (book1 is OLBook) {
widget.books.add(book1);
}
final OLBookBase book2 =
await Provider.of<OpenLibrary>(context, listen: false)
.getBookByISBN(
isbn: ISBN2, loadCover: loadCovers, coverSize: size);
print(book2.toString());
if (book2 is OLBook) {
widget.books.add(book2);
}
final OLBookBase book3 =
await Provider.of<OpenLibrary>(context, listen: false)
.getBookByISBN(
isbn: ISBN3, loadCover: loadCovers, coverSize: size);
print(book3.toString());
if (book3 is OLBook) {
widget.books.add(book3);
}
setState(() {
isLoading = false;
});
},
child: const Icon(Icons.book),
),
);
}
Widget bookWidget({required OLBook book, required BuildContext context}) {
String author = '';
if (book.authors.isNotEmpty) {
author = book.authors.first.name.trim();
}
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: MediaQuery.of(context).size.width * 0.8,
height: 80.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding:
const EdgeInsets.only(top: 4.0, bottom: 4.0, left: 20.0),
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.6,
child: Text(
book.title,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.black,
fontSize: 14,
fontWeight: FontWeight.bold),
),
),
),
Padding(
padding:
const EdgeInsets.only(top: 4.0, bottom: 4.0, left: 20.0),
child: Text(
author,
style: const TextStyle(color: Colors.black, fontSize: 12),
),
),
],
),
Padding(
padding: const EdgeInsets.only(right: 20.0),
child: SizedBox(
height: book.covers.isNotEmpty ? 64.0 : 0,
child: book.covers.isNotEmpty
? Image.memory(book.covers.first)
: null,
),
),
],
),
),
);
}
}
示例代码
import 'package:flutter/material.dart';
import 'package:open_library/open_library.dart';
import 'screens/book_screen.dart';
import 'package:provider/provider.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return Provider(
create: (_) => OpenLibrary(),
dispose: (_, OpenLibrary ol) => ol.dispose(),
child: MaterialApp(
title: '图书示例',
home: BookScreen()
));
}
}
更多关于Flutter图书馆管理插件open_library的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter图书馆管理插件open_library的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用open_library
插件的示例代码。open_library
是一个假定的插件名称,用于演示目的,因为实际上可能没有一个广泛知名的名为open_library
的Flutter插件专门用于图书馆管理。但我会基于一个类似的假设插件功能来编写代码示例,展示如何集成和使用一个图书管理插件。
首先,你需要确保你的Flutter项目中已经添加了该插件。在pubspec.yaml
文件中添加依赖项(注意:这里open_library
是一个假设的包名,你需要替换为实际的包名):
dependencies:
flutter:
sdk: flutter
open_library: ^x.y.z # 替换为实际的版本号
然后运行flutter pub get
来安装依赖。
接下来,在你的Flutter应用中,你可以按照以下方式使用open_library
插件(假设它提供了图书的增删改查功能):
import 'package:flutter/material.dart';
import 'package:open_library/open_library.dart'; // 导入假设的open_library插件
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Library Management',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: LibraryScreen(),
);
}
}
class LibraryScreen extends StatefulWidget {
@override
_LibraryScreenState createState() => _LibraryScreenState();
}
class _LibraryScreenState extends State<LibraryScreen> {
final OpenLibrary _library = OpenLibrary(); // 实例化插件
List<Book> _books = []; // 用于存储图书列表
@override
void initState() {
super.initState();
_fetchBooks(); // 初始化时获取图书列表
}
Future<void> _fetchBooks() async {
setState(() {
// 显示加载指示器
});
try {
_books = await _library.getBooks(); // 假设getBooks()方法返回图书列表
setState(() {}); // 更新UI
} catch (e) {
print('Error fetching books: $e');
}
}
Future<void> _addBook(String title, String author) async {
Book newBook = Book(title: title, author: author);
try {
await _library.addBook(newBook); // 假设addBook()方法添加新书
_fetchBooks(); // 重新获取图书列表以更新UI
} catch (e) {
print('Error adding book: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Library Management'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
Expanded(
child: _books.isEmpty
? Center(child: CircularProgressIndicator()) // 显示加载指示器如果图书列表为空
: ListView.builder(
itemCount: _books.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_books[index].title),
subtitle: Text(_books[index].author),
);
},
),
),
TextField(
decoration: InputDecoration(labelText: 'Book Title'),
onSubmitted: (title) {
_showAuthorDialog(title);
},
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// 显示一个对话框让用户输入书名和作者
_showTitleDialog();
},
tooltip: 'Add Book',
child: Icon(Icons.add),
),
);
}
Future<void> _showTitleDialog() async {
final TextEditingController _titleController = TextEditingController();
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Enter Book Title'),
content: TextField(
controller: _titleController,
decoration: InputDecoration(labelText: 'Title'),
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('Cancel'),
),
TextButton(
onPressed: () async {
String title = _titleController.text;
if (title.isEmpty) return;
await _showAuthorDialog(title);
Navigator.of(context).pop();
},
child: Text('OK'),
),
],
);
},
);
}
Future<void> _showAuthorDialog(String title) async {
final TextEditingController _authorController = TextEditingController();
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Enter Book Author'),
content: TextField(
controller: _authorController,
decoration: InputDecoration(labelText: 'Author'),
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('Cancel'),
),
TextButton(
onPressed: () async {
String author = _authorController.text;
if (author.isEmpty) return;
await _addBook(title, author);
Navigator.of(context).pop();
},
child: Text('OK'),
),
],
);
},
);
}
}
// 假设的Book类
class Book {
final String title;
final String author;
Book({required this.title, required this.author});
}
// 假设的OpenLibrary类(实际上这个类将由open_library插件提供)
class OpenLibrary {
Future<List<Book>> getBooks() async {
// 这里应该是与后端服务或本地数据库交互的代码
// 为了演示,我们返回一个硬编码的图书列表
return [
Book(title: 'Book One', author: 'Author A'),
Book(title: 'Book Two', author: 'Author B'),
];
}
Future<void> addBook(Book book) async {
// 这里应该是将新书添加到后端服务或本地数据库的代码
// 为了演示,我们不实际添加,只是打印信息
print('Added book: ${book.title} by ${book.author}');
}
}
请注意,上述代码中的OpenLibrary
类和Book
类是基于假设的。在实际使用中,open_library
插件应该会提供这些类或相应的API来管理图书。你需要参考该插件的官方文档来了解具体的API和使用方法。如果open_library
插件实际上存在,并且提供了不同的API,你需要根据插件的文档相应地调整代码。