微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

颤抖-有人可以帮我让这个发布按钮执行吗?

如何解决颤抖-有人可以帮我让这个发布按钮执行吗?

希望大家今天过得不错。我还有另一个过去几天来一直困扰的问题。我试图将这些数据上传到我的Firestore实例,但是我的发布按钮似乎从未触发过。我试图从它调用方法中打印一条语句,但是我似乎也无法使它起作用。我正在尝试创建一个社交媒体应用,我们将不胜感激。

我的主要目标是让发布按钮在upload.dart中执行。

我还包括了home.dart,因为这两个类在性能上是相互联系的。

How the interface is supposed to look and function

upload.dart

import 'dart:io';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:Flutter/material.dart';
import 'package:Flutter_svg/Flutter_svg.dart';
import 'package:Fluttermedia/models/user.dart';
import 'package:Fluttermedia/pages/home.dart';
import 'package:Fluttermedia/widgets/progress.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:image/image.dart' as Im;
import 'package:uuid/uuid.dart';

class Upload extends StatefulWidget {
  final User currentUser;

  Upload({this.currentUser});

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

class _UploadState extends State<Upload> {
  TextEditingController locationController = TextEditingController();
  TextEditingController captionController = TextEditingController();
  File file;
  bool isuploading = false;
  String postId = Uuid().v4();

  handleChooseFromgallery() async{
    Navigator.pop(context);
    File file = await ImagePicker.pickImage(source: ImageSource.gallery);
    setState(() {
      this.file = file;
    });
  }

  handleTakePhoto() async {
    Navigator.pop(context);
    File file = await ImagePicker.pickImage(source: ImageSource.camera,maxHeight: 675,maxWidth: 960);
    setState(() {
      this.file = file;
    });
  }

