Flutter集成LeanCloud服务插件lean_sdk_flutter的使用
Flutter集成LeanCloud服务插件lean_sdk_flutter
的使用
在本教程中,我们将介绍如何在Flutter应用中集成LeanCloud服务,并使用lean_sdk_flutter
插件。我们将通过一个完整的示例来演示如何连接银行账户、创建支付源、重新连接银行账户以及完成支付。
环境配置
首先,确保你已经在项目中添加了lean_sdk_flutter
插件。你可以通过以下两种方式之一来安装该插件:
使用命令行安装
打开终端并运行以下命令:
flutter pub add lean_sdk_flutter
手动添加到pubspec.yaml
在你的pubspec.yaml
文件中添加以下依赖:
dependencies:
lean_sdk_flutter: ^3.0.6
然后执行以下命令以更新依赖项:
flutter pub get
示例代码
以下是完整的示例代码,展示了如何在Flutter应用中使用lean_sdk_flutter
插件。
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:go_router/go_router.dart';
import 'package:lean_sdk_flutter/lean_sdk_flutter.dart';
void main() {
runApp(const MyApp());
}
/// 路由配置。
final GoRouter _router = GoRouter(
routes: <RouteBase>[
GoRoute(
path: '/',
builder: (BuildContext context, GoRouterState state) {
return const HomeScreen();
},
routes: <RouteBase>[
GoRoute(
path: 'app/flutter/connect/success',
builder: (BuildContext context, GoRouterState state) {
return const SuccessScreen();
},
),
GoRoute(
path: 'app/flutter/connect/fail',
builder: (BuildContext context, GoRouterState state) {
return const FailScreen();
},
),
],
),
],
);
/// 主应用。
class MyApp extends StatelessWidget {
/// 构造函数。
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: _router,
);
}
}
/// 主屏幕
class HomeScreen extends StatefulWidget {
/// 构造函数。
const HomeScreen({super.key});
[@override](/user/override)
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final TextEditingController _appTokenController = TextEditingController();
String appToken = "";
// 连接
final TextEditingController _connectCustomerIDController = TextEditingController();
String connectCustomerID = "";
final TextEditingController _connectBankIdentifierController = TextEditingController();
String connectBankIdentifier = "";
final TextEditingController _connectPaymentDestinationIDController = TextEditingController();
String connectPaymentDestinationID = "";
// 重新连接
final TextEditingController _reconnectIDController = TextEditingController();
String reconnectID = "";
// 创建受益人
final TextEditingController _customerIDController = TextEditingController();
String customerID = "";
final TextEditingController _paymentSourceIDController = TextEditingController();
String paymentSourceID = "";
final TextEditingController _paymentDestinationIDController = TextEditingController();
String paymentDestinationID = "";
// 支付
bool isShowBalances = false;
final TextEditingController _accountIdController = TextEditingController();
String accountId = "";
final TextEditingController _paymentIntentIDController = TextEditingController();
String paymentIntentID = "";
[@override](/user/override)
Widget build(BuildContext context) {
var permissions = [
LeanPermissions.identity,
LeanPermissions.transactions,
LeanPermissions.balance,
LeanPermissions.accounts,
LeanPermissions.payments
];
var isSandbox = true;
var environment = 'staging';
_connect() {
showDialog(
context: context,
builder: (BuildContext context) => Center(
child: Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Lean.connect(
showLogs: true,
env: environment,
accessToken: "",
appToken: appToken,
isSandbox: isSandbox,
customerId: connectCustomerID,
bankIdentifier: connectBankIdentifier,
paymentDestinationId: connectPaymentDestinationID,
permissions: permissions,
failRedirectUrl: "https://cdn.leantech.me/app/flutter/connect/success",
successRedirectUrl: "https://cdn.leantech.me/app/flutter/connect/fail",
customization: const {
"button_text_color": "white",
"theme_color": "red",
"button_border_radius": "10",
"overlay_color": "pink",
},
callback: (LeanResponse resp) {
if (kDebugMode) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("Callback: ${resp.message}"),
));
}
Navigator.pop(context);
},
actionCancelled: () => Navigator.pop(context),
),
),
),
);
}
_reconnect() {
showDialog(
context: context,
builder: (context) {
return Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Lean.reconnect(
env: environment,
appToken: appToken,
reconnectId: reconnectID,
isSandbox: isSandbox,
showLogs: true,
accessToken: "",
callback: (LeanResponse resp) {
if (kDebugMode) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("Callback: ${resp.message}"),
));
}
Navigator.pop(context);
},
actionCancelled: () => Navigator.pop(context),
),
);
},
);
}
_createPaymentSource() {
showDialog(
context: context,
builder: (BuildContext context) => Center(
child: Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: SizedBox(
height: MediaQuery.of(context).size.height * 0.8,
child: Lean.createPaymentSource(
env: environment,
appToken: appToken,
customerId: customerID,
paymentSourceId: paymentSourceID,
paymentDestinationId: paymentDestinationID,
isSandbox: isSandbox,
showLogs: true,
accessToken: "",
callback: (LeanResponse resp) {
if (kDebugMode) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("Callback: ${resp.message}"),
));
}
Navigator.pop(context);
},
actionCancelled: () => Navigator.pop(context),
),
),
),
),
);
}
_pay() {
showDialog(
context: context,
builder: (context) {
return Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Lean.pay(
env: environment,
appToken: appToken,
accountId: accountId,
paymentIntentId: paymentIntentID,
showBalances: isShowBalances,
isSandbox: isSandbox,
showLogs: true,
accessToken: "",
callback: (LeanResponse resp) {
if (kDebugMode) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("Callback: ${resp.message}"),
));
}
Navigator.pop(context);
},
actionCancelled: () => Navigator.pop(context),
),
);
},
);
}
return SafeArea(
child: Scaffold(
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset('assets/images/lean.png', width: 100, height: 100),
],
),
Container(
margin: const EdgeInsets.all(10.0),
padding: const EdgeInsets.only(bottom: 20),
decoration: BoxDecoration(
color: Colors.grey[200],
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 2,
blurRadius: 2,
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 0),
child: TextFormField(
key: Key('appToken'),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: '应用令牌',
),
controller: _appTokenController,
onChanged: (value) {
setState(() {
appToken = value;
});
},
),
),
]),
),
Container(
margin: const EdgeInsets.all(10.0),
padding: const EdgeInsets.only(bottom: 20),
decoration: BoxDecoration(
color: Colors.grey[200],
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 2,
blurRadius: 2,
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 0),
child: TextFormField(
key: Key('connectCustomerId'),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: '客户ID',
),
controller: _connectCustomerIDController,
onChanged: (value) {
setState(() {
connectCustomerID = value;
});
},
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 0),
child: TextFormField(
key: Key('connectBankIdentifier'),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: '银行标识符',
),
controller: _connectBankIdentifierController,
onChanged: (value) {
setState(() {
connectBankIdentifier = value;
});
},
),
),
Padding(
padding: const EdgeInsets.only(bottom: 14, left: 8, right: 8),
child: TextFormField(
key: Key('connectPaymentDestinationId'),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: '支付目的地ID',
),
controller: _connectPaymentDestinationIDController,
onChanged: (value) {
setState(() {
connectPaymentDestinationID = value;
});
},
),
),
ElevatedButton(
onPressed: () => _connect(),
style: _buttonStyle(),
child: const Text('连接'),
),
]),
),
Container(
margin: const EdgeInsets.all(10.0),
padding: const EdgeInsets.only(bottom: 20),
decoration: BoxDecoration(
color: Colors.grey[200],
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 2,
blurRadius: 2,
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 14, left: 8, right: 8),
child: TextFormField(
key: Key('reconnectId'),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: '重新连接ID',
),
controller: _reconnectIDController,
onChanged: (value) {
setState(() {
reconnectID = value;
});
},
),
),
ElevatedButton(
onPressed: () => _reconnect(),
style: _buttonStyle(),
child: const Text('重新连接'),
),
]),
),
Container(
margin: const EdgeInsets.all(10.0),
padding: const EdgeInsets.only(bottom: 20),
decoration: BoxDecoration(
color: Colors.grey[200],
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 2,
blurRadius: 2,
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 0),
child: TextFormField(
key: Key('createBeneficiaryCustomerId'),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: '客户ID',
),
controller: _customerIDController,
onChanged: (value) {
setState(() {
customerID = value;
});
},
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 0),
child: TextFormField(
key: Key('createBeneficiaryPaymentSourceId'),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: '支付来源ID',
),
controller: _paymentSourceIDController,
onChanged: (value) {
setState(() {
paymentSourceID = value;
});
},
),
),
Padding(
padding: const EdgeInsets.only(bottom: 14, left: 8, right: 8),
child: TextFormField(
key: Key('createBeneficiaryPaymentDestinationId'),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: '支付目的地ID',
),
controller: _paymentDestinationIDController,
onChanged: (value) {
setState(() {
paymentDestinationID = value;
});
},
),
),
ElevatedButton(
onPressed: () => _createPaymentSource(),
style: _buttonStyle(),
child: const Text('创建支付来源'),
),
]),
),
Container(
margin: const EdgeInsets.all(10.0),
padding: const EdgeInsets.only(bottom: 20),
decoration: BoxDecoration(
color: Colors.grey[200],
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
spreadRadius: 2,
blurRadius: 2,
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text("显示余额"),
Switch(
value: isShowBalances,
onChanged: (value) {
setState(() {
isShowBalances = value;
});
},
),
],
)),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 0),
child: TextFormField(
key: Key('payAccountId'),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: '账户ID',
),
controller: _accountIdController,
onChanged: (value) {
setState(() {
accountId = value;
});
},
),
),
Padding(
padding: const EdgeInsets.only(bottom: 14, left: 8, right: 8),
child: TextFormField(
key: Key('paymentIntentId'),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: '支付意向ID',
),
controller: _paymentIntentIDController,
onChanged: (value) {
setState(() {
paymentIntentID = value;
});
},
),
),
ElevatedButton(
onPressed: () => _pay(),
style: _buttonStyle(),
child: const Text('支付'),
),
]),
),
],
),
)));
}
// _cardStyle() =>
_buttonStyle() => ElevatedButton.styleFrom(
shape: const StadiumBorder(),
backgroundColor: Colors.black,
minimumSize: const Size(200, 40),
maximumSize: const Size(200, 40),
);
}
/// 成功屏幕
class SuccessScreen extends StatelessWidget {
/// 构造函数。
const SuccessScreen({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('成功')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text("账户已连接。"),
ElevatedButton(
onPressed: () => context.go('/'),
child: const Text('返回主屏幕'),
),
],
)),
);
}
}
/// 失败屏幕
class FailScreen extends StatelessWidget {
/// 构造函数。
const FailScreen({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('失败')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text("账户连接失败。"),
ElevatedButton(
onPressed: () => context.go('/'),
child: const Text('返回主屏幕'),
),
],
)),
);
}
}
更多关于Flutter集成LeanCloud服务插件lean_sdk_flutter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter集成LeanCloud服务插件lean_sdk_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
要在Flutter项目中集成LeanCloud服务,可以使用lean_sdk_flutter
插件。以下是详细的使用步骤:
1. 添加依赖
在pubspec.yaml
文件中添加lean_sdk_flutter
插件的依赖:
dependencies:
flutter:
sdk: flutter
lean_sdk_flutter: ^0.0.1 # 使用最新版本
然后运行flutter pub get
来安装依赖。
2. 初始化LeanCloud SDK
在Flutter应用的入口文件(通常是main.dart
)中初始化LeanCloud SDK:
import 'package:flutter/material.dart';
import 'package:lean_sdk_flutter/lean_sdk_flutter.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化LeanCloud SDK
await LeanSdkFlutter.init(
appId: 'your-app-id', // 替换为你的App ID
appKey: 'your-app-key', // 替换为你的App Key
serverUrl: 'https://your-server-url', // 替换为你的服务器地址
);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
3. 使用LeanCloud服务
在应用中可以使用LeanCloud提供的各种服务,例如存储对象、查询数据等。
存储对象
import 'package:lean_sdk_flutter/lean_sdk_flutter.dart';
class MyHomePage extends StatelessWidget {
Future<void> saveObject() async {
var object = LeanObject('TestObject');
object.setString('name', 'Flutter');
object.setInt('age', 3);
await object.save();
print('Object saved successfully');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('LeanCloud Demo'),
),
body: Center(
child: ElevatedButton(
onPressed: saveObject,
child: Text('Save Object'),
),
),
);
}
}
查询数据
import 'package:lean_sdk_flutter/lean_sdk_flutter.dart';
class MyHomePage extends StatelessWidget {
Future<void> queryObjects() async {
var query = LeanQuery('TestObject');
query.whereEqualTo('name', 'Flutter');
var results = await query.find();
for (var obj in results) {
print('Object ID: ${obj.objectId}, Name: ${obj.getString('name')}, Age: ${obj.getInt('age')}');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('LeanCloud Demo'),
),
body: Center(
child: ElevatedButton(
onPressed: queryObjects,
child: Text('Query Objects'),
),
),
);
}
}
4. 其他功能
lean_sdk_flutter
插件还提供了其他功能,如用户管理、文件上传、云函数调用等。具体使用方法可以参考插件的官方文档或源码。
5. 注意事项
- 确保在LeanCloud控制台中正确配置了应用。
- 确保网络请求权限已添加到
AndroidManifest.xml
和Info.plist
中。
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Info.plist -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>