首页 > 解决方案 > 处理模型生成按钮的 onPress

问题描述

我有一个模型,我为了这个问题而简化了

MyModel(a:0, b:0, c:0) //a b c are integers

现在我需要从这个模型生成按钮,所以我创建了一个新类,该类将该模型作为参数并生成按钮

class Panel extends StatelessWidget {
  final MyModel model;

  const Panel({this.model});

  List<Widget> _buildContent() {
    final list = [
      {'a': model.a},
      {'b': model.b},
      {'c': model.c}
    ];
    List<Widget> l = [];
    list.forEach((element) {
      l.add(FlatButton(child: Text(element.keys.first), onPressed: () {}));
    });
    return l;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        height: 70,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: _buildContent(),
        ));
  }
}

在我的主要课程中,我只是这样称呼它

Panel(model: myModel);

我正在尝试找到处理这些按钮按下的最简洁方法,每个按钮应在每次按下时将其元素更新为 +1,并将更新后的模型发送回主类

标签: flutterdart

解决方案


当模型更改时,您需要让 Panel 提供回调。然后您可以更改应用程序中使用的模型。请注意添加到面板中的“onChange”回调,该回调在 App 中调用setState以实际更改模型。

例子:

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

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

class Model {
  final int a;
  final int b;
  final int c;

  const Model({this.a, this.b, this.c});
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Model model = Model(a: 1, b: 2, c: 3);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(title: Text('Current Model: a:${model.a}, b:${model.b}, c: ${model.c}')),
        body: Center(
          child: Panel(
            model: model, 
            onChange: (changedModel) => setState(() => model = changedModel)),
        ),
      ),
    );
  }
}

class PanelButton {
  final String text;
  final Model Function() onClick;

  const PanelButton(this.text, this.onClick);
}

class Panel extends StatelessWidget {
  final Model model;
  final void Function(Model) onChange;

  const Panel({@required this.model, this.onChange});

  List<Widget> _buildContent() {
    final list = [
      PanelButton('a', () => Model(a: model.a + 1, b: model.b, c: model.c)),
      PanelButton('b', () => Model(a: model.a, b: model.b + 1, c: model.c)),
      PanelButton('c', () => Model(a: model.a, b: model.b, c: model.c + 1)),
    ];

    return list
        .map((x) => FlatButton(
            child: Text(x.text), onPressed: () => _raiseOnChange(x.onClick())))
        .toList();
  }

  void _raiseOnChange(Model model) {
    if (onChange != null) {
      onChange(model);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        height: 70,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: _buildContent(),
        ));
  }
}

推荐阅读