【问题标题】:How to build another Widget inside a button's onTap function如何在按钮的 onTap 函数中构建另一个小部件
【发布时间】:2020-03-11 16:21:19
【问题描述】:

编辑(第 2 次): 我将状态从有状态小部件更改为无状态小部件,结果证明我可以解决问题。

编辑: 所以我犯了一个错误,我不应该在 onTap 函数中创建一个小部件,相反,我应该在某处实例化 CardMatcher,然后访问 CardMatcher,发送按钮的关键字,并让 CardMatcher 在单击按钮时为我检查关键字.

任何想法如何做到这一点?谁能帮我写一个简单的代码?

换句话说,我想制作一个可以检查是否有两个按钮被点击的小部件。该小部件应该在另一个文件中,以便可以重复使用。 ーーーー

所以我制作了一个自定义按钮,它将关键字传递给另一个检查关键字的小部件 (CardMatcher)。如果两个按钮具有相同的关键字,则小部件 (CardMatcher) 将对其进行处理。

按钮被点击时会传递关键字。可悲的是,什么也没有发生。没有检测到错误,但应用程序也没有构建 CardMatcher。这是按钮的代码:


import 'package:flutter/material.dart';
import 'package:fluttermatchcard/cardMatcher.dart';
import 'package:fluttermatchcard/cardMatcher.dart';
import 'package:fluttermatchcard/testerState.dart';

class CardButton extends StatefulWidget {

  final Widget child;
  //final GestureTapCallback onPressed;
  final double widthBut;
  final double heightBut;
  final Color colorInitial;
  final Color colorClicked ;
  final Color textColorInitial ;
  final Color textColorClicked ;
  final Alignment alignment;
  final Text text;
  final String keyword;

  CardButton({
    //@required this.onPressed,
    this.child,
    @required this.keyword,
    this.heightBut =40,
    this.widthBut = 75,
    this.colorClicked = Colors.white,
    this.colorInitial=Colors.amber,
    this.textColorClicked = Colors.amber,
    this.textColorInitial = Colors.white,
    this.alignment = Alignment.center,
    this.text = const Text(
                           "Card",
                              style: TextStyle(
                              fontSize: 20,
      ),
    ),

  });

  @override
  _CardButtonState createState() => _CardButtonState(
      keyword,
      widthBut,
      heightBut,
      colorClicked,
      colorInitial,
      textColorClicked,
      textColorInitial,
      alignment,
      text,
  );
}

class _CardButtonState extends State<CardButton> {

  String _keyword;
  double _widthBut ;
  double _heightBut;
  Color _colorInitial;
  Color _colorClicked ;
  Color _textColorInitial;
  Color _textColorClicked ;
  Alignment _alignment ;
  Text _text;

  _CardButtonState(
      this._keyword,
      this._widthBut,
      this._heightBut,
      this._colorClicked,
      this._colorInitial,
      this._textColorClicked,
      this._textColorInitial,
      this._alignment,
      this._text,
      );

  Color _colorNow;
  Color _textColorNow;

  bool isClicked = false;

  void initState() {
    _colorNow=_colorInitial;
    _text = Text(_text.data, style: TextStyle(color: _textColorInitial, fontSize: _text.style.fontSize),);
    super.initState();
  }

  void ChangeButton(){

    setState(() {
      isClicked= !isClicked;
      if(isClicked){
        _colorNow=_colorClicked;
        _text = Text(_text.data, style: TextStyle(color: _textColorClicked, fontSize: _text.style.fontSize),);
      }
      else{
        _colorNow=_colorInitial;
        _text = Text(_text.data, style: TextStyle(color: _textColorInitial, fontSize: _text.style.fontSize),);
      }
    });

    //super.initState();//no idea

  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: _widthBut,
      height: _heightBut,
      child: InkWell(
        onTap: (){ChangeButton();
        CardMatcher(_keyword);
        print("onTap");},
        child: Container(
          padding: EdgeInsets.all(3),
          alignment: _alignment,
          decoration: BoxDecoration(
              color: _colorNow,
              boxShadow: [
                BoxShadow(
                    color: Colors.black12,
                    blurRadius: 5,
                    offset: Offset(0,2),
                    spreadRadius: 2
                )
              ],
              border: Border.all(
                  color: Colors.amberAccent
              )
          ),
          child: _text,
        ),
      ),
    );
    //widget.onPressed();
  }
}

对于 CardMatcher:

import 'package:flutter/material.dart';

class CardMatcher extends StatefulWidget {
  final String keyword_now;
  CardMatcher(this.keyword_now);

