【问题标题】:how to repeat the same future function each time another function is called?每次调用另一个函数时如何重复相同的未来函数?
【发布时间】:2020-12-09 12:18:59
【问题描述】:

我试图在显示消息之前显示一个打字指示器,我已经尝试了下面的代码,但它只显示一次打字指示器(仅适用于第一条消息),我想要的是每次都显示它我想打印一条消息。

这是修改后,第一条消息后的代码仍然没有再次显示打字指示

import 'package:bubble/bubble.dart';
import 'package:flutter/material.dart';
import 'package:flutter_chat_bubble/bubble_type.dart';
import 'package:flutter_chat_bubble/chat_bubble.dart';
import 'package:flutter_chat_bubble/clippers/chat_bubble_clipper_2.dart';
import 'package:flutter_dialogflow/dialogflow_v2.dart';
import 'package:progress_indicators/progress_indicators.dart';

void main() {
  runApp(Bot());
}

class Bot extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'bot',
      theme: ThemeData(
        primarySwatch: Colors.grey,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      debugShowCheckedModeBanner: false,
      home: HomePage(title: 'bot'),
    );
  }
}

class HomePage extends StatefulWidget {
  HomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  bool _nextWidget = false;
  @override
  void initState() {
    super.initState();
  }

  void myMethod(){
    Future.delayed(
        const Duration(
          seconds: 5,
          milliseconds: 500,
        ),
            () {
          if (this.mounted) {
            setState(() {
              _nextWidget = true;
            });
          }
        });
  }
  void response(query) async {
    AuthGoogle authGoogle = await AuthGoogle(
        fileJson: "assets/credentials.json").build();
    Dialogflow dialogflow =
    Dialogflow(authGoogle: authGoogle, language: Language.english);
    AIResponse aiResponse = await dialogflow.detectIntent(query);
    setState(() {
      messsages.insert(0, {
        "data": 0,
        "message": aiResponse.getListMessage()[0]["text"]["text"][0].toString()
      });
    });
    print(aiResponse.getListMessage()[0]["text"]["text"][0].toString());
  }
  final messageInsert = TextEditingController();
  List<Map> messsages = List();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor:  Colors.grey[850],
      appBar: AppBar(
        leading: IconButton(icon: Icon(Icons.menu, color: Colors.white, size: 45)),
        backgroundColor: Colors.grey[800],
      ),
      body: Container(
        child: Column(
          children: [
            Flexible(
              child: ListView.builder(
                  reverse: true,
                  itemCount: messsages.length,
                  itemBuilder: (context, index) => chat(
                      messsages[index]["message"].toString(),
                      messsages[index]["data"])
              ),
            ),
            Container(
              color: Colors.grey[850],
              child: ListTile(
                leading: IconButton(
                  icon: Icon(Icons.mic_off, color: Colors.white, size: 35),
                ),
                title: Container(
                  height: 45,
                  decoration: BoxDecoration(
                    shape: BoxShape.rectangle,
                    borderRadius: BorderRadius.all(Radius.circular(10)),
                    color: Colors.white,
                  ),
                  padding: EdgeInsets.only(left: 10),
                  child: TextFormField(
                    cursorColor: Colors.grey[850],
                    controller: messageInsert,
                    decoration: InputDecoration(
                      hintText: "Chat with me",
                      hintStyle: TextStyle(
                          color: Colors.black
                      ),
                    ),
                    style: TextStyle(
                        fontSize: 16,
                        color: Colors.black
                    ),
                    onChanged: (value) {}
                  )
                ),
                trailing:
                IconButton(
                    icon: Icon(
                      Icons.send,
                      size: 30.0,
                      color: Colors.greenAccent,
                    ),
                    onPressed: () {
                      if (messageInsert.text.isEmpty) {
                        print("empty message");
                      } else {
                        setState(() {
                          messsages.insert(0,
                              {"data": 1, "message": messageInsert.text});
                        });
                        response(messageInsert.text);
                        messageInsert.clear();
                      }
                      FocusScopeNode currentFocus = FocusScope.of(context);
                      if (!currentFocus.hasPrimaryFocus) {
                        currentFocus.unfocus();
                      }
                    })
              )
            ),
            SizedBox(height: 10.0)
          ]
        ),
      )
    );
  }

  Widget bot(String message) {
    myMethod();
    return _nextWidget ?  botMessage(message) : botInd();
  }

  Widget botInd() {
    return Container(
        alignment: Alignment.bottomLeft,
        margin: EdgeInsets.only(top: 20),
        child: Container(
            constraints: BoxConstraints(maxWidth: 75, maxHeight: 100),
            child: JumpingDotsProgressIndicator(fontSize: 50.0, color: Colors.white)
        )
    );
  }

  Widget botMessage(String message) {
    return ChatBubble(
        clipper: ChatBubbleClipper2(type: BubbleType.receiverBubble),
        alignment: Alignment.bottomLeft,
        margin: EdgeInsets.only(top: 20),
        backGroundColor: Colors.white,
        child: Container(
            constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.7),
            child: Text(
                message,
                style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)
            )
        )
    );
  }

  Widget user(String message) {
    return ChatBubble(
        clipper: ChatBubbleClipper2(type: BubbleType.sendBubble),
        alignment: Alignment.bottomRight,
        margin: EdgeInsets.only(top: 20),
        backGroundColor: Colors.white,
        child: Container(
            constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.7),
            child: Text(
                message,
                style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)
            )
        )
    );
  }

  Widget chat(String message, int data) {
    return data == 0 ? bot(message) : user(message);
  }
}

【问题讨论】:

  • 这是因为任何状态对象的init状态只运行一次
  • 我该如何解决这个问题,让它可以运行多次?

标签: flutter dart flutter-layout flutter-animation


【解决方案1】:

initState 方法在您的代码出现在屏幕上之前运行 1 次。因此,我建议您使用您在 initState 方法中编写并希望运行的代码块,通过创建一个不同于 initState 的新方法,例如:

void myMethod(){

  Future.delayed(
    const Duration(
      seconds: 7,
      milliseconds: 500,
    ),
        () {
      if (this.mounted) {
        setState(() {
          _nextWidget = !_nextWidget;
    });
  }
});}

之后,尝试调用“myMethod”。

希望这对你有用。

【讨论】:

  • 方法一直重复没有用,所以输出一直在指标和消息之间切换
  • 您像我说的那样创建了一个新方法,但您的 initState 中仍然有这些代码,当您创建名为“myMethod”的方法时,您需要在 initState 中删除这些代码。因为您将在要使用的地方使用新创建的方法
  • 你像我说的那样创建了方法,但是你从来没有在任何地方调用过那个方法,你能不能在你想执行的时候调用那个方法
  • 我尝试这样做但仍然无法正常工作,它会不断重复,而不是在显示消息时停止。
  • 我认为问题是,您在“myMethod”方法中将 _nextWidget 变量设为 true,但您再也不会设为 false,并且每 5.5 秒 botMessage 都会返回:Widget bot(String message) { myMethod(); return _nextWidget ? botMessage(message) : botInd(); } 如果 _nextWidget 为 true,则返回 botMessage。当您执行“myMethod”时,您将其设为真,但您不会再次将其设为假。
猜你喜欢
  • 2015-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-14
  • 1970-01-01
  • 2017-03-07
  • 1970-01-01
相关资源
最近更新 更多