微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Flutter:如何在另一个字段中将其他值对象分配为文本编辑控制器?

如何解决Flutter:如何在另一个字段中将其他值对象分配为文本编辑控制器?

我正在建立一个包含联系人姓名和电话号码字段的表单。用户将能够从以前保存的联系人列表中选择(点击)联系人,这将在其各自的字段中显示姓名和电话号码。

要实现此目的,我使用的是Flutter_Form_Builder软件包版本:3.14.0中的TypeAheadFormField来构建表单。

我在认的TypeAheadFormField控制器中成功从本地数据库分配了_nameController。 但是我无法通过选择与FormFormerTextField相同的选项来分配_mobileController。

我设法通过TypeAheadFormField获得“名称”值,但是每次我从建议中切换选择时, _mobileController.text在FormBuilderTextField上未更新

我的代码如下:

    import 'package:myApp/customer.dart';
    import 'package:myApp/db_helper.dart';
    import 'package:Flutter/material.dart';
    import 'package:Flutter_form_builder/Flutter_form_builder.dart';
    
    class MyForm extends StatefulWidget {
      @override
      _MyFormState createState() => _MyFormState();
    }
    
    class _MyFormState extends State<MyForm> {
      DatabaseHelper _dbHelper;
    
      Customer _customer = Customer();
      List<Customer> _customerList = [];
    
      final _formKey = GlobalKey<FormBuilderState>();
      final _cfKey = GlobalKey<FormBuilderState>();
    
      final _nameController = TextEditingController();
      final _inputContactNameController = TextEditingController();
      final _inputContactPhoneController = TextEditingController();
      var _mobileController = TextEditingController();
    
      @override
      void initState() {
        super.initState();
        _refreshBikeSellerList();
        setState(() {
          _dbHelper = DatabaseHelper.instance;
        });
        _mobileController = TextEditingController();
        _mobileController.addListener(() {
          setState(() {});
        });
      }
    
      @override
      void dispose() {
        _mobileController.dispose();
        _nameController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
          child: FormBuilder(
            key: _formKey,child: Column(
              children: [
                FormBuilderTypeAhead(
                  attribute: 'contact_person',initialValue: _customer,controller: _nameController,onChanged: (val) {},itemBuilder: (context,Customer _customer) {
                    return ListTile(
                      title: Text(_customer.name),subtitle: Text(_customer.mobile),);
                  },selectionToTextTransformer: (Customer c) => c.name,suggestionsCallback: (query) {
                    if (query.isNotEmpty) {
                      var lowercaseQuery = query.toLowerCase();
                      return _customerList.where((_customer) {
                        return _customer.name
                            .toLowerCase()
                            .contains(lowercaseQuery);
                      }).toList(growable: false)
                        ..sort((a,b) => a.name
                            .toLowerCase()
                            .indexOf(lowercaseQuery)
                            .compareto(
                                b.name.toLowerCase().indexOf(lowercaseQuery)));
                    } else {
                      return _customerList;
                    }
                  },textFieldConfiguration: TextFieldConfiguration(
                    autofocus: true,style: DefaultTextStyle.of(context).style.copyWith(
                          fontSize: 17,letterSpacing: 1.2,color: Colors.black,fontWeight: FontWeight.w300,),// controller: guessMotor1,onSuggestionSelected: (val) {
                    if (val != null) {
                      return _customerList.map((_customer) {
                        setState(() {
                          _mobileController.text = _customer.mobile;
                        });
                      }).toList();
                    } else {
                      return _customerList;
                    }
                  },FormBuilderTextField(
                  controller: _mobileController,attribute: 'mobile',readOnly: true,style: TextStyle(fontSize: 17),decoration: Inputdecoration(
                    hintText: 'mobile',SizedBox(height: 40),Container(
              child: RaisedButton(
                onpressed: () async {
                  await manageContact(context);
                },child: Text('Manage Contact'),],);
      }
    
      manageContact(BuildContext context) async {
        showDialog(
          context: context,builder: (context) => AlertDialog(
            title: Text(
              'Manage Contact',textAlign: TextAlign.center,titleTextStyle: TextStyle(
                fontWeight: FontWeight.w500,fontSize: 17,color: Colors.black45,letterSpacing: 0.8),shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.all(Radius.circular(12))),content: FormBuilder(
              key: _cfKey,child: Column(
                mainAxisSize: MainAxisSize.min,children: [
                  // SizedBox(height: 10),InkResponse(
                    onTap: () {},child: CircleAvatar(
                      radius: 30,child: Icon(
                        Icons.person_add,color: Colors.grey[100],backgroundColor: Colors.grey[500],SizedBox(height: 10),Container(
                    width: MediaQuery.of(context).size.width * 0.5,margin: EdgeInsets.symmetric(horizontal: 15),child: FormBuilderTextField(
                      maxLength: 20,controller: _inputContactNameController,textAlign: TextAlign.start,keyboardType: TextInputType.text,textCapitalization: TextCapitalization.words,attribute: 'contact_person',decoration: Inputdecoration(
                          prefixIcon: Icon(
                        Icons.person_outline,size: 22,)),onChanged: (val) {
                        setState(() {
                          _customer.name = val;
                          _formKey
                              .currentState.fields['contact_person'].currentState
                              .validate();
                        });
                      },autovalidateMode: AutovalidateMode.always,validators: [
                        FormBuilderValidators.required(),FormBuilderValidators.maxLength(20),FormBuilderValidators.minLength(2),child: FormBuilderTextField(
                      attribute: 'phone_number',controller: _inputContactPhoneController,keyboardType: TextInputType.number,decoration: Inputdecoration(
                          prefixIcon: Icon(
                        Icons.phone_android,onChanged: (val) {
                        setState(() {
                          _customer.mobile = val;
                          _formKey.currentState.fields['phone_number'].currentState
                              .validate();
                        });
                      },FormBuilderValidators.numeric(),valueTransformer: (text) {
                        return text == null ? null : num.tryParse(text);
                      },SizedBox(height: 20),Row(
                    mainAxisAlignment: MainAxisAlignment.spaceAround,children: [
                      RaisedButton(
                          color: Colors.white,child: Text('Cancel'),onpressed: () {
                            Navigator.of(context).pop();
                          }),RaisedButton(
                        color: Colors.grey[400],child: Text(
                          'Save',style: TextStyle(color: Colors.white),onpressed: () async {
                          try {
                            if (_formKey.currentState.validate()) {
                              _formKey.currentState.save();
                              if (_customer.id == null)
                                await _dbHelper.insertBikeContact(_customer);
                              else
                                await _dbHelper.updateCustomer(_customer);
                              _refreshBikeSellerList();
                              _formKey.currentState.reset();
                              _inputContactNameController.clear();
                              _inputContactPhoneController.clear();
                              Navigator.of(context).pop();
                            }
                          } catch (e) {
                            print(e);
                          }
                        },)
                    ],);
      }
    
      _refreshBikeSellerList() async {
        List<Customer> x = await _dbHelper.getCustomer();
        setState(() {
          _customerList = x;
        });
      }
    }

我点击时有没有可能更新_mobileController的方法

任何帮助将不胜感激。 预先谢谢你。

已编辑

我保存客户数据的类:

class Customer {
  int id;
  String name;
  String mobile;

  static const tblCustomer = 'Customer';
  static const colId = 'id';
  static const colName = 'name';
  static const colMobile = 'mobile';

  Customer({
    this.id,this.name,this.mobile,});

  Map<String,dynamic> toMap() {
    var map = <String,dynamic>{colName: name,colMobile: mobile};
    if (id != null) map[colId] = id;
    return map;
  }

  Customer.fromMap(Map<String,dynamic> map) {
    id = map[colId];
    name = map[colName];
    mobile = map[colMobile];
  }

  @override
  bool operator ==(Object other) =>
      identical(this,other) ||
      other is Customer &&
          runtimeType == other.runtimeType &&
          name == other.name;

  @override
  int get hashCode => name.hashCode;

  @override
  String toString() {
    return name;
  }
}

这是我的数据库

import 'dart:async';
import 'dart:io';

import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

import 'customer.dart';

class DatabaseHelper {
  static const _databaseVersion = 1;
  static const _databaseName = 'Kiloin.db';

  DatabaseHelper._();
  static final DatabaseHelper instance = DatabaseHelper._();

  Database _database;
  Future<Database> get database async {
    if (_database != null) return _database;
    _database = await _initDatabase();
    return _database;
  }

  _initDatabase() async {
    Directory dataDirectory = await getApplicationDocumentsDirectory();
    String dbPath = join(dataDirectory.path,_databaseName);
    return await openDatabase(
      dbPath,version: _databaseVersion,onCreate: _onCreateDB,);
  }

  _onCreateDB(Database db,int version) async {
    await db.execute('''
    CREATE TABLE ${Customer.tblCustomer}(
      ${Customer.colId} INTEGER PRIMARY KEY AUTOINCREMENT,${Customer.colName} TEXT NOT NULL,${Customer.colMobile} TEXT NOT NULL
    ) 
    ''');
  }

  Future<int> insertBikeContact(Customer customer) async {
    Database db = await database;
    return await db.insert(Customer.tblCustomer,customer.toMap());
  }

  Future<List<Customer>> getCustomer() async {
    Database db = await database;
    List<Map> contact = await db.query(Customer.tblCustomer);
    return contact.length == 0
        ? []
        : contact.map((e) => Customer.fromMap(e)).toList();
  }

  Future<int> updateCustomer(Customer customer) async {
    Database db = await database;
    return await db.update(Customer.tblCustomer,customer.toMap(),where: '${Customer.colId}=?',whereArgs: [customer.id]);
  }

  Future<int> deleteContact(int id) async {
    Database db = await database;
    return await db.delete(Customer.tblCustomer,whereArgs: [id]);
  }
}

解决方法

您从onSuggestionSelected获得的价值就是客户。使用该值来更新_mobileController.text

onSuggestionSelected: (customer) {
       if (customer != null) {
          setState(() {
             _mobileController.text = customer.mobile;
          });
       }
    }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。