在 Flutter 中按下按钮时将新的小部件作为列表插入

Posted

技术标签:

【中文标题】在 Flutter 中按下按钮时将新的小部件作为列表插入【英文标题】:Inserting new Widgets as List on Pressing Button in Flutter 【发布时间】:2021-07-25 09:13:47 【问题描述】:

我正在制作这样的屏幕,它可以从电话簿中选择联系人并将姓名作为列表插入到我的应用程序中。我想要的是,当我按下添加护理人员(+)按钮时,它应该选择一个联系人并显示姓名。 我为 MOM 部分制作了一个小部件,但每当我单击按钮时,它都会将 MOM 重写为我从电话簿中选择的任何联系人。

我做了这个屏幕:

我也想和妈妈一样添加爸爸和姐姐的联系方式,但是我做不到

这是我的屏幕代码:

import 'package:epicare/NavigBar.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_switch/flutter_switch.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:contact_picker/contact_picker.dart';

//Check contacts permission
Future<PermissionStatus> _getPermission() async 

  final PermissionStatus permission = await Permission.contacts.status;
  if (permission != PermissionStatus.granted &&
      permission != PermissionStatus.denied) 
    final Map<Permission, PermissionStatus> permissionStatus =
    await [Permission.contacts].request();
    return permissionStatus[Permission.contacts] ??
        PermissionStatus.undetermined;
   else 
    return permission;
  



class CaregiverScreen extends StatefulWidget 
  @override
  _CaregiverScreenState createState() => _CaregiverScreenState();


class _CaregiverScreenState extends State<CaregiverScreen> 
  final ContactPicker _contactPicker = new ContactPicker();
  Contact _contact;

  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  bool isSwitched = true;
  @override
  Widget build(BuildContext context) 
    //Size size = MediaQuery.of(context).size;
    return Scaffold(
      key: _scaffoldKey,
      backgroundColor: Colors.white,
      appBar: AppBar(
        backgroundColor: const Color(0xffE5E0A1),
        elevation: 0,
        centerTitle: true,
        title: Text(
          "Add Caregiver",
          style: TextStyle(
            fontSize: 15.0,
            color: Colors.black,
            fontFamily: 'Montserrat',
            fontWeight: FontWeight.normal,
          ),
        ),
        leading: IconButton(
          icon: Icon(
            Icons.arrow_back,
            color: Colors.black,
          ),
          onPressed: () 
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) 
                  return Homepage();
                ,
              ),
            );
          ,
        ),
      ),
      body: SingleChildScrollView(
        child: Container(
          padding: EdgeInsets.symmetric(horizontal: 10, vertical: 40),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                children: [
                  MaterialButton(
                    onPressed: () async 

                      final PermissionStatus permissionStatus = await _getPermission();
                      if (permissionStatus == PermissionStatus.granted) 
                        //We can now access our contacts here
                        // var contactNumber = openContactBook();
                        Contact contact = await _contactPicker.selectContact();
                        setState(() 
                          _contact = contact;
                        );
                      
                      else 
                        //If permissions have been denied show standard cupertino alert dialog
                        showDialog(
                            context: context,
                            builder: (BuildContext context) => CupertinoAlertDialog(
                              title: Text('Permissions error'),
                              content: Text('Please enable contacts access '
                                  'permission in system settings'),
                              actions: <Widget>[
                                CupertinoDialogAction(
                                  child: Text('OK'),
                                  onPressed: () => Navigator.of(context).pop(),
                                )
                              ],
                            ));
                      
                    ,
                    color: const Color(0xffd4d411),
                    textColor: Colors.white,
                    child: Icon(
                      Icons.add,
                      size: 32,
                    ),
                    padding: EdgeInsets.all(3),
                    shape: CircleBorder(),
                  ),
                  Text(
                    'Add a Caregiver',
                    style: TextStyle(
                        fontFamily: 'Montserrat',
                        fontSize: 13,
                        color: const Color(0xff000000),
                        height: 1.5384615384615385,
                        fontWeight: FontWeight.w600),
                    textHeightBehavior:
                        TextHeightBehavior(applyHeightToFirstAscent: false),
                    textAlign: TextAlign.left,
                  )
                ],
              ),
                _contact == null ? Container() : CaregiversList(_contact.fullName),
            ],
          ),
        ),
      ),
    );
  
