【问题标题】:Disable icon buttons in flutter在颤动中禁用图标按钮
【发布时间】:2021-07-19 01:22:38
【问题描述】:

我想根据 'flag' 变量中存储的值禁用图标按钮。

这是我的代码:

class PlaceTile extends StatelessWidget {
  

  final Place place;
  PlaceTile({ this.place });

  getUserById(String id) {
    
    DatabaseService().placesCollection.document(id).get().then((DocumentSnapshot doc) {
      print(doc.data);
  
    });

  }

  checkUserStatus() async {
    
     String flag='inactive';

    final FirebaseAuth auth = FirebaseAuth.instance;
    
    final FirebaseUser user  = await auth.currentUser();
    String uid = user.uid;
    UserDatabaseService().userCollection.getDocuments().then((QuerySnapshot snapshot) {
      snapshot.documents.forEach((DocumentSnapshot doc) {
        if(doc.documentID == uid)
        {
          if(doc.data['status']=='true')
          {
              flag = 'active';
          }
        }
        });
    });
    return flag;
  }


  String value;

  @override
  Widget build(BuildContext context) {
    void showQueueDetailsPanel() {
      showModalBottomSheet(context: context, builder: (context) {
        return Container(
          padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 60.0),
          child: QueueDetails(value: place.name),
        );
      });
    }
    return Padding(
      padding: EdgeInsets.only(top: 8.0),
      child: Card(
        margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0),
        child: ListTile(
          isThreeLine: true,
          leading: CircleAvatar(
            radius: 25.0,
            backgroundColor: Colors.white,
          ),
            title: Text(place.name),
            subtitle: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                //Text("People   "+place.totalPeople.toString()),
                Text(""),
                Text("Token    "+place.tokenAvailable.toString()),
              ],
            ),
            
            trailing: FlatButton.icon(
              icon: Icon(Icons.add_box_rounded),
              label: Text('Join'),
              onPressed: checkUserStatus()=='inactive' ?
              () async => showQueueDetailsPanel() : null,
            ),
          ),
        )
    );
    }
}

但是,即使onPressed 条件为“非活动”,所有“加入”按钮都被禁用。我尝试通过单独运行这两个函数来调试代码,看起来还不错。但是,每当我使用onPressed 条件来检查flag 变量时,所有按钮似乎都被禁用了,即使条件显然是正确的。

编辑 1

class PlaceTile extends StatelessWidget {
  

  final Place place;
  PlaceTile({ this.place });

  getUserById(String id) {
    
    DatabaseService().placesCollection.document(id).get().then((DocumentSnapshot doc) {
      print(doc.data);
  
    });

  }

  String checkUserStatus()  {
    
     String flag='inactive';

    final FirebaseAuth auth = FirebaseAuth.instance;
    
    //final FirebaseUser user  = await auth.currentUser();
    auth.currentUser().then((user) {
    String uid = user.uid;
    UserDatabaseService().userCollection.getDocuments().then((QuerySnapshot snapshot) {
      snapshot.documents.forEach((DocumentSnapshot doc) {
        if(doc.documentID == uid)
        {
          if(doc.data['status']=='true')
          {
              flag = 'active';
          }
        }
        });
    });

  });
      return flag;
  }


  String value;

  @override
  Widget build(BuildContext context) {
    void showQueueDetailsPanel() {
      showModalBottomSheet(context: context, builder: (context) {
        return Container(
          padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 60.0),
          child: QueueDetails(value: place.name),
        );
      });
    }
    return Padding(
      padding: EdgeInsets.only(top: 8.0),
      child: Card(
        margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0),
        child: ListTile(
          isThreeLine: true,
          leading: CircleAvatar(
            radius: 25.0,
            backgroundColor: Colors.white,
          ),
            title: Text(place.name),
            subtitle: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                //Text("People   "+place.totalPeople.toString()),
                Text(""),
                Text("Token    "+place.tokenAvailable.toString()),
              ],
            ),
            
            trailing: FlatButton.icon(
              icon: Icon(Icons.add_box_rounded),
              label: Text('Join'),
              onPressed: checkUserStatus()=='inactive' ?
              () async => showQueueDetailsPanel() : null,
            ),
          ),
        )
    );
    }
}

