如何在子窗口小部件上编辑值

时间:2019-09-17 07:31:39

标签: flutter dart

我尝试编辑子窗口小部件的值,我可以使用StatefulWidget父级来做到这一点,但是我想使用StatelessWidget父级来做到这一点,而无需使用全局值

    class Homepage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          FlatButton(child: Text('addFile'), onPressed: () {}),
          FlatButton(child: Text('deleteFile'), onPressed: () {})
        ],
      ),
      body: Child(),
    );
  }
}

class Child extends StatefulWidget {
  @override
  _ChildState createState() => _ChildState();
}

class _ChildState extends State<Child> {
  var hasFile = true;
  @override
  Widget build(BuildContext context) {
    return hasFile ? Text('has a file') : Text("no File");
  }
}

2 个答案:

答案 0 :(得分:1)

您可以使用BLoC模式来实现这种功能,

这里是BLoC类,它将处理布尔状态

import 'dart:async';

class Bloc {
  final _fileController = StreamController<bool>();

  changeState(bool val) {
    _fileController.sink.add(val);
  }

  get hasFile => _fileController.stream;

  dispose() {
    _fileController.close();
  }
}

final bloc = Bloc();

然后,您可以在Stateful Widget中添加流构建器,在其中将提供BLoC类的流。 StreamBuilder根据Stream更新其UI。

class Child extends StatefulWidget {
  @override
  _ChildState createState() => _ChildState();
}

class _ChildState extends State<Child> {
  var hasFile = true;

  @override
  void dispose() {
    bloc.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: bloc.hasFile,
      initialData: false,
      builder: (context, snapshot) {
        return snapshot.data ? Text('has a file') : Text("no File");
      },
    );
  }
}

最后,您可以使用无状态窗口小部件访问BLoC类,如下所示

class Homepage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          FlatButton(
              child: Text('addFile'),
              onPressed: () {
                bloc.changeState(true);
              }),
          FlatButton(
              child: Text('deleteFile'),
              onPressed: () {
                bloc.changeState(false);
              })
        ],
      ),
      body: Child(),
    );
  }
}

完整示例如下

import 'package:flutter/material.dart';
import 'dart:async';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Homepage(),
    );
  }
}

class Homepage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          FlatButton(
              child: Text('addFile'),
              onPressed: () {
                bloc.changeState(true);
              }),
          FlatButton(
              child: Text('deleteFile'),
              onPressed: () {
                bloc.changeState(false);
              })
        ],
      ),
      body: Child(),
    );
  }
}

class Child extends StatefulWidget {
  @override
  _ChildState createState() => _ChildState();
}

class _ChildState extends State<Child> {
  var hasFile = true;

  @override
  void dispose() {
    bloc.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: bloc.hasFile,
      initialData: false,
      builder: (context, snapshot) {
        return snapshot.data ? Text('has a file') : Text("no File");
      },
    );
  }
}

class Bloc {
  final _fileController = StreamController<bool>();

  changeState(bool val) {
    _fileController.sink.add(val);
  }

  get hasFile => _fileController.stream;

  dispose() {
    _fileController.close();
  }
}

final bloc = Bloc();

答案 1 :(得分:1)

您在想错误的方式。子aka Text()应该从由应用程序管理或至少由上面的小部件管理的模型中获取其值。我将使用提供者软件包https://pub.dev/packages/provider,并执行以下操作:

import 'package:provider/provider.dart';
import 'package:flutter/material.dart';


class MyState with ChangeNotifier {
  String _myText;

  MyState(this._myText);

  getMyText() => _myText;

  void changeText(String newText) {
    _myText = newText;
    notifyListeners();
  }
}

class Homepage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
        providers: [
          ChangeNotifierProvider(builder: (_) => MyState("initial Text")),
        ],
        child: Scaffold(
          appBar: AppBar(
            actions: <Widget>[
              FlatButton(
                  child: Text('addFile'),
                  onPressed: () {
                    Provider.of<MyState>(context).changeText("addFile");
                  }),
              FlatButton(
                  child: Text('deleteFile'),
                  onPressed: () {
                    Provider.of<MyState>(context).changeText("deleteFile");
                  })
            ],
          ),
          body: Child(),
        ));
  }
}

class Child extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    MyState myState = Provider.of<MyState>(context);
    return Text(myState.getMyText());
  }
}

此代码在没有IDE支持的情况下甚至无法编译运行。但这应该可以指引您正确的方向。