面试题答案
一键面试1. 数据请求
使用 Future
来处理数据请求。可以封装一个函数,例如 fetchProductData
,它接收筛选条件(如价格范围、商品类别等)作为参数,并返回一个 Future
。在这个函数内部,使用 http
或其他网络请求库向服务器发送请求。
import 'package:http/http.dart' as http;
import 'dart:convert';
Future<List<dynamic>> fetchProductData({
double? minPrice,
double? maxPrice,
String? category,
}) async {
// 构建请求URL
Uri url = Uri.parse('https://your-server-url/api/products');
Map<String, String> queryParameters = {};
if (minPrice != null) queryParameters['minPrice'] = minPrice.toString();
if (maxPrice != null) queryParameters['maxPrice'] = maxPrice.toString();
if (category != null) queryParameters['category'] = category;
url = url.replace(queryParameters: queryParameters);
// 发送请求
http.Response response = await http.get(url);
if (response.statusCode == 200) {
return json.decode(response.body);
} else {
throw Exception('Failed to load products');
}
}
2. 错误处理
在 fetchProductData
函数中,如果请求失败(状态码非200),抛出异常。在调用这个 Future
的地方,使用 try - catch
块来捕获异常并处理。
try {
List<dynamic> products = await fetchProductData(minPrice: 10, maxPrice: 100, category: 'electronics');
// 处理成功获取的数据,更新UI
} catch (e) {
// 处理错误,提示用户
print('Error: $e');
}
3. UI更新机制
使用 StatefulWidget
来管理UI状态。在 State
类中定义一个变量来存储商品列表数据。当数据请求成功时,更新这个变量,并调用 setState
方法来通知Flutter框架重新构建UI。
class ProductListPage extends StatefulWidget {
@override
_ProductListPageState createState() => _ProductListPageState();
}
class _ProductListPageState extends State<ProductListPage> {
List<dynamic> _products = [];
bool _isLoading = false;
@override
void initState() {
super.initState();
_fetchProducts();
}
Future<void> _fetchProducts() async {
setState(() {
_isLoading = true;
});
try {
List<dynamic> products = await fetchProductData(minPrice: 10, maxPrice: 100, category: 'electronics');
setState(() {
_products = products;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
});
// 可以在这里弹出一个对话框提示用户网络波动等错误
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Network error: $e')));
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Product List')),
body: _isLoading
? Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: _products.length,
itemBuilder: (context, index) {
// 构建商品列表项
return ListTile(title: Text(_products[index]['name']));
},
),
);
}
}
4. 使用Stream处理网络波动
可以使用 Stream
来监听网络状态变化。引入 connectivity_plus
库来获取网络连接状态。
import 'package:connectivity_plus/connectivity_plus.dart';
class NetworkMonitor {
static final NetworkMonitor _instance = NetworkMonitor._();
late StreamSubscription<ConnectivityResult> _subscription;
final StreamController<ConnectivityResult> _controller = StreamController<ConnectivityResult>.broadcast();
NetworkMonitor._() {
_subscription = Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
_controller.add(result);
});
}
Stream<ConnectivityResult> get networkStream => _controller.stream;
void dispose() {
_subscription.cancel();
_controller.close();
}
}
在 ProductListPage
中监听这个 Stream
,当网络状态变化时进行相应处理。
class _ProductListPageState extends State<ProductListPage> {
//... 其他代码
@override
void initState() {
super.initState();
_fetchProducts();
NetworkMonitor().networkStream.listen((ConnectivityResult result) {
if (result == ConnectivityResult.none) {
// 网络断开,提示用户
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Network disconnected')));
} else {
// 网络恢复,重新获取数据
_fetchProducts();
}
});
}
@override
void dispose() {
NetworkMonitor().dispose();
super.dispose();
}
//... 其他代码
}
通过以上步骤,利用Flutter的异步操作(Future
)与 Stream
实现了电商应用中商品列表筛选、数据请求、错误处理以及UI更新机制,并处理了网络波动情况。