如何解决“NoSuchMethodError: The method 'findRenderObject' was called on null”错误?

时间:2021-05-17 08:55:29

标签: flutter google-cloud-firestore flutter-layout qr-code flutter-dependencies

我正在尝试保存 QR 图像并为此添加共享可选性,但在这样做时,我遇到了“findRenderObject 被调用为 null”对象。

我该如何解决这个错误?这是下面的代码

生成Qr.dart

import 'package:attendee/services/database.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'dart:ui';
import 'package:flutter/rendering.dart';
import 'package:intl/intl.dart';
import 'package:attendee/constants.dart';
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';

class GeneratePage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => GeneratePageState();
}

class GeneratePageState extends State<GeneratePage> {
  String qrData =
      "https://github.com/neon97"; // already generated qr code when the page opens
  FirebaseAuth auth = FirebaseAuth.instance;
  String subject;

  GlobalKey globalKey = new GlobalKey();

  final CollectionReference student_details =
      FirebaseFirestore.instance.collection('students');
  final CollectionReference tutor_details =
      FirebaseFirestore.instance.collection("tutors");

  String timeString;
  bool _validate = false;
  // String formattedDate = DateFormat('kk:mm:ss \n EEE d MMM').format(now);

  static const double _topSectionTopPadding = 50.0;
  static const double _topSectionBottomPadding = 20.0;
  static const double _topSectionHeight = 50.0;

  void _getTime() {
    final String formattedDateTime =
        DateFormat('yyyy-MM-dd \n kk:mm:ss').format(DateTime.now()).toString();
    //DateFormat('yyyy-MM-dd').toString();
    setState(() {
      timeString = formattedDateTime;
    });
  }

  @override
  void initState() {
    super.initState();
    Timer.periodic(Duration(seconds: 1), (Timer t) => _getTime());
  }

  @override
  Widget build(BuildContext context) {
    var numberOfClasses;
    return Scaffold(
      appBar: AppBar(
        title: Text('QR Code Generator'),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.share),
            onPressed: _captureAndSharePng,
          )
        ],
      ),
      body: SingleChildScrollView(
        child: Container(
          padding: EdgeInsets.all(20.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              QrImage(
                //plce where the QR Image will be shown
                data: qrData,
              ),
              SizedBox(
                height: 40.0,
              ),
              Text(
                "New QR Link Generator",
                style: TextStyle(fontSize: 20.0),
              ),
              TextField(
                controller: qrdataFeed,
                decoration: InputDecoration(
                  hintText: "SUBJECT-anything",
                  errorText:
                      _validate ? "Please enter in Sub-Date format!" : null,
                ),
              ),
              Padding(
                  padding: EdgeInsets.fromLTRB(40, 20, 40, 0),
                  child: MaterialButton(
                    minWidth: double.infinity,
                    height: 60,
                    onPressed: () async {
                      qrdataFeed.text
                              .contains(RegExp(r'^[a-zA-Z]*\-[a-zA-Z]*$'))
                          ? _validate = false
                          : _validate = true;
                      if (qrdataFeed.text.isEmpty) {
                        //a little validation for the textfield
                        if (!mounted) return;
                        setState(() {
                          qrData = "";
                        });
                      } else {
                        int index = qrdataFeed.text.indexOf('-');
                        subject = qrdataFeed.text.substring(0, index);
                        print("Subject name is $subject");
                        String user = isTutor ? "tutors" : "students";
                        String uid = FirebaseAuth.instance.currentUser.uid;
                        numberOfClasses = await FirebaseFirestore.instance
                            .collection(user)
                            .doc(uid)
                            .get()
                            .then((value) {
                          return value.data()['numberOfClasses'];
                        });
                        String rollno = await FirebaseFirestore.instance
                            .collection(user)
                            .doc(uid)
                            .get()
                            .then((value) {
                          return value.data()['rollno'];
                        });
                        print('$numberOfClasses is printed pehle');
                        await DatabaseService().attendance(rollno);

                        setState(() {
                          qrData = qrdataFeed.text;
                          scanned = true;
                          print('done');
                          numberOfClasses += 1; //idhar se dekhke
                          print('$numberOfClasses is printed');
                        });
                        await tutor_details.doc(uid).set(
                            {'numberOfClasses': numberOfClasses},
                            SetOptions(merge: true));
                      }
                    },
                    shape: RoundedRectangleBorder(
                        side: BorderSide(
                          color: Colors.black,
                        ),
                        borderRadius: BorderRadius.circular(50)),
                    child: Text(
                      "Generate QR",
                      style:
                          TextStyle(fontWeight: FontWeight.w600, fontSize: 18),
                    ),
                  )),
            ],
          ),
        ),
      ),
    );
  }

  final qrdataFeed = TextEditingController();
  Future<void> _captureAndSharePng() async {
    try {
      RenderRepaintBoundary boundary =
          globalKey.currentContext.findRenderObject();
      print(boundary);
      var image = await boundary.toImage();
      ByteData byteData = await image.toByteData(format: ImageByteFormat.png);
      Uint8List pngBytes = byteData.buffer.asUint8List();

      final tempDir = await getTemporaryDirectory();
      final file = await new File('${tempDir.path}/image.png').create();
      await file.writeAsBytes(pngBytes);

      final channel = const MethodChannel('channel:me.attendee.share/share');
      channel.invokeMethod('shareFile', 'image.png');
    } catch (e) {
      print(e.toString());
    }
  }
}

1 个答案:

答案 0 :(得分:0)

错误在这里:

RenderRepaintBoundary boundary = globalKey.currentContext.findRenderObject();

尝试使用 context 更改 globalKey.currentContext 并查看错误是否已解决

再见:D