2

我正在尝试使用颤振的联系人服务从手机获取联系人我正在计算所有联系人的数量,但它没有在 ListView 上显示联系人。它给了我以下错误。

I/flutter (18134): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (18134): The following RangeError was thrown building:
I/flutter (18134): RangeError (index): Invalid value: Valid value range is empty: 0
I/flutter (18134):
I/flutter (18134): When the exception was thrown, this was the stack:
I/flutter (18134): #0      List.[] (dart:core-patch/array.dart:16:52)
I/flutter (18134): #1      ListMixin.elementAt (dart:collection/list.dart:61:33)
I/flutter (18134): #2      MappedListIterable.elementAt (dart:_internal/iterable.dart:417:40)
I/flutter (18134): #3      _ContactPageState.contactListView.<anonymous closure> (package:private_call/contact_screen.dart:134:55)
I/flutter (18134): #4      SliverChildBuilderDelegate.build (package:flutter/src/widgets/sliver.dart:446:22)
I/flutter (18134): #5      SliverMultiBoxAdaptorElement._build.<anonymous closure> (package:flutter/src/widgets/sliver.dart:1134:67)
I/flutter (18134): #6      _HashMap.putIfAbsent (dart:collection-patch/collection_patch.dart:139:29)
I/flutter (18134): #7      SliverMultiBoxAdaptorElement._build (package:flutter/src/widgets/sliver.dart:1134:26)
I/flutter (18134): #8      SliverMultiBoxAdaptorElement.createChild.<anonymous closure> (package:flutter/src/widgets/sliver.dart:1147:55)
I/flutter (18134): #9      BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2607:19)
I/flutter (18134): #10     SliverMultiBoxAdaptorElement.createChild (package:flutter/src/widgets/sliver.dart:1140:11)
I/flutter (18134): #11     RenderSliverMultiBoxAdaptor._createOrObtainChild.<anonymous closure> (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:354:23)
I/flutter (18134): #12     RenderObject.invokeLayoutCallback.<anonymous closure> (package:flutter/src/rendering/object.dart:1866:58)
I/flutter (18134): #13     PipelineOwner._enableMutationsToDirtySubtrees (package:flutter/src/rendering/object.dart:918:15)
I/flutter (18134): #14     RenderObject.invokeLayoutCallback (package:flutter/src/rendering/object.dart:1866:13)
I/flutter (18134): #15     RenderSliverMultiBoxAdaptor._createOrObtainChild (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:343:5)
I/flutter (18134): #16     RenderSliverMultiBoxAdaptor.insertAndLayoutChild (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:489:5)
I/flutter (18134): #17     RenderSliverList.performLayout.advance (package:flutter/src/rendering/sliver_list.dart:219:19)
I/flutter (18134): #18     RenderSliverList.performLayout (package:flutter/src/rendering/sliver_list.dart:262:19)
I/flutter (18134): #19     RenderObject.layout (package:flutter/src/rendering/object.dart:1767:7)
I/flutter (18134): #20     RenderSliverEdgeInsetsPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:135:11)
I/flutter (18134): #21     RenderSliverPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:375:11)
I/flutter (18134): #22     RenderObject.layout (package:flutter/src/rendering/object.dart:1767:7)
I/flutter (18134): #23     RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:452:13)
I/flutter (18134): #24     RenderShrinkWrappingViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1783:12)
I/flutter (18134): #25     RenderShrinkWrappingViewport.performLayout (package:flutter/src/rendering/viewport.dart:1741:20)
I/flutter (18134): #26     RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1630:7)
I/flutter (18134): #27     PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:887:18)
I/flutter (18134): #28     RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:402:19)
I/flutter (18134): #29     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:884:13)
I/flutter (18134): #30     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:284:5)
I/flutter (18134): #31     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1113:15)
I/flutter (18134): #32     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1052:9)
I/flutter (18134): #33     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:968:5)
I/flutter (18134): #37     _invoke (dart:ui/hooks.dart:261:10)
I/flutter (18134): #38     _drawFrame (dart:ui/hooks.dart:219:3)
I/flutter (18134): (elided 3 frames from dart:async)
I/flutter (18134): ════════════════════════════════════════════════════════════════════════════════════════════════════

这是错误截图

我在联系人服务构造函数中添加了 isSearching 布尔值,它为每个联系人分配了一个错误的布尔值。

这是我的代码

import 'package:contacts_service/contacts_service.dart';
import 'package:flutter/material.dart';
import 'package:private_call/appBar.dart';
import 'cards_1.dart';

class ContactPage extends StatefulWidget {
  @override
  _ContactPageState createState() => _ContactPageState();
}

class _ContactPageState extends State<ContactPage> {
  Color primaryColorButton = Color(0xFF4C4F5E);
  Icon changeIcon = Icon(Icons.add);
  String private_call = 'Private Call';
  // bool selected = false;
  List<Contact> contacts = [];
  List<Contact> contactsFiltered = [];
  TextEditingController searchController = new TextEditingController();

  @override
  void initState() {
    super.initState();
    getAllContacts();
    searchController.addListener(() {
      filterContacts();
    });
  }

