如何在Flutter中更改应用栏标题

16
**change the appbar title dynamically**
从数据库获取appbar标题,然后设置到appbar中。我是Flutter的新手,尝试了setState但仍然不起作用。如何根据服务器响应以及数据库值更改appbar文本?

使用Async/await和FutureBuilder从数据库中获取数据并在AppBar中使用setState()更新标题。

import 'dart:async';

import 'package:flutter/material.dart'; 
import 'package:parking_app/data/database_helper.dart'; 
import'package:parking_app/models/user.dart';

class HomeScreen extends StatefulWidget {   @override   State<StatefulWidget> createState() {
    return new HomeScreenState();   } }

class HomeScreenState extends State<HomeScreen> {   @override   Widget build(BuildContext context) {
    var db = new DatabaseHelper();
    Future<User> user = db.getUser();
    String appBarTitle = "eClerx Parking";
    var appBarTitleText = new Text(appBarTitle);
if (user != null) {
  user.then((val) {
    if (val == null) {
      return;
    }
    print(TAG+ "  user data : " + val.emailId);
    setState(() {
      build(context);
      appBarTitle = val.emailId;
    });
  });
}
return new MaterialApp(
  home: new Scaffold(
    appBar: new AppBar(
      title: appBarTitleText,
      actions: <Widget>[
        // action button
        new IconButton(
          icon: new Icon(Icons.settings_power),
          onPressed: () {
            _logout();
          },
        ),
        // action button
      ],
    ),
    body: new Padding(
      padding: const EdgeInsets.all(16.0),
      child: new ChoiceCard(choice: choices[0]),
    ),
  ),
);   } }
4个回答

11

如果您的数据库获取是异步的,您也可以拆分代码。

class HomeScreenState extends State<HomeScreen> {
     var appBarTitleText = new Text("eClerx Parking");

     Future getUser() async {
        var user = await db.getUser();

        if (user != null) {
           user.then((val) {
              if (val == null) {
                return;
              }
              print("user data : " + val.emailId);

              setState(() {
                appBarTitleText = Text(val.emailId);
             });
           });
        }
    }


    @override
       void initState() {
       super.initState();
       getUser();
    }

    @override
    Widget build(BuildContext context) {
    ...

3

不应该在build方法中执行所有操作。因为每次调用setState时,build方法都会重新绘制,所以你每次绘制时都初始化了String appBarTitle = "eClerx Parking";

你需要重写initState()方法并将这个逻辑放在里面。

var db = new DatabaseHelper();
    Future<User> user = db.getUser();
    String appBarTitle = "eClerx Parking";
    var appBarTitleText = new Text(appBarTitle);


if (user != null) {
  user.then((val) {
    if (val == null) {
      return;
    }
    print("user data : " + val.emailId);
    //DO THIS TO UPDATE THE STATE AND FORCE A REDRAW
    setState(() {
      appBarTitle = val.emailId;
    });
  });

此外,将 appBarTitle = val.emailId; 包裹在 setState() 函数中。

编辑:您没有等待来自数据库的结果 Future<User> user = db.getUser();,因此用户始终为 null,setState 从未被调用。

尝试使用 Future<User> user = await db.getUser();


2

更改

appBarTitle = val.emailId

to

setState(() {
  appBarTitle = val.emailId;
});

嘿,Günter!我认为他试图在build函数内完成所有操作,因此在那里调用setState可能不起作用。我尝试在下面回答了这个问题。如果我错了,请纠正我。 - Sebastian
那里不是理想的,但我不明白为什么它不能工作。 - Günter Zöchbauer
我的意思是,是的,你说得对,这不是理想的解决方法,但它应该能够正常工作。也许问题在于他没有等待来自db的响应Future<User> user = db.getUser();,所以用户将永远为空,并且不会调用setState,你觉得呢? - Sebastian
@GünterZöchbauer 对我的代码进行了更改,添加了setState方法,但仍无法正常工作。在日志中,打印方法被调用了无限次数。 - AKASH WANGALWAR

0

StatefulWidget 状态类内创建全局变量并将其命名为 appBar Title。

var appBarTitle ="some text";

将 appBar 标题分配给它

然后使用 setState 方法更改其值


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接