Flutter商城结算页面开发:地址选择、支付方式选择、订单提交
以下是结算页面的代码示例:
import 'package:flutter/material.dart';
import 'package:your_app/api_service.dart';
import 'package:your_app/models/address_model.dart';
class CheckoutPage extends StatefulWidget {
@override
_CheckoutPageState createState() => _CheckoutPageState();
}
class _CheckoutPageState extends State<CheckoutPage> {
List<AddressModel> _addressList = [];
AddressModel _selectedAddress;
bool _isAddingAddress = false;
final TextEditingController _nameController = TextEditingController();
final TextEditingController _phoneController = TextEditingController();
final TextEditingController _provinceController = TextEditingController();
final TextEditingController _cityController = TextEditingController();
final TextEditingController _districtController = TextEditingController();
final TextEditingController _addressLineController = TextEditingController();
void _getAddressList() async {
List<AddressModel> addressList = [];
try {
List<Map<String, dynamic>> jsonData = await ApiService.getAddresses();
jsonData.forEach((addressData) => addressList.add(AddressModel.fromJson(addressData)));
setState(() {
_addressList = addressList;
if (_addressList.isNotEmpty) {
_selectedAddress = _addressList.firstWhere((address) => address.isDefault);
}
});
} catch (e) {
// handle error
}
}
void _submitOrder() async {
try {
String result = await ApiService.submitOrder(_selectedAddress.id, '支付宝');
List<dynamic> data = jsonDecode(result);
// handle response data
} catch (e) {
// handle error
}
}
void _addAddress() async {
setState(() {
_isAddingAddress = true;
});
try {
String result = await ApiService.saveAddress(
addressId: '',
province: _provinceController.text,
city: _cityController.text,
district: _districtController.text,
addressLine: _addressLineController.text,
phone: _phoneController.text,
isDefault: 1,
name: _nameController.text,
);
// handle response data
_getAddressList();
} catch (e) {
// handle error
} finally {
setState(() {
_isAddingAddress = false;
});
}
}
@override
void initState() {
super.initState();
_getAddressList();
}
@override
void dispose() {
_nameController.dispose();
_phoneController.dispose();
_provinceController.dispose();
_cityController.dispose();
_districtController.dispose();
_addressLineController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('结算'),
),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(height: 16),
Text('选择地址', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
SizedBox(height: 8),
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey[300]),
borderRadius: BorderRadius.circular(8),
),
child: Column(
children: [
for (var address in _addressList)
ListTile(
onTap: () {
setState(() {
_selectedAddress = address;
});
},
leading: Radio(
value: address,
groupValue: _selectedAddress,
onChanged: (value) {
setState(() {
_selectedAddress = value;
});
},
),
title: Text(address.name),
subtitle: Text('${address.province}${address.city}${address.district}${address.addressLine}'),
),
Divider(),
ListTile(
onTap: () {
showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text('新增地址'),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
controller: _nameController,
decoration: InputDecoration(labelText: '收件人姓名'),
),
TextField(
controller: _phoneController,
decoration: InputDecoration(labelText: '电话'),
),
TextField(
controller: _provinceController,
decoration: InputDecoration(labelText: '省份'),
),
TextField(
controller: _cityController,
decoration: InputDecoration(labelText: '城市'),
),
TextField(
controller: _districtController,
decoration: InputDecoration(labelText: '区县'),
),
TextField(
controller: _addressLineController,
decoration: InputDecoration(labelText: '详细地址'),
),
],
),
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('取消'),
),
TextButton(
onPressed: _isAddingAddress ? null : _addAddress,
child: _isAddingAddress ? CircularProgressIndicator() : Text('确定'),
),
],
),
);
},
leading: Icon(Icons.add),
title: Text('新增地址'),
),
],
),
),
SizedBox(height: 16),
Text('选择支付方式', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
SizedBox(height: 8),
RadioListTile(
value: '支付宝',
groupValue: '支付宝',
onChanged: (value) {},
title: Text('支付宝'),
),
RadioListTile(
value: '微信',
groupValue: '支付宝',
onChanged: (value) {},
title: Text('微信支付'),
),
],
),
),
bottomNavigationBar: Container(
height: kBottomNavigationBarHeight + 16,
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
decoration: BoxDecoration(
border: Border(top: BorderSide(color: Colors.grey[300])),
color: Colors.white,
),
child: ElevatedButton(
onPressed: _selectedAddress == null ? null : _submitOrder,
child: Text('结算'),
),
),
);
}
}
以下是地址模型的代码示例:
```dart
class AddressModel {
final int id;
final String name;
final String phone;
final String province;
final String city;
final String district;
final String addressLine;
final bool isDefault;
AddressModel({
this.id,
this.name,
this.phone,
this.province,
this.city,
this.district,
this.addressLine,
this.isDefault,
});
factory AddressModel.fromJson(Map<String, dynamic> json) {
return AddressModel(
id: json['id'],
name: json['name'],
phone: json['phone'],
province: json['province'],
city: json['city'],
district: json['district'],
addressLine: json['addressLine'],
isDefault: json['isDefault'] == 1,
);
}
}
在上面的代码中,我们使用ApiService类来进行网络请求,并将数据解析成AddressModel对象。CheckoutPage类则负责展示结算页面,并处理用户交互。
主要功能包括:
- 获取用户地址列表
- 选择地址
- 新增地址
- 选择支付方式
- 提交订单
- 处理支付结果
代码说明:
_getAddressList()函数用于获取用户地址列表,并将数据解析成AddressModel对象。_selectedAddress变量用于保存用户选择的地址。_submitOrder()函数用于提交订单,并处理支付结果。_addAddress()函数用于新增地址。AddressModel类用于解析地址数据。
注意:
- 以上代码仅供参考,需要根据实际需求进行修改。
- 支付功能需要根据具体的支付平台进行实现。
- 代码中使用
dio库进行网络请求,请确保已安装该库。 - 使用
jsonDecode函数解析JSON数据。 - 确保在
ApiService类中定义了getAddresses(),submitOrder()和saveAddress()方法。 - 确保在
AddressModel类中定义了fromJson()方法。
总结:
本文介绍了如何使用Flutter开发一个商城结算页面,并提供了完整的代码示例。通过学习本文,您可以掌握使用Flutter开发结算页面的基本方法,并根据实际需求进行定制开发。
原文地址: http://www.cveoy.top/t/topic/oi3A 著作权归作者所有。请勿转载和采集!