  String flattenPhoneNumber(String phoneStr) {
    return phoneStr.replaceAllMapped(RegExp(r'^(\+)|\D'), (Match m) {
      return m[0] == "+" ? "+" : "";
    });
  }

  filterContacts() {
    setState(() {
      List<Contact> _contacts = [];
      _contacts.addAll(contacts);
      if (searchController.text.isNotEmpty) {
        _contacts.retainWhere(
          (contact) {
            String searchTerm = searchController.text.toLowerCase();
            String searchTermFlatten = flattenPhoneNumber(searchTerm);
            String contactName = contact.displayName.toLowerCase();
            bool nameMatches = contactName.contains(searchTerm);
            if (nameMatches == true) {
              return true;
            }

            if (searchTermFlatten.isEmpty) {
              return false;
            }

            var phone = contact.phones.firstWhere((phn) {
              String phnFlattened = flattenPhoneNumber(phn.value);
              return phnFlattened.contains(searchTermFlatten);
            }, orElse: () => null);

            return phone != null;
          },
        );

        contactsFiltered = _contacts;
      }
    });
  }

  getAllContacts() async {
    List<Contact> _contacts = (await ContactsService.getContacts()).toList();
    setState(() {
      contacts = _contacts;
    });
  }

  @override
  Widget build(BuildContext context) {
    bool isSearching = searchController.text.isNotEmpty;
    return Scaffold(
      backgroundColor: Theme.of(context).primaryColor,
      body: Column(
        children: <Widget>[
          AppbarCustom(
            tMain: private_call,
          ),
          Expanded(
            child: Container(
              child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: <Widget>[
                    searchBar(context),
                    contactListView(isSearching),
                  ]),
            ),
          ),
        ],
      ),
    );
  }

  Expanded contactListView(bool isSearching) {
    return Expanded(
      child: ListView.builder(
        shrinkWrap: true,
        itemCount:
            isSearching == true ? contactsFiltered.length : contacts.length,
        itemBuilder: (context, index) {
          Contact contact =
              isSearching == true ? contactsFiltered[index] : contacts[index];

          return ListTile(
            onTap: () {
              // print(contact.isSelected);
              // print(contact.phones.elementAt(0).value);
              setState(() {
                (!contacts[index].isSelected)
                    ? contacts[index].isSelected = true
                    : contacts[index].isSelected = false;
              });
              print(index);
              print(contacts[index].isSelected);
            },
            selected: contacts[index].isSelected,
            title: Text(contact.displayName),
            subtitle: CardType(ttText: contact.phones.elementAt(0).value),
            leading: (contact.avatar != null && contact.avatar.length > 0)
                ? CircleAvatar(
                    backgroundImage: MemoryImage(contact.avatar),
                  )
                : CircleAvatar(
                    child: Text(contact.initials()),
                  ),
            trailing: (contacts[index].isSelected)
                ? Icon(Icons.check)
                : Icon(Icons.add),
          );
        },
      ),
    );
  }

  Container searchBar(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(15.0),
      child: TextField(
        controller: searchController,
        decoration: InputDecoration(
            labelText: 'Search',
            border: new OutlineInputBorder(
              borderSide: new BorderSide(
                color: Theme.of(context).primaryColor,
              ),
            ),
            prefixIcon: Icon(
              Icons.search,
              color: Colors.teal.shade300,
            )),
      ),
    );
  }
}

当我调试代码时,我发现由于这一行而发生错误

subtitle: CardType(ttText: contact.phones.elementAt(0).value)

在这个方法中contactListView(bool isSearching)

CardType() 只不过是文本小部件

4

2 回答 2

1

添加空处理程序检查器;作为 :

CardType(ttText: contact.phones?contact.phones.elementAt(0).value:'')

尝试运行您的代码,但遇到了一些问题。所以,我不能告诉你“waitContact()”出了什么问题,但你可以使用 FutureBuilder。像下面这样的东西应该可以工作:

return Scaffold(
            appBar: AppBar(
                title: Text("Enable Notifications"),
            ),
            body: FutureBuilder<bool>(
                future: waitContact(),  
                builder: (BuildContext context, AsyncSnapshot snapshot) {
                    if (snapshot.connectionState == ConnectionState.done) {
                        // YOUR CUSTOM CODE GOES HERE
                        return Column(
                          children: <Widget>[
                              AppbarCustom(
                                 tMain: private_call,
                              ),
                              Expanded(
                                 child: Container(
                                    child: Column(
                                       crossAxisAlignment:     CrossAxisAlignment.stretch,
                                       children: <Widget>[
                                            searchBar(context),
                                            contactListView(isSearching),
                                       ]),
                                  ),
                            ),
                       ],
  );
                    } else {
                        return new CircularProgressIndicator();
                    }
                }
            )
        );
于 2020-05-21T11:14:22.507 回答
0
leading: (contact.avatar != null)
                                          ? CircleAvatar(
                                              backgroundImage:
                                                  MemoryImage(contact.avatar),
                                            )
                                          : CircleAvatar(
                                              child: Text(contact.initials()),
                                            ),

参数类型“Uint8List?” 不能分配给参数类型“Uint8List”。

于 2021-11-25T11:19:05.777 回答