- Install
- Set up an editor
- Test drive
- Write your first Flutter app, part 1
- Learn more
- Flutter for Android developers
- Flutter for iOS developers
- Flutter for React Native developers
- Flutter for web developers
- Flutter for Xamarin.Forms developers
- Introduction to declarative UI
- Cookbook
- Codelabs
- Tutorials
- User interface
- Introduction to widgets
- Layouts in Flutter
- Layout tutorial
- Dealing with box constraints
- Adding interactivity to your Flutter app
- Adding assets and images
- Navigation & routing
- Introduction to animations
- Animations overview
- Animations tutorial
- Hero Animations
- Staggered Animations
- Advanced UI
- Slivers
- Taps, drags, and other gestures
- Widget catalog
- Data & backend
- State management
- State management
- Start thinking declaratively
- Differentiate between ephemeral state and app state
- Simple app state management
- List of state management approaches
- JSON and serialization
- Firebase
- Accessibility & internationalization
- Accessibility
- Internationalizing Flutter apps
- Platform integration
- Writing custom platform-specific code
- Packages & plugins
- Using packages
- Developing packages & plugins
- Background processes
- Tools & techniques
- Android Studio / IntelliJ
- Visual Studio Code
- Upgrading Flutter
- Hot reload
- Code formatting
- Debugging Flutter apps
- Using OEM debuggers
- Flutter's build modes
- Testing Flutter apps
- Performance best practices
- Flutter performance profiling
- Creating flavors for Flutter
- Preparing an Android App for Release
- Preparing an iOS App for Release
- Continuous Delivery using fastlane with Flutter
- Bootstrap into Dart
- Inside Flutter
- Platform specific behaviors and adaptations
- Technical Overview
- Technical videos
- FAQ
- Flutter widget index
- Install
- Windows install
- MacOS install
- Linux install
- Set up an editor
- Write your first Flutter app, part 1
- Learn more
- Cupertino (iOS-style) widgets
- Layout widgets
- Animation and motion widgets
- Retrieve the value of a text field
- Basic widgets
- Material Components widgets
- Animate the properties of a Container
- Fade a Widget in and out
- Add a Drawer to a screen
- Displaying SnackBars
- Exporting fonts from a package
- Updating the UI based on orientation
- Using Themes to share colors and font styles
- Using custom fonts
- Working with Tabs
- Building a form with validation
- Create and style a text field
- Focus on a Text Field
- Handling changes to a text field
- Retrieve the value of a text field
- Adding Material Touch Ripples
- Handling Taps
- Implement Swipe to Dismiss
- Display images from the internet
- Fade in images with a placeholder
- Working with cached images
- Basic List
- Create a horizontal list
- Creating a Grid List
- Creating lists with different types of items
- Place a floating app bar above a list
- Working with long lists
- Report errors to a service
- Animating a Widget across screens
- Navigate to a new screen and back
- Navigate with named routes
- Pass arguments to a named route
- Return data from a screen
- Send data to a new screen
- Fetch data from the internet
- Making authenticated requests
- Parsing JSON in the background
- Working with WebSockets
- Persist data with SQLite
- Reading and Writing Files
- Storing key-value data on disk
- Play and pause a video
- Take a picture using the Camera
- An introduction to integration testing
- Performance profiling
- Scrolling
- An introduction to unit testing
- Mock dependencies using Mockito
- An introduction to widget testing
- Finding widgets
- Tapping, dragging and entering text
- Development
- Introduction to widgets
- Layout tutorial
- Dealing with box constraints
- Adding interactivity to your Flutter app
- Adding assets and images
- Navigation & routing
- Navigate to a new screen and back
- Send data to a new screen
- Return data from a screen
- Navigate with named routes
- Animating a Widget across screens
- AnimatedList
- Sample App Catalog
- Animations overview
- Animations tutorial
- Staggered Animations
- Slivers
- Taps, drags, and other gestures
- Accessibility widgets
- Assets, images, and icon widgets
- Async widgets
- Input widgets
- Interaction model widgets
- Painting and effect widgets
- Scrolling widgets
- Styling widgets
- Text widgets
- State management
- Start thinking declaratively
- Differentiate between ephemeral state and app state
- Simple app state management
- List of state management approaches
- JSON and serialization
- Accessibility
- Internationalizing Flutter apps
- Writing custom platform-specific code
- Using packages
- Fetch data from the internet
- Developing packages & plugins
- Background processes
- Android Studio / IntelliJ
- Set up an editor
- Flutter inspector
- Creating Useful Bug Reports
- Visual Studio Code
- Set up an editor
- Upgrading Flutter
- Hot reload
- Code formatting
Fetch data from the internet
Fetching data from the internet is necessary for most apps. Luckily, Dart and Flutter provide tools for this type of work.
Directions
- Add the
http
package - Make a network request using the
http
package - Convert the response into a custom Dart object
- Fetch and Display the data with Flutter
1. Add the http
package
The http
package provides the simplest way to fetch data from the internet.
To install the http
package, you must add it to the dependencies section of the pubspec.yaml
. You can find the latest version of the http package on the Pub site.
dependencies:
http: <latest_version>
2. Make a network request
In this example, you’ll fetch a sample post from the JSONPlaceholder REST API using the http.get() method.
Future<http.Response> fetchPost() {
return http.get('https://jsonplaceholder.typicode.com/posts/1');
}
The http.get()
method returns a Future
that contains a Response
.
Future
is a core Dart class for working with async operations. It is used to represent a potential value or error that will be available at some time in the future.- The
http.Response
class contains the data received from a successful http call.
3. Convert the response into a custom Dart object
While it’s easy to make a network request, working with a raw Future<http.Response>
isn’t very convenient. To make your life easier, convert the http.Response
into a Dart object.
Create a Post
class
First, create a Post
class that contains the data from the network request. It will include a factory constructor that creates a Post
from json.
Converting JSON by hand is only one option. For more information, please see the full article on JSON and serialization.
class Post {
final int userId;
final int id;
final String title;
final String body;
Post({this.userId, this.id, this.title, this.body});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
userId: json['userId'],
id: json['id'],
title: json['title'],
body: json['body'],
);
}
}
Convert the http.Response
to a Post
Now, update the fetchPost
function to return a Future<Post>
. To do so, you’ll need to:
- Convert the response body into a json
Map
with thedart:convert
package. - If the server returns an “OK” response with a status code of 200, convert the json
Map
into aPost
using thefromJson
factory method. - If the server returns an unexpected response, throw an error
Future<Post> fetchPost() async {
final response =
await http.get('https://jsonplaceholder.typicode.com/posts/1');
if (response.statusCode == 200) {
// If server returns an OK response, parse the JSON
return Post.fromJson(json.decode(response.body));
} else {
// If that response was not OK, throw an error.
throw Exception('Failed to load post');
}
}
Hooray! Now you’ve got a function that we can call to fetch a Post from the internet.
4. Fetch and Display the data
In order to fetch the data and display it on screen, you can use the FutureBuilder
widget. The FutureBuilder
Widget comes with Flutter and makes it easy to work with async data sources.
You must provide two parameters:
- The
Future
you want to work with. In this case, call thefetchPost()
function. - A
builder
function that tells Flutter what to render, depending on the state of theFuture
: loading, success, or error.
FutureBuilder<Post>(
future: fetchPost(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.title);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner
return CircularProgressIndicator();
},
);
5. Moving the fetch call out of the build()
method
Although it’s convenient, it’s not recommended to put a call to an API in a build()
method.
Flutter calls the build()
method every time it wants to change anything in the view, and this happens surprisingly often. If you leave the fetch call in your build()
method, you’ll flood the API with unnecessary calls and slow down your app.
Here are some better options so it’ll only hit the API when the page is initially loaded.
Pass it into a StatelessWidget
With this strategy, the parent widget is responsible for calling the fetch method, storing its result, and then passing it to your widget.
class MyApp extends StatelessWidget {
final Future<Post> post;
MyApp({Key key, this.post}) : super(key: key);
You can see a working example of this in the complete example below.
Call it in the lifecycle of a StatefulWidget
’s state
If your widget is stateful, you can call the fetch method in either the initState
or didChangeDependencies
methods.
initState
is called exactly once and then never again. If you want to have the option of reloading the API in response to an InheritedWidget
changing, put the call into the didChangeDependencies
method. See State
for more details.
class _MyAppState extends State<MyApp> {
Future<Post> post;
@override
void initState() {
super.initState();
post = fetchPost();
}
Testing
For information on how to test this functionality, please see the following recipes:
Complete example
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<Post> fetchPost() async {
final response =
await http.get('https://jsonplaceholder.typicode.com/posts/1');
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
return Post.fromJson(json.decode(response.body));
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
class Post {
final int userId;
final int id;
final String title;
final String body;
Post({this.userId, this.id, this.title, this.body});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
userId: json['userId'],
id: json['id'],
title: json['title'],
body: json['body'],
);
}
}
void main() => runApp(MyApp(post: fetchPost()));
class MyApp extends StatelessWidget {
final Future<Post> post;
MyApp({Key key, this.post}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Fetch Data Example'),
),
body: Center(
child: FutureBuilder<Post>(
future: post,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.title);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner
return CircularProgressIndicator();
},
),
),
),
);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论