Flutter登录应用:实现TextField接收并校验数据库名称的方法
Flutter登录应用数据库名称动态配置实现方案
我正在开发一款登录应用,登录界面设有三个TextField:工号、密码、公司代码(即数据库名称)。点击登录按钮时,需要通过输入的数据库名称连接对应数据库,完成账号密码的校验。目前代码可实现账号密码的校验,但无法处理数据库名称的接收与校验,我已尝试添加DBnameController,但未完成完整功能,现寻求具体实现方案。
现有代码
import 'package:flutter/material.dart'; import 'package:hdislogin/screen/menu.dart'; import 'package:postgres/postgres.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: LoginPage(), ); } } class LoginPage extends StatefulWidget { const LoginPage({super.key}); @override State<LoginPage> createState() => _LoginPageState(); } class _LoginPageState extends State<LoginPage> { final TextEditingController DBnameController = TextEditingController(); final TextEditingController _empl_noController = TextEditingController(); final TextEditingController _passwdController = TextEditingController(); Future<void> _login() async { //final String DBname = DBnameController.text; final String empl_no = _empl_noController.text; final String passwd = _passwdController.text; PostgreSQLConnection connection = PostgreSQLConnection( 'ip', 5432, 'DBName', username: 'username', password: 'password', ); try { await connection.open(); final List<List<dynamic>> results = await connection.query( 'SELECT * from table', substitutionValues: { 'empl_no': empl_no, 'passwd': passwd, }, ); if (results.isNotEmpty) { print('success'); Navigator.push( context, MaterialPageRoute(builder: (_) => Menu()), ); } else { print('fail'); } } finally { await connection.close(); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(35), child: Center( child: Column( children: [ Padding( padding: const EdgeInsets.all(10), child: Image.asset( 'assets/images/hdis.png', height: 300, width: 300, ), ), TextField( maxLength: 4, //controller: DBnameController = 'DBname', decoration: InputDecoration( labelText: 'CompanyCode', ), ), TextField( maxLength: 6, decoration: InputDecoration( labelText: 'userID', ), ), TextField( obscureText: true, decoration: InputDecoration( labelText: 'password', ), ), Container( margin: EdgeInsets.only(top: 0), child: ElevatedButton( style: OutlinedButton.styleFrom( minimumSize: Size(70, 30), ), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (_) => Menu()), ); }, child: Text( "Login", style: TextStyle( color: Colors.black, ), ), ), ), ], ), ), ), ), ); } }
我尝试过的修改
class _LoginPageState extends State<LoginPage> //added part final TextEditingController DBnameController = TextEditingController(); . . . TextField( maxLength: 4, //added part //controller: DBnameController = 'DBname', decoration: InputDecoration( labelText: 'CompanyCode', ), ),
具体实现步骤
正确绑定控制器与TextField
把CompanyCode对应的TextField的controller属性直接绑定到DBnameController,同时给另外两个TextField也绑定对应的控制器:TextField( maxLength: 4, controller: DBnameController, decoration: const InputDecoration( labelText: 'CompanyCode', ), ), TextField( maxLength: 6, controller: _empl_noController, decoration: const InputDecoration( labelText: 'userID', ), ), TextField( obscureText: true, controller: _passwdController, decoration: const InputDecoration( labelText: 'password', ), )动态获取数据库名称并建立连接
在_login方法中获取输入的数据库名称,替换固定的数据库名,同时添加输入校验和异常处理:Future<void> _login() async { final String DBname = DBnameController.text.trim(); final String empl_no = _empl_noController.text.trim(); final String passwd = _passwdController.text.trim(); // 校验输入是否为空 if (DBname.isEmpty || empl_no.isEmpty || passwd.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('请填写完整信息')), ); return; } PostgreSQLConnection connection = PostgreSQLConnection( 'ip', 5432, DBname, // 使用输入的数据库名称 username: 'username', password: 'password', ); try { await connection.open(); // 参数化查询避免SQL注入 final List<List<dynamic>> results = await connection.query( 'SELECT * FROM your_table_name WHERE empl_no = @empl_no AND passwd = @passwd', substitutionValues: { 'empl_no': empl_no, 'passwd': passwd, }, ); if (results.isNotEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('登录成功')), ); Navigator.push( context, MaterialPageRoute(builder: (_) => Menu()), ); } else { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('工号或密码错误')), ); } } catch (e) { // 处理数据库连接异常 ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('数据库连接失败:${e.toString()}')), ); } finally { await connection.close(); } }修正登录按钮点击事件
把登录按钮的onPressed改为调用_login方法,而非直接跳转:ElevatedButton( style: OutlinedButton.styleFrom( minimumSize: const Size(70, 30), ), onPressed: _login, child: const Text( "Login", style: TextStyle( color: Colors.black, ), ), )
修改后的完整代码
import 'package:flutter/material.dart'; import 'package:hdislogin/screen/menu.dart'; import 'package:postgres/postgres.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: LoginPage(), ); } } class LoginPage extends StatefulWidget { const LoginPage({super.key}); @override State<LoginPage> createState() => _LoginPageState(); } class _LoginPageState extends State<LoginPage> { final TextEditingController DBnameController = TextEditingController(); final TextEditingController _empl_noController = TextEditingController(); final TextEditingController _passwdController = TextEditingController(); Future<void> _login() async { final String DBname = DBnameController.text.trim(); final String empl_no = _empl_noController.text.trim(); final String passwd = _passwdController.text.trim(); if (DBname.isEmpty || empl_no.isEmpty || passwd.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('请填写完整信息')), ); return; } PostgreSQLConnection connection = PostgreSQLConnection( 'ip', 5432, DBname, username: 'username', password: 'password', ); try { await connection.open(); final List<List<dynamic>> results = await connection.query( 'SELECT * FROM your_table_name WHERE empl_no = @empl_no AND passwd = @passwd', substitutionValues: { 'empl_no': empl_no, 'passwd': passwd, }, ); if (results.isNotEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('登录成功')), ); Navigator.push( context, MaterialPageRoute(builder: (_) => Menu()), ); } else { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('工号或密码错误')), ); } } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('数据库连接失败:${e.toString()}')), ); } finally { await connection.close(); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(35), child: Center( child: Column( children: [ Padding( padding: const EdgeInsets.all(10), child: Image.asset( 'assets/images/hdis.png', height: 300, width: 300, ), ), TextField( maxLength: 4, controller: DBnameController, decoration: const InputDecoration( labelText: 'CompanyCode', ), ), TextField( maxLength: 6, controller: _empl_noController, decoration: const InputDecoration( labelText: 'userID', ), ), TextField( obscureText: true, controller: _passwdController, decoration: const InputDecoration( labelText: 'password', ), ), Container( margin: const EdgeInsets.only(top: 10), child: ElevatedButton( style: OutlinedButton.styleFrom( minimumSize: const Size(70, 30), ), onPressed: _login, child: const Text( "Login", style: TextStyle( color: Colors.black, ), ), ), ), ], ), ), ), ), ); } }
内容的提问来源于stack exchange,提问作者김민규
相关产品推荐
相关产品推荐