【问题讨论】:

    标签: flutter google-cloud-firestore


    【解决方案1】:

    您正在尝试使 Stateless 小部件具有状态。要使您的代码正常工作,您需要将 Stateless 小部件转换为 Statefull 小部件。

    您的代码如下所示:

    
    class PlaceTile extends StatefulWidget {
      final Place place;
      PlaceTile({this.place});
    
      @override
      _PlaceTileState createState() => _PlaceTileState();
    }
    
    class _PlaceTileState extends State<PlaceTile> {
      String flag = 'inactive';
    
      @override
      initState() {
        super.initState();
        checkUserStatus();
      }
    
      void getUserById(String id) {
        DatabaseService()
            .placesCollection
            .document(id)
            .get()
            .then((DocumentSnapshot doc) {
          print(doc.data);
        });
      }
    
      Future checkUserStatus() async {
        final FirebaseAuth auth = FirebaseAuth.instance;
    
        final FirebaseUser user = await auth.currentUser();
        String uid = user.uid;
        UserDatabaseService()
            .userCollection
            .getDocuments()
            .then((QuerySnapshot snapshot) {
          snapshot.documents.forEach((DocumentSnapshot doc) {
            if (doc.documentID == uid) {
              if (doc.data['status'] == 'true') {
                setState(() {
                  flag = 'active';
                });
              }
            }
          });
        });
        return flag;
      }
    
          void showQueueDetailsPanel() {
        showModalBottomSheet(
            context: context,
            builder: (context) {
              return Container(
                padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 60.0),
                child: QueueDetails(value: widget.place.name),
              );
            });
      }
    
    
      @override
      Widget build(BuildContext context) {
    
    
        return Padding(
            padding: EdgeInsets.only(top: 8.0),
            child: Card(
              margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0),
              child: ListTile(
                isThreeLine: true,
                leading: CircleAvatar(
                  radius: 25.0,
                  backgroundColor: Colors.white,
                ),
                title: Text(widget.place.name),
                subtitle: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    //Text("People   "+place.totalPeople.toString()),
                    Text(""),
                    Text("Token    " + widget.place.tokenAvailable.toString()),
                  ],
                ),
                trailing: FlatButton.icon(
                  icon: Icon(Icons.add_box_rounded),
                  label: Text('Join'),
                  onPressed: flag == 'inactive' ? showQueueDetailsPanel : null,
                ),
              ),
            ));
      }
    }
    
    

    【讨论】:

    • 对不起,我粘贴了原始代码。现在答案应该是正确的。
    【解决方案2】:
      String checkUserStatus() {
        String flag = 'inactive';
    
        final FirebaseAuth auth = FirebaseAuth.instance;
    
        auth.currentUser().then((user) {
          String uid = user.uid;
          UserDatabaseService()
              .userCollection
              .getDocuments()
              .then((QuerySnapshot snapshot) {
            snapshot.documents.forEach((DocumentSnapshot doc) {
              if (doc.documentID == uid) {
                if (doc.data['status'] == 'true') {
                  flag = 'active';
                }
              }
            });
          });
          return flag;
        });
      }
    
    onPressed: checkUserStatus() == 'inactive'
                      ? () async => showQueueDetailsPanel()
                      : null,
    

    如果 checkUserStatus() 用作异步函数,则应等待它或通过 .then() 访问其值。

    【讨论】:

    • 更新了答案
    • 可能是个愚蠢的问题,但数据中是否设置了标志 a?
    • 必须从函数返回才能访问该值。
    • 上面的小部件相当复杂,如果你可以简化它,或者把它改成一个有状态的小部件,这样更容易推理状态。调试起来会更容易。现在这里发生了很多事情。
    • 先用 FutureBuilder 试试这个,它应该更容易,因为异步的东西会更自然。万事如意!
    猜你喜欢
    • 2023-03-10
    • 2021-07-10
    • 2023-02-03
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 2021-09-14
    • 2023-02-07
    • 2023-03-21
    相关资源
    最近更新 更多