如何在ListTile中保存按钮的状态并使按钮异步?

时间:2020-07-21 20:17:16

标签: flutter dart button async-await future

我试图通过保存功能向ListTile添加按钮。 要实现保存功能,我需要一个帖子ID,以便我可以分配从ListTileTree传递的正确标题。

这时的问题是它是一个最终值。因此,我使用Google并找到了Stackoverflow - How to resolve “Only static members can be accessed in initializers” in flutter?

我使用了最后一个答案将其置于Init状态,但现在我得到了诸如“将getter'scrollOffsetCorrection'调用为null的异常。 收件人:空”。

我该如何解决?

这是导致错误的部分:

class PostState extends State<_Post> {
  final PostModel post;

  PostState({
    Key key,
    @required this.post,
  })  : assert(post != null),
        super();

  static bool liked = false;

  @override
  void initState() {
    bool _liked = IsLiked.initializeLike(post.postId);
    liked = _liked;
  }

  _pressed() async {
    if (liked == true) {
      setState(() {
        liked = false;
      });
      IsLiked.deleteLike(post.postId);
    } else {
      liked = true;
      IsLiked.like(post);
      setState(() {
        liked = true;
      });
    }

    final directory = await getApplicationDocumentsDirectory();
  }

  @override
  Widget build(BuildContext context) {
    return IconButton(
      icon: new Icon(liked ? Icons.favorite : Icons.favorite_border,
          color: liked ? Colors.red : Colors.grey),
      onPressed: () => _pressed(),
    );
  }

IsLiked.initializeLike(post.postId)实际上仅返回false,因为没有保存收藏夹

更新:我认为解决方案的一部分是Future Builder,因为IsLiked.initializeLike(post.postId)是异步的,所以我实现了一个Future Icon,它返回了Icon Button。现在的问题是,我得到另一个错误:“跟踪小部件会占用整个图块宽度。请使用大小大小的小部件。” 一些可以帮助我的想法或链接?

这是我的新解决方案的代码:

@override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: IsLiked.initializeLike(post.postId),
      builder: (BuildContext context, AsyncSnapshot<dynamic> snap){
        print(liked);
        return IconButton(
          icon: new Icon(liked ? Icons.favorite : Icons.favorite_border,
              color: liked ? Colors.red : Colors.grey),
          onPressed: () => _pressed(),
        );
      },
    );

Update2: 好吧,我找到了一个几乎可行的解决方案。铸造喜欢的未来。 但是现在的问题是,如何比较未来的状态是对还是错?

更新的代码:

static Future<bool> _liked = test();

  static Future<bool> test() async{
    final directory = await getApplicationDocumentsDirectory();
    return false;
  }
  static bool liked = false;

 @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _liked,
      builder: (BuildContext context, AsyncSnapshot<bool> snapshot){
        if(snapshot.hasData){
          return IconButton(
            icon: new Icon(liked ? Icons.favorite : Icons.favorite_border,
                color: liked ? Colors.red : Colors.grey, size: 30),
            onPressed: () => _pressed(),
          );
        }else{
          return CircularProgressIndicator(
            backgroundColor: Hexcolor("#FFFFFF"),
            valueColor: new AlwaysStoppedAnimation<Color>(Hexcolor('#FE2E2E')));
        }
      },
    );

  }

这是整个班级。

import 'package:Kontra/api/models.dart';
import 'package:Kontra/pages/articel.dart';
import 'package:Kontra/utils/is_liked.dart';
import 'package:Kontra/utils/picture_revision.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:path_provider/path_provider.dart';

class Post extends StatelessWidget {
  final PostModel post;

  const Post({
    Key key,
    @required this.post,
  })  : assert(post != null),
        super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListTile(
      leading: CachedNetworkImage(
        imageUrl: PictureRevision.revisePicture(post.pictures),
        placeholder: (context, url) => CircularProgressIndicator(
          backgroundColor: Hexcolor("#FFFFFF"),
          valueColor: new AlwaysStoppedAnimation<Color>(Hexcolor('#FE2E2E')),
        ),
        errorWidget: (context, url, error) => Icon(Icons.error),
        width: 60.0,
        height: 60.0,
        alignment: Alignment.centerRight,
      ),
      title: Text(post.title, textAlign: TextAlign.left),
      onTap: () => Navigator.of(context).push(
        MaterialPageRoute(builder: (context) => articel(post: post)),
      ),
      trailing: _Post(post: post),
    );
  }
}

class _Post extends StatefulWidget {
  final PostModel post;

  const _Post({
    Key key,
    @required this.post,
  })  : assert(post != null),
        super(key: key);

  @override
  PostState createState() => new PostState(
        post: post,
      );
}

class PostState extends State<_Post> {
  final PostModel post;

  PostState({Key key, @required this.post})
      : assert(post != null),
        super();

  static Future<bool> _liked = test();

  static Future<bool> test() async{
    final directory = await getApplicationDocumentsDirectory();
    return false;
  }
  static bool liked = false;

  _pressed() async {
    if (liked == true) {
      setState(() {
        liked = false;
      });
      IsLiked.deleteLike(post.postId);
    } else {
      liked = true;
      IsLiked.like(post);
      setState(() {
        liked = true;
      });
    }
    final directory = await getApplicationDocumentsDirectory();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _liked,
      builder: (BuildContext context, AsyncSnapshot<bool> snapshot){
        if(snapshot.hasData){
          return IconButton(
            icon: new Icon(liked ? Icons.favorite : Icons.favorite_border,
                color: liked ? Colors.red : Colors.grey, size: 30),
            onPressed: () => _pressed(),
          );
        }else{
          return CircularProgressIndicator(
            backgroundColor: Hexcolor("#FFFFFF"),
            valueColor: new AlwaysStoppedAnimation<Color>(Hexcolor('#FE2E2E')));
        }
      },
    );

  }
}


1 个答案:

答案 0 :(得分:0)

好的,最后我找到了解决方案。它与将来的构建器一起使用,我不得不使用liked = snapshot.data

初始化内部喜欢的对象

最后一堂课是这样的:

class PostState extends State<_Post> {
  final PostModel post;

  PostState({Key key, @required this.post})
      : assert(post != null),
        super();

  static Future<bool> _liked = test();

  static Future<bool> test() async{
    final directory = await getApplicationDocumentsDirectory();
    return false;
  }
  static bool liked;

  _pressed() async {

    if (liked == true) {
      setState(() {
        liked = false;
      });
      IsLiked.deleteLike(post.postId);
    } else {
      liked = true;
      IsLiked.like(post);
      setState(() {
        liked = true;
      });
    }
    final directory = await getApplicationDocumentsDirectory();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _liked,
      builder: (BuildContext context, AsyncSnapshot<bool> snapshot){
        if(snapshot.hasData){
          liked = snapshot.data;
          return IconButton(
            icon: new Icon(liked ? Icons.favorite : Icons.favorite_border,
                color: liked ? Colors.red : Colors.grey, size: 30),
            onPressed: () => _pressed(),
          );
        }else{
          return CircularProgressIndicator(
            backgroundColor: Hexcolor("#FFFFFF"),
            valueColor: new AlwaysStoppedAnimation<Color>(Hexcolor('#FE2E2E')));
        }
      },
    );

  }
}