  @override
  _CardMatcherState createState() {
    print("cardMatch");

    _CardMatcherState(keyword_now);
  }
}

class _CardMatcherState extends State<CardMatcher> {
  String _keyword_1;
  String _keyword_2;
  String _keyword_now;

  _CardMatcherState(
      this._keyword_now,
      );

  void _collectKeywords(){
    print("EnterCollect");

    setState(() {
      if(_keyword_1==null)
        {
          print("key1");
          _keyword_1=_keyword_now;
        }
      else{
        _keyword_2=_keyword_now;
        _matchKeyword(_keyword_1,_keyword_2);
      }
    });
  }

  void _matchKeyword(_keyWord_one, _keyWord_two){
    if(_keyWord_one==_keyWord_two){
      //Lock the But
      print("MATCH!!!!");
    }
  }

  @override
  Widget build(BuildContext context) {
    print("BUILD");
    _collectKeywords();
    return null;
  }
}

请救救我

【问题讨论】:

  • InkWell 中的代码没有意义。您正在尝试将 Widget 放入方法中。这不是正确的 Dart/Flutter 代码。您应该显示 Widget,然后根据类状态中声明的变量进行更改。仅通过您的代码,要理解您真正想要实现的目标并不容易。一个更简单的例子会给你更好的回应。
  • 我的错。我试图在我的屏幕小部件中实例化我的 CardMatcher,但也没有发生任何事情。似乎每次我想制作一个没有返回值的小部件时,颤振都不会为我制作那种小部件。所以,也许正确的问题是:如何以及在哪里制作没有返回值的小部件?那么,如何从另一个小部件更改该小部件的变量?
  • 让我们试着简化一下。您想根据变量更改要显示的小部件吗?或者您想根据来自其他地方的变量更改小部件内的变量?
  • 很抱歉,但我想我已经找到了解决这个问题的方法(至少是临时解决方案)。谢谢各位,帮忙!!你们太棒了对不起,我的话不准确

标签: flutter widget parameter-passing


【解决方案1】:

您尝试在 onTap 函数中创建 CardMatcher 小部件!
你需要做什么:
1. onTap 必须调用ChangeButton(但不要在此处创建CardMatcher
2.ChangeButton必须调用setState()AND更改_keyword字段
3. 在构建树中使用CardMatcher 实例,_keyword 作为构造函数参数

当调用setState 时,您指示颤振重建(即调用build())小部件。如果您更改了一个状态(即_keyword),那么build 方法将使用新状态的值来构建相应的小部件

【讨论】:

  • 感谢您的回复,但很抱歉我没有明白...我尝试了您的建议,但我想我错过了一些东西
  • 我认为正确的问题是: 1.如何在 stateles 小部件(例如,名为 Home 的屏幕)中实例化有状态小部件 (CardMacther)? CardMacther 不是 UI,您如何以及在哪里写下来? 2. 一个按钮如何访问另一个小部件的变量。如果我没有误会,按钮会更改 CardMatcher 中声明的“关键字”,然后为 CardMatcher 设置新状态,对吗?如何有权更改其变量?
【解决方案2】:

您的代码中似乎唯一缺少的是使用widget. 前缀来访问Stateful 小部件构造函数变量,如下所示:

class CardMatcher extends StatefulWidget {
  final String keyword_now;
  CardMatcher(this.keyword_now);

  @override
  _CardMatcherState createState() {
    print("cardMatch");

    _CardMatcherState(keyword_now);
  }
}

class _CardMatcherState extends State<CardMatcher> {
  String _keyword_1;
  String _keyword_2;


  void _collectKeywords(){
    print("EnterCollect");

    setState(() {
      if(_keyword_1 == null)
        {
          print("key1");
          _keyword_1 = widget.keyword_now;
        }
      else{
        _keyword_2 = widget.keyword_now;
        _matchKeyword(_keyword_1,_keyword_2);
      }
    });
  }

  void _matchKeyword(_keyWord_one, _keyWord_two){
    if(_keyWord_one==_keyWord_two){
      //Lock the But
      print("MATCH!!!!");
    }
  }

  @override
  Widget build(BuildContext context) {
    print("BUILD");
    _collectKeywords();
    return null;
  }
}

【讨论】:

  • 嗯...感谢您的回复,但我认为这并不能解决我的问题。问题是,当我单击(onTap)按钮时,应该构建 CardMatcher,但不知何故 CardMatcher 没有出现(我试图在构建中打印“cardMatch”,遗憾的是什么也没出现)。
猜你喜欢
  • 2020-10-15
  • 2019-04-18
  • 1970-01-01
  • 2020-11-10
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-18
相关资源
最近更新 更多