針對前一個 Web Service Client 和表格呈現資料的範例,增加需要處理狀態更新機制(StatefulWidget)的查詢方塊。
components/post_table_with_search.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:webservice_client/models/post.dart';
// ignore: must_be_immutable
class PostTableWithSearch extends StatefulWidget {
PostTableWithSearch(this.posts, {super.key});
List<Post> posts;
@override
State createState() {
return _PostTableWithSearch();
}
}
class _PostTableWithSearch extends State<PostTableWithSearch> {
String filterInput = '';
List<Post> filteredPosts = [];
void changeFilteredPosts(String userInput) {
filterInput = userInput;
filteredPosts = widget.posts.where(
(element) {
if(userInput == '') {
return true;
}
else if(element.title.contains(userInput)) {
//print(element.title);
return true;
}
else {
return false;
}
},
).toList();
if(filteredPosts.isEmpty) {
filteredPosts.add(Post(0, 0, "查無資料", "查無資料"));
}
}
@override
Widget build(BuildContext context) {
if(filteredPosts.isEmpty) {
changeFilteredPosts('');
}
var searchTextEditingController = TextEditingController()..text = filterInput;
Widget searchBar = TextField(
controller: searchTextEditingController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Enter a search term'
),
onSubmitted: (userInput){
setState(() {
changeFilteredPosts(userInput);
});
},
);
// Convert object variables to data column list
List<String> columnNames = (jsonDecode(filteredPosts[0].toJsonObjectString()) as Map<String, dynamic>).keys.toList();
List<DataColumn> dataColumns = columnNames.map((key) {
return DataColumn(label: Text(key));
},).toList();
// Convert object variables to data row list
List<DataRow> dataRows = filteredPosts.map((post) {
Map<String, dynamic> postJson = jsonDecode(post.toJsonObjectString()) as Map<String, dynamic>;
List<DataCell> dataCells = columnNames.map((key){
return DataCell(
Text(postJson[key].toString()));
}).toList();
return DataRow(cells: dataCells);
},).toList();
return SingleChildScrollView(
child: Container(
alignment: Alignment.topCenter,
child: Column(children: [
SizedBox(
width: 800,
child: searchBar,
),
SizedBox(
width: 800,
child: DataTable(columns: dataColumns, rows: dataRows),
)
]),
),
);
}
}
screen/post_screen.dart
import 'package:flutter/material.dart';
import 'package:webservice_client/components/post_table_with_search.dart';
import 'package:webservice_client/daos/post_dao.dart';
import 'package:webservice_client/models/post.dart';
class PostScreen extends StatefulWidget {
const PostScreen({super.key});
@override
State createState() {
return _PostScreen();
}
}
class _PostScreen extends State<PostScreen> {
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: PostDao.getPosts(),
builder: (BuildContext context, AsyncSnapshot<List<Post>> asyncSnapshot) {
return Scaffold(
body: PostTableWithSearch(asyncSnapshot.requireData),
);
}
);
}
}


Leave a comment