Flutter中如何通过JSON API从互联网获取数据并填充DataTable?
Hey there! Let's walk through exactly how to fetch data from a JSON API and display it in a Flutter DataTable—this is a super common use case, and I’ll break it down into straightforward, actionable steps.
http Package to Your Project First, you need a reliable way to make network requests. The official http package is the standard here. Open your pubspec.yaml file and add it under dependencies:
dependencies: flutter: sdk: flutter http: ^1.1.0 # Use the latest version available on pub.dev
Run flutter pub get in your terminal to install the package.
Working with raw JSON is messy and error-prone—convert the API response into strongly-typed Dart objects instead. Let’s assume your API returns a list of "products" with fields like id, name, price, and category. Here’s what your model class might look like:
class Product { final int id; final String name; final double price; final String category; Product({ required this.id, required this.name, required this.price, required this.category, }); // Convert JSON data to a Product object factory Product.fromJson(Map<String, dynamic> json) { return Product( id: json['id'], name: json['name'], price: json['price'].toDouble(), category: json['category'], ); } }
Tweak the fields and parsing logic to match your actual API response structure—this is just an example to get you started!
Create an async function to handle network requests and data parsing. We’ll include basic error handling to avoid crashes if the request fails or the JSON is invalid:
import 'dart:convert'; import 'package:http/http.dart' as http; Future<List<Product>> fetchProducts() async { final response = await http.get(Uri.parse('https://your-api-endpoint.com/products')); if (response.statusCode == 200) { // Parse the JSON array into a list of Product objects List<dynamic> jsonProducts = json.decode(response.body); return jsonProducts.map((json) => Product.fromJson(json)).toList(); } else { // Throw an exception if the server returns an error throw Exception('Failed to load products. Status code: ${response.statusCode}'); } }
Don’t forget to import dart:convert for the json.decode method!
FutureBuilder Since fetching data is asynchronous, use FutureBuilder to handle loading, success, and error states gracefully. This widget will automatically rebuild when the data is ready:
class ProductTableScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Product Inventory')), body: FutureBuilder<List<Product>>( future: fetchProducts(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { // Show a loading spinner while data is being fetched return const Center(child: CircularProgressIndicator()); } else if (snapshot.hasError) { // Display an error message if something goes wrong return Center(child: Text('Oops! ${snapshot.error}')); } else if (!snapshot.hasData || snapshot.data!.isEmpty) { // Show an empty state if no data is returned return const Center(child: Text('No products found')); } else { // Data is ready—render the DataTable return SingleChildScrollView( scrollDirection: Axis.horizontal, child: DataTable( border: TableBorder.all(), columns: const [ DataColumn(label: Text('ID'), numeric: true), DataColumn(label: Text('Product Name')), DataColumn(label: Text('Price'), numeric: true), DataColumn(label: Text('Category')), ], rows: snapshot.data!.map((product) { return DataRow(cells: [ DataCell(Text(product.id.toString())), DataCell(Text(product.name)), DataCell(Text('\$${product.price.toStringAsFixed(2)}')), DataCell(Text(product.category)), ]); }).toList(), ), ); } }, ), ); } }
- Horizontal Scrolling: Wrapping the DataTable in
SingleChildScrollViewwithAxis.horizontalensures your table stays usable on small screens. - State Management: For more complex apps (e.g., refreshing data, filtering), use state management tools like Riverpod, Provider, or Bloc instead of a basic FutureBuilder.
- Caching: Cache API responses (with packages like
shared_preferencesor Hive) to reduce redundant network calls and improve offline functionality. - Pagination: If your API returns a large dataset, implement pagination to load data in chunks instead of all at once—this boosts performance.
That’s all you need! Adjust the model, API endpoint, and UI styling to fit your specific project requirements.
内容的提问来源于stack exchange,提问作者user16867349

