在颤振中调用 PhotoURL 时出现空错误 [重复]

Posted

技术标签:

【中文标题】在颤振中调用 PhotoURL 时出现空错误 [重复]【英文标题】:PhotoURL was called on null error in flutter [duplicate] 【发布时间】:2021-02-06 15:21:08 【问题描述】:

在我的颤振项目中,我使用了 CachedNetworkImageProvider,我在其中传递了照片 url,但它向我显示了一个错误,它被称为 null。任何人都可以帮助我吗?查看第 158 行。如果您认为这部分没有任何问题,并且是其他一些小部件导致错误,(由我制作),那么请告诉我,我会为您提供。请帮我。我对这件事很陌生。

这是个例外 -

The getter 'photoUrl' was called on null.
Receiver: null
Tried calling: photoUrl
The relevant error-causing widget was: 
  Upload file:///C:/Users/Hp/androidStudioProjects/social_app/lib/pages/home.dart:117:11

这是代码 -

import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:image_picker/image_picker.dart';
import 'package:social_app/models/users.dart';

class Upload extends StatefulWidget 

  final User currentUser;
  Upload(this.currentUser);

  @override
  _UploadState createState() => _UploadState();


class _UploadState extends State<Upload> 

  File file;
  handleTakePhoto() async 
    Navigator.pop(context);
    File file = await ImagePicker.pickImage(source: ImageSource.camera, maxWidth: 960, maxHeight: 675);
    // ImagePicker imagePicker;
    // PickedFile pickedFile = await imagePicker.getImage(source: ImageSource.camera, maxHeight: 675, maxWidth: 960);
    // File file = File(pickedFile.path);
    setState(() 
      this.file = file;
    );
  

  handleChooseFromGallery() async
    Navigator.pop(context);
    File file = await ImagePicker.pickImage(source: ImageSource.gallery);
    setState(() 
      this.file = file;
    );
    // ImagePicker imagePicker;
    // PickedFile pickedFile = await imagePicker.getImage(source: ImageSource.gallery);
    // File file = File(pickedFile.path);
    // setState(() 
    //   this.file = file;
    // );
  

  selectImage(parentContext) 
    return showDialog(
      context: parentContext,
      builder: (context) 
        return SimpleDialog(
          title: Text('Create Post'),
          children: <Widget>[
            SimpleDialogOption(
              child: Text('Click Photo'),
              onPressed: handleTakePhoto,
            ),
            SimpleDialogOption(
              child: Text('Import from Gallery'),
              onPressed: handleChooseFromGallery,
            ),
            SimpleDialogOption(
              child: Text('Cancel'),
              onPressed: () => Navigator.pop(context),
            ),
          ],
        );
      
    );
  

  Container buildSplashScreen() 
    return Container(
      color: Colors.black54,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          SvgPicture.asset('assets/images/upload.svg', height: 300.0,),
          Padding(
            padding: EdgeInsets.only(top: 40.0),
            child: RaisedButton(
              padding: EdgeInsets.all(10.0),
              shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
              child: Text(
                'Upload Image',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 30.0,
                ),
              ),
              color: Colors.blueGrey[600],
              onPressed: () => selectImage(context),
            ),
          ),
        ],
      ),
    );
  

  clearImage() 
    setState(() 
      file =null;
    );
  

  Scaffold buildUploadForm() 
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white70,
        leading: IconButton(
          icon: Icon(Icons.arrow_back, color: Colors.black,),
          onPressed: clearImage,
        ),
        title: Center(
          child: Text(
            'Caption Post',
            style: TextStyle(
              color: Colors.black,
            ),
          ),
        ),
        actions: [
          FlatButton(
            onPressed: () => print('Pressed'),
            child: Text(
              'Post',
              style: TextStyle(
                color: Colors.blueAccent,
                fontWeight: FontWeight.bold,
                fontSize: 20.0,
              ),
            ),
          ),
        ],
      ),
      body: ListView(
        children: <Widget>[
          Container(
            height: 220.0,
            width: MediaQuery.of(context).size.width * 0.8,
            child: Center(
              child: AspectRatio(
                aspectRatio: 16/9,
                child: Container(
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      fit: BoxFit.cover,
                      image: FileImage(file),
                    ),
                  ),
                ),
              ),
            ),
          ),
          Padding(
            padding: EdgeInsets.only(top: 10.0),
          ),
          ListTile(
            leading: CircleAvatar(
              backgroundImage: CachedNetworkImageProvider(widget.currentUser.photoUrl),
            ),
            title: Container(
              width: 250.0,
              child: TextField(
                  decoration: InputDecoration(
                  hintText: "Write a caption..",
                    border: InputBorder.none,
                ),
              ),
            ),
          ),
          Divider(

          ),
          ListTile(
            leading: Icon(
              Icons.pin_drop,
              color: Colors.blue,
              size: 36.0,
            ),
            title: Container(
              width: 250.0,
              child: TextField(
                decoration: InputDecoration(
                  hintText: 'Search a location...',
                  border: InputBorder.none,
                ),
              ),
            ),
          ),
          Container(
            width: 200.0,
            height: 100.0,
            alignment: Alignment.center,
            child: RaisedButton.icon(
              label: Text(
                'Use current location...',
                style: TextStyle(
                  color: Colors.white,
                ),
              ),
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(30.0),
              ),
              color: Colors.blue,
              onPressed: () => print('Get user location'),
              icon: Icon(
                Icons.my_location,
                color: Colors.white,
              ),
            ),
          ),
        ],
      ),
    );
  

  @override
  Widget build(BuildContext context) 
    return file == null ? SafeArea(
      child: Scaffold(
        backgroundColor: Colors.black45,
        body: buildSplashScreen(),
      ),
    ) : buildUploadForm();
  