Widget CaregiversList(String name)
    print(name);
    var c = name.split(' ');
    print(c[0]);
    var caregiver = c[0];
    var output = getInitials(string: caregiver, limitTo: 1);
    print(output);
    // var i = caregiver.codeUnitAt(0);
    // print(i);
    return Container(
    padding: EdgeInsets.symmetric(vertical: 20, horizontal: 27),
    child: Row(
      //crossAxisAlignment: CrossAxisAlignment.center,
      //mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: <Widget>[
        CircleAvatar(
          radius: 24,
          backgroundColor: const Color(0xffd4d411),
          child: CircleAvatar(
            radius: 22,
            backgroundColor: Colors.white,
            child: Text(
              output,
              style: TextStyle(
                fontFamily: 'Segoe UI',
                fontSize: 20,
                color: const Color(0xff000000),
              ),
            ),
          ),
        ),
        SizedBox(width: 19),
        Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              caregiver,
              style: TextStyle(
                  fontFamily: 'Montserrat',
                  fontSize: 13,
                  color: const Color(0xff000000),
                  height: 1.5384615384615385,
                  fontWeight: FontWeight.w600),
              textHeightBehavior: TextHeightBehavior(
                  applyHeightToFirstAscent: false),
              textAlign: TextAlign.left,
            ),
            isSwitched
                ? Text(
                    "Activated",
                    style: TextStyle(
                        fontFamily: 'Montserrat',
                        fontSize: 10,
                        color: const Color(0x80232425),
                        fontWeight: FontWeight.w500),
                    textAlign: TextAlign.left,
                  )
                : Text(
                    "Disabled",
                    style: TextStyle(
                        fontFamily: 'Montserrat',
                        fontSize: 10,
                        color: const Color(0x80232425),
                        fontWeight: FontWeight.w500),
                    textAlign: TextAlign.left,
                  ),
          ],
        ),
        SizedBox(width: 143),
        FlutterSwitch(
          width: 40.0,
          height: 20.0,
          value: isSwitched,
          toggleSize: 15,
          borderRadius: 40.0,
          padding: 2.0,
          showOnOff: false,
          activeColor: const Color(0xffd4d411),
          activeToggleColor: Colors.white,
          inactiveColor: const Color(0xffDDDBAF),
          inactiveToggleColor: Colors.white,
          onToggle: (value) 
            setState(() 
              isSwitched = value;
              print(isSwitched);
            );
          ,
        ),
      ],
    ),
  );


  String getInitials(String string, int limitTo) 
    var buffer = StringBuffer();
    var split = string.split(' ');
    for (var i = 0 ; i < (limitTo ?? split.length); i ++) 
      buffer.write(split[i][0]);
    
    return buffer.toString();
  

请帮助我,因为我是 Flutter 的新手。 提前谢谢你:)

【问题讨论】:

【参考方案1】:

您需要管理从联系人中选择的 Caregiverlist。例如

class Caregiver 
  String name;
  bool isActive;
  
  Caregiver(this.name, this.isActive);
  
  factory Caregiver.fromJson(Map<String, dynamic> map) 
    if (map == null) return null;
    return Caregiver(name: map['name'] ?? "", 
                     isActive: map['isActive']);
  

初始化看护人列表

List<Caregiver> _careList = [];

添加看护人

Contact contact = await _contactPicker.selectContact();
setState(() 
  _careList.add(Caregiver(name: contact, isActive: true));
);

