我遇到了“图像 url 被调用为 null”的问题。我已经定义了ImageUrl
,但我不知道问题出在哪里。
我在add_contact.dart
中添加了future builder,但是问题没有解决。我不知道我应该在哪里使用 future builder。
这是我的代码:
home_page.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:pop/widgets/add_contact.dart';
import 'package:pop/widgets/user_item.dart';
import '../providers/user.dart';
import 'package:provider/provider.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
final products = Provider.of<Users>(context).items;
return Scaffold(
appBar: AppBar(
title: Text('Pop'),
actions: [
PopupMenuButton(
child: Icon(Icons.more_vert, color: Colors.white),
itemBuilder: (context) => [
PopupMenuItem(
child: Text('add account to chat'),
value: 'add',
),
PopupMenuItem(
child: Text('logout'),
value: 'logout',
),
],
onSelected: (val) {
switch (val) {
case 'logout':
FirebaseAuth.instance.signOut();
break;
case 'add':
showModalBottomSheet(
context: context,
builder: (ctx) => AddContact(),
);
break;
default:
}
},
),
],
),
body: ListView.builder(
itemCount: products.length,
itemBuilder: (ctx, i) => ChangeNotifierProvider.value(
value: products[i],
child: UserButton(
products[i].imageUrl,
products[i].name,
products[i].phoneNumber,
),
),
),
);
}
}
user.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:intl_phone_number_input/intl_phone_number_input.dart';
class UserItem with ChangeNotifier {
final String name;
final String phoneNumber;
final String imageUrl;
UserItem({
@required this.name,
@required this.phoneNumber,
@required this.imageUrl,
});
}
class Users with ChangeNotifier {
List<UserItem> _items = [];
List<UserItem> get items {
return [..._items];
}
Future<void> addItem(String phone) async {
UserItem newItem;
await FirebaseFirestore.instance
.collection('users')
.where('phone_number', isEqualTo: phone)
.get()
.then(
(QuerySnapshot value) => value.docs.forEach(
(element) {
newItem = UserItem(
name: element['username'],
phoneNumber: element['phone_number'],
imageUrl: element['image_url'],
);
},
),
);
_items.add(newItem);
notifyListeners();
}
}
add_contact.dart
import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:intl_phone_number_input/intl_phone_number_input.dart';
import 'package:provider/provider.dart';
import '../providers/user.dart';
class AddContact extends StatefulWidget {
@override
_AddContactState createState() => _AddContactState();
}
class _AddContactState extends State<AddContact> {
PhoneNumber number;
bool isLoading = false;
final Stream<DocumentSnapshot> _query = FirebaseFirestore.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser.uid)
.snapshots();
@override
Widget build(BuildContext context) {
return Form(
child: Container(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom + 10),
child: SingleChildScrollView(
child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
StreamBuilder<DocumentSnapshot>(
stream: _query,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
}
return InternationalPhoneNumberInput(
initialValue: PhoneNumber(
isoCode: snapshot.data['iso_code'],
),
onInputChanged: (val) {
number = val;
},
);
},
),
isLoading
? CircularProgressIndicator()
: RaisedButton.icon(
color: Colors.amber,
onPressed: () {
FutureBuilder(
future: Provider.of<Users>(context, listen: false)
.addItem(number.phoneNumber),
builder: (ctx, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
isLoading = true;
}
isLoading = false;
},
);
Navigator.of(context).pop();
},
label: Text('add contact'),
icon: Icon(Icons.add),
),
],
),
),
),
);
}
}