  selectimage(parentContext){
    return showDialog(
        context: parentContext,builder: (context) {
          return simpledialog(
            title: Text("Create Post"),children: <Widget>[
              simpledialogOption(
                child: Text("Photo With Camera"),onpressed: handleTakePhoto,),simpledialogOption(
                child: Text("Image from gallery"),onpressed: handleChooseFromgallery,simpledialogOption(
                child: Text("Cancel"),onpressed: () => Navigator.pop(context),],);
      }
    );
  }

  Container buildSplashScreen(){
    return Container(
      color: Theme.of(context).accentColor.withOpacity(0.6),child: Column(
        mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
          SvgPicture.asset('assets/images/upload.svg',height: 260.0,Padding(
            padding: EdgeInsets.only(top:20.0),child: RaisedButton(
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(8.0),child: Text(
                "Upload Image",style: TextStyle(
                color: Colors.white,fontSize: 22.0,color: Colors.deepOrange,onpressed: () => selectimage(context),)
        ],);
  }

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

  //This compresses images for firebase
  compressImage() async{
    final tempDir = await getTemporaryDirectory();
    final path = tempDir.path;
    Im.Image imageFile = Im.decodeImage(file.readAsBytesSync());
    final compressedImageFile = File('$path/img_$postId.jpg')..writeAsBytesSync(Im.encodeJpg(imageFile,quality: 85));
    setState(() {
      file = compressedImageFile;
    });
  }

  Future<String> uploadImage(imageFile) async{
    StorageUploadTask uploadTask = storageRef.child("post_$postId.jpg").putFile(imageFile);
    StorageTaskSnapshot storageSnap = await uploadTask.onComplete;
    String downloadUrl = await storageSnap.ref.getDownloadURL();
    return downloadUrl;
  }

  //upload new info to firestore that creates a new collection
  createPostInFirestore({String mediaUrl,String location,String description}){
    postsRef.document(widget.currentUser.id)
        .collection("userPosts")
        .document(postId)
        .setData({
      "postId": postId,"ownerId": widget.currentUser.id,"username": widget.currentUser.username,"mediaUrl": mediaUrl,"description": description,"location": location,"timestamp": timeStamp,"likes":{}
        });
  }

  //Getting the info from the caption,location and pic
  handleSubmit() async{
    setState(() {
      isuploading = true;
    });
    await compressImage();
    String mediaUrl = await uploadImage(file);
    createPostInFirestore(
      mediaUrl: mediaUrl,location: locationController.text,description: captionController.text,);
    captionController.clear();
    locationController.clear();
    setState(() {
      file = null;
      isuploading = false;
    });
  }

  Scaffold buildUploadForm(){
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white70,leading: IconButton(
          icon: Icon(Icons.arrow_back,color: Colors.black,onpressed: clearImage,title: Text(
          "Caption Post",style: TextStyle(color: Colors.black),actions: <Widget>[
          FlatButton(
            onpressed: () => isuploading ? null : () => handleSubmit(),child: Text(
                "Post",style: TextStyle(
                color: Colors.blueAccent,fontWeight: FontWeight.bold,fontSize: 20.0,body: ListView(
        children: <Widget>[
          isuploading ? linearProgress(context):Text(""),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),ListTile(
            leading: CircleAvatar(
              backgroundImage: CachednetworkImageProvider(widget.currentUser.photoUrl),title: Container(
              width: 250.0,child: TextField(
                controller: captionController,decoration: Inputdecoration(
                  hintText: "Write a Caption...",border: InputBorder.none,Divider(),ListTile(
            leading: Icon(Icons.pin_drop,color: Colors.orange,size: 35.0),child: TextField(
                controller: locationController,decoration: Inputdecoration(
                  hintText: "Where was this photo taken",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 ? buildSplashScreen() : buildUploadForm();
  }
}


home.dart


import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:Flutter/cupertino.dart';
import 'package:Flutter/material.dart';
import 'package:Fluttermedia/models/user.dart';
import 'package:Fluttermedia/pages/activity_Feed.dart';
import 'package:Fluttermedia/pages/create_account.dart';
import 'package:Fluttermedia/pages/profile.dart';
import 'package:Fluttermedia/pages/search.dart';
import 'package:Fluttermedia/pages/upload.dart';
import 'package:google_sign_in/google_sign_in.dart';

final GoogleSignIn googleSignIn = GoogleSignIn();
final StorageReference storageRef = FirebaseStorage.instance.ref();
final usersRef = Firestore.instance.collection('users');
final postsRef = Firestore.instance.collection('posts');
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();
    // Detects if user signs in
    googleSignIn.onCurrentUserChanged.listen((account) {
      handleSignIn(account);
    },onError: (err){
      print('Error sigining in: $err');
    });
    //Reauthenticate user when app is opened
    googleSignIn.signInSilently(suppressErrors: false)
    .then((account) =>
        handleSignIn(account)).catchError((err){
          print('Error signing in on retry: $err');
    });

  }

  @override
  Widget build(BuildContext context) {
    return isAuth ? buildAuthScreen() : buildUnAuthScreen();
  }

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

  //Helper Functions
  //The sign in section of the code
  handleSignIn(GoogleSignInAccount account){
      if(account != null){
        createuserInFirestore();
        setState(() {
          isAuth = true;
        });
      }else{
        setState(() {
          isAuth = false;
        });
      }
  }

  login(){
    googleSignIn.signIn();
  }

  logout(){
    googleSignIn.signOut();
  }

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

  createuserInFirestore() async{
    // 1) Check if user exists in users collection in database (According to id)
    final GoogleSignInAccount user = googleSignIn.currentUser;
    DocumentSnapshot doc = await usersRef.document(user.id).get();
    if(!doc.exists){
      // 2) If the user doesn't exist,take them to create account page
      final username = await Navigator.push(context,MaterialPageRoute(builder: (context) => CreateAccount()));
      // 3) get username from create account,use it to make new user document in users collection
      usersRef.document(user.id).setData({
        "id":user.id,"username":username,"photoUrl": user.photoUrl,"email":user.email,"displayName": user.displayName,"bio":"","timeStamp": timeStamp,});
      doc = await usersRef.document(user.id).get();
    }
    currentUser = User.fromDocument(doc);
    //print(currentUser);
    //print(currentUser.username);
  }

  onTap(int pageIndex){
    //This what you would use to animate in between the different screens
    pageController.animatetoPage(
        pageIndex,duration: Duration(milliseconds: 300),curve: Curves.easeInOut
    );
  }

//UI Code
  Widget buildAuthScreen() {
    return Scaffold(
      body: PageView(
        children: <Widget>[
          //Timeline(),RaisedButton(
            child: Text('logout'),onpressed: logout,ActivityFeed(),Upload(currentUser: currentUser),Search(),Profile(),controller: pageController,onPageChanged: onPageChanged,physics: NeverScrollableScrollPhysics(),bottomNavigationBar: CupertinoTabBar(
        currentIndex: pageIndex,onTap: onTap,activeColor: Theme.of(context).primaryColor,items: [
          BottomNavigationBarItem(icon: Icon(Icons.whatshot),BottomNavigationBarItem(icon: Icon(Icons.notifications_active),BottomNavigationBarItem(icon: Icon(Icons.photo_camera,size: 34.0,BottomNavigationBarItem(icon: Icon(Icons.search),BottomNavigationBarItem(icon: Icon(Icons.account_circle),);

    /*return RaisedButton(
      child: Text('logout'),);*/
  }

  Scaffold buildUnAuthScreen() {
    return Scaffold(
      body: Container(
        width: MediaQuery.of(context).size.width,height: MediaQuery.of(context).size.height,decoration: Boxdecoration(
          gradient: LinearGradient(
            begin: Alignment.topRight,end: Alignment.bottomLeft,colors: [
              Theme.of(context).primaryColor,Theme.of(context).accentColor,]
          )
        ),child: Column(
          mainAxisAlignment: MainAxisAlignment.center,crossAxisAlignment: CrossAxisAlignment.center,children: <Widget>[
            Text('FlutterMedia',style: TextStyle(
              fontFamily: "Signatra",fontSize: 90.0,color: Colors.white
            ),GestureDetector(
              onTap:() => login(),child: Container(
                width: 260,height: 60,decoration: Boxdecoration(
                  image: decorationImage(
                    image: Assetimage('assets/images/google_signin_button.png'),fit: BoxFit.cover,)
          ],);
  }


}

解决方法

onPressed: () => isUploading ? null : () => handleSubmit(),

好吧,这是您的问题。您本应具有一个三级条件,当onPressed为假时,会使handleSubmit调用isUploading。相反,您已经将onPressed做成了一个返回函数的函数。

为了更清楚地说明这一点,让我们将此函数分解为适当的非lambda函数和if / else块:

onPressed: () {
  if (isUploading) {
    return null;
  } else {
    return () {
      handleUpload();
    }
  }
}

因此请考虑按下按钮时会发生什么。它调用外部函数,该函数检查isUploading。如果为true,则该函数返回null;如果为false,则返回另一个函数,如果调用该函数,则调用handleUpload。因此,这种播放方式是onPressed永远不会为null(有时只会返回null),并且永远不会调用handleUpload(因为返回的内部函数不会再被调用为自身)。

删除外部lambda,它将起作用:

onPressed: isUploading ? null : () => handleSubmit(),

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。