显示看护人列表(要在 Scrollview 中显示 ListView,请添加以下 3 行。

ListView.separated(
 physics: NeverScrollableScrollPhysics(),
 shrinkWrap: true,
 primary: false,
itemBuilder: (context, index)         
  return _caregiverWidget(index);
,
separatorBuilder: (_, __) => Divider(),
itemCount: _careList.length);

添加新功能

Widget _caregiverWidget(int index) 
  Caregiver _caregiver = _careList[index];
  print(_caregiver.name);
  var c = _caregiver.name.split(' ');
  print(c[0]);
  var caregiver = c[0];
  var output = getInitials(string: caregiver, limitTo: 1);
  print(output);
  // var i = caregiver.codeUnitAt(0);
  // print(i);
  return Container(
    padding: EdgeInsets.symmetric(vertical: 20, horizontal: 27),
    child: Row(
      //crossAxisAlignment: CrossAxisAlignment.center,
      //mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: <Widget>[
        CircleAvatar(
          radius: 24,
          backgroundColor: const Color(0xffd4d411),
          child: CircleAvatar(
            radius: 22,
            backgroundColor: Colors.white,
            child: Text(
              output,
              style: TextStyle(
                fontFamily: 'Segoe UI',
                fontSize: 20,
                color: const Color(0xff000000),
              ),
            ),
          ),
        ),
        SizedBox(width: 19),
        Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              caregiver,
              style: TextStyle(
                  fontFamily: 'Montserrat',
                  fontSize: 13,
                  color: const Color(0xff000000),
                  height: 1.5384615384615385,
                  fontWeight: FontWeight.w600),
              textHeightBehavior:
                  TextHeightBehavior(applyHeightToFirstAscent: false),
              textAlign: TextAlign.left,
            ),
            _caregiver.isActive
                ? Text(
                    "Activated",
                    style: TextStyle(
                        fontFamily: 'Montserrat',
                        fontSize: 10,
                        color: const Color(0x80232425),
                        fontWeight: FontWeight.w500),
                    textAlign: TextAlign.left,
                  )
                : Text(
                    "Disabled",
                    style: TextStyle(
                        fontFamily: 'Montserrat',
                        fontSize: 10,
                        color: const Color(0x80232425),
                        fontWeight: FontWeight.w500),
                    textAlign: TextAlign.left,
                  ),
          ],
        ),
        SizedBox(width: 143),
        FlutterSwitch(
          width: 40.0,
          height: 20.0,
          value: _caregiver.isActive,
          toggleSize: 15,
          borderRadius: 40.0,
          padding: 2.0,
          showOnOff: false,
          activeColor: const Color(0xffd4d411),
          activeToggleColor: Colors.white,
          inactiveColor: const Color(0xffDDDBAF),
          inactiveToggleColor: Colors.white,
          onToggle: (value) 
            setState(() 
              _caregiver.isActive = value;
              _careList.removeAt(index);
              _careList.insert(index, _caregiver);
            );
          ,
        ),
      ],
    ),
  );

【讨论】:

我应该在哪里添加最后两段代码?我按照您的要求创建了一个新班级,并且我更新了联系人挑选线,但对于最后一部分,即显示护理人员列表并切换激活/停用,我应该在哪里使用它们? codepile.net/pile/pra4w5zP 我添加了您要求的代码,但它给了我错误,我无法弄清楚为什么,请您查看链接上的代码并帮助我哪里出错了? 更新了源代码,但我无法测试。请检查并告诉我。 是的,它工作得很好,非常感谢你:) 你帮我写了这段代码我想再问一件事,如果想删除小部件之间的分隔线,那么应该使用什么来代替? 不客气。你可以使用容器()。请将 Divider() 替换为 Container()。

以上是关于在 Flutter 中按下按钮时将新的小部件作为列表插入的主要内容,如果未能解决你的问题,请参考以下文章

如何检测按下的鼠标何时进入不同框架中的小部件

我们可以在 Flutter 中创建一个新的小部件吗?

仅当我在主应用程序中按下活动中的按钮时,如何更新小部件

如何在 Flutter 的小部件树中将新的 MaterialPageRoute 作为子项打开

Flutter:在 ListView 中按下卡片小部件不起作用

在 Tkinter 中按下按钮后如何清除 Entry 小部件?