主页 -

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:social_app/pages/activity_feed.dart';
import 'package:social_app/pages/create_account.dart';
import 'package:social_app/pages/profile.dart';
import 'package:social_app/pages/search.dart';
import 'package:social_app/pages/timeline.dart';
import 'package:social_app/pages/upload.dart';
import 'package:social_app/widgets/header.dart';
import 'package:social_app/models/users.dart';

final GoogleSignIn googleSignIn = GoogleSignIn();
final usersRef = FirebaseFirestore.instance.collection('users');
final DateTime timeStamp = DateTime.now();
User currentUser;

class Home extends StatefulWidget 
  @override
  _HomeState createState() => _HomeState();


class _HomeState extends State<Home> 
  bool isAuth = false;
  PageController pageController;
  int pageIndex=0;

  @override
  void initState()
    super.initState();
    pageController = PageController(initialPage: 0);
    googleSignIn.onCurrentUserChanged.listen((account) 
      handleSignIn(account);
    ,
    onError: (error) 
      print("Error in signing in : $error");
    );
    googleSignIn.signInSilently(suppressErrors: false).then((account)
      handleSignIn(account);
    ).catchError((error)
      print("Error in signing in : $error");
    );
  

  handleSignIn(GoogleSignInAccount account) 
    if (account != null) 
      createUserInFirestore();
      setState(() 
        isAuth = true;
      );
    
    else 
      setState(() 
        isAuth = false;
      );
    
  

  createUserInFirestore() async
    final GoogleSignInAccount user = googleSignIn.currentUser;
    DocumentSnapshot doc = await usersRef.doc(user.id).get();

    if(!doc.exists) 
      final username = await Navigator.push(context, MaterialPageRoute(builder: (context) => CreateAccount()));
      usersRef.doc(user.id).set(
        "id" : user.id,
        "username" : username,
        "photoUrl" : user.photoUrl,
        "email" : user.email,
        "displayName" : user.displayName,
        "bio" : "",
        "timeStamp" : timeStamp,
      );
    
  

  @override
  void dispose() 
    pageController.dispose();
    super.dispose();
  

  login() 
    googleSignIn.signIn();
  

  logout() 
    googleSignIn.signOut();
  

  onPageChanged(int pageIndex) 
    setState(() 
      this.pageIndex = pageIndex;
    );
  

  onTap(int pageIndex) 
    pageController.animateToPage(
      pageIndex,
      duration: Duration(milliseconds: 250),
      curve: Curves.easeInOut,
    );
  

  Scaffold buildAuthScreen()
    return Scaffold(
      body: PageView(
        children: <Widget>[
          //Timeline(),
          RaisedButton(
             onPressed: logout,
             child: Text('logout'),
           ),
          Search(),
          Upload(currentUser: currentUser),
          ActivityFeed(),
          Profile(),
        ],
        controller: pageController,
        onPageChanged: onPageChanged,
        physics: NeverScrollableScrollPhysics(),
      ),
      bottomNavigationBar: CupertinoTabBar(
        backgroundColor: Colors.black,
        currentIndex: pageIndex,
        onTap: onTap,
        activeColor: Colors.white,
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home_filled)),
          BottomNavigationBarItem(icon: Icon(Icons.search)),
          BottomNavigationBarItem(icon: Icon(Icons.add_box_outlined)),
          BottomNavigationBarItem(icon: Icon(Icons.favorite_border)),
          BottomNavigationBarItem(icon: Icon(Icons.account_circle)),
        ],
      ),
    );
    // return RaisedButton(
    //   onPressed: logout,
    //   child: Text('logout'),
    // );
  

  Scaffold buildUnauthScreen() 
    return Scaffold(
      appBar: header(context, titleText: 'Instagram'),
      backgroundColor: Colors.black,
      body: SafeArea(
        child: Container(
          decoration: BoxDecoration(
            gradient: LinearGradient(
              begin: Alignment.topRight,
              end: Alignment.bottomLeft,
              colors: [
                Theme.of(context).primaryColor,
                Colors.teal.withOpacity(1.0),
                Colors.orange,
              ]
            ),
          ),
          alignment: Alignment.center,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Text(
                'Technua',
                style: GoogleFonts.gochiHand(
                  fontSize: 70.0,
                  color: Colors.white,
                ),
              ),
              GestureDetector(
                onTap: login,
                child: Container(
                  height: 60.0,
                  width: 260.0,
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: AssetImage('assets/images/google_signin_button.png'),
                      fit: BoxFit.cover,
                    )
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  

  @override
  Widget build(BuildContext context) 
    return isAuth ? buildAuthScreen() : buildUnauthScreen();
  

【问题讨论】:

@nvoigt 我已经在其中初始化它的构造函数呢?? 我猜你没有?您是否有一行将某些非 null 的内容传递给构造函数? 我已经编辑了这个问题,你能检查一下吗,见行号。 117首页。 @nvoigt 你是对的,我只是忘记在 home.dart 中添加这些语句 - doc = await usersRef.doc(user.id).get(); currentUser = User.fromDocument(doc); 【参考方案1】:

您的当前用户为空。您必须在此处设置用户:

    final User currentUser;

【讨论】:

【参考方案2】:

您在StatefulWidget Upload 中创建了一个可选的命名参数currentUser。我认为您在Upload 小部件中传递的用户是null

您必须检查您从哪里调用Upload 小部件,然后检查用户是否为null

但是,如果currentUsernull,您可以使用null 感知运算符来防止错误,如下所示:

leading: CircleAvatar(
           backgroundImage: CachedNetworkImageProvider(
                              widget.currentUser?.photoUrl,  // <-----
                            ),
         ),

【讨论】:

不是构造函数初始化的吗?? 它由构造函数使用传递给它的值进行初始化。如果您将null 作为参数传递,那么它将使用null 初始化currentUser

以上是关于在颤振中调用 PhotoURL 时出现空错误 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

在 Android N 中调用位置时出现空点异常。 [重复]

如何在 Razorpages 教程中处理添加迁移时出现空参数错误

在刷卡器中从 php 加载图像时出现空错误

使用 Kotlin 在片段中引用 RecyclerView 时出现空指针错误

有时在调用时与对手创建 QBRTCSession 时出现空指针异常

从活动调用片段方法时出现空指针异常