Flutter 如何从设置页面设​​置布尔值

Flutter How to set Boolean from Settingpage

如何使用 boolean SwitchListTile 从“设置”页面打开主页上的 On/Off 振动?

我想如果设置页面中的SwitchListTile打开,每次我点击它时主页都会振动,反之亦然。基本上我不知道如何从其他页面控制某些页面

这是我的设置页面

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class MySettingPage extends StatefulWidget {
  const MySettingPage({Key key}) : super(key: key);

  @override
  _MySettingPageState createState() => _MySettingPageState();
}

class _MySettingPageState extends State<MySettingPage> {
  bool isVibrate = false;

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

  getSwitchValues() async {
    isVibrate = await getSwitchState();
    setState(() {});
  }

  Future<bool> saveSwitchState(bool value) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setBool("switchState", value);
    return prefs.setBool("switchState", value);
  }

  Future<bool> getSwitchState() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    bool isVibrate = prefs.getBool("switchState");
    return isVibrate;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        titleSpacing: 0,
        title: Text("Pengaturan"),
        leading: IconButton(
            icon: Icon(Icons.arrow_back),
            onPressed: () {
              Navigator.of(context).pop();
            }),
      ),
      body: Container(
        padding: EdgeInsets.all(10),
        child: ListView(
          children: [
            SwitchListTile(
              title: Text("Getar"),
              value: isVibrate,
              onChanged: (bool value) async {
                setState(() {
                  isVibrate = value;
                  saveSwitchState(value);
                });
              },
            ),
            //
          ],
        ),
      ),
    );
  }
}

这是我的主页

import 'package:flutter/material.dart';
import 'package:vibration/vibration.dart';
import 'mysettingpage.dart';

class MyHomePage extends StatefulWidget {
  final bool isVibrate;
  MyHomePage({Key key, this.isVibrate}) : super(key: key);
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  void _incrementCounter() {
    setState(() {
      _counter++;
      if (widget.isVibrate == true) {
        Vibration.vibrate(duration: 70);
      }
      if (widget.isVibrate == false) {
        Vibration.cancel();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("My Homepage"),
        titleSpacing: 0,
        leading: IconButton(
          icon: Icon(Icons.settings),
          onPressed: () {
            Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (BuildContext context) => MySettingPage(),
                ));
          },
        ),
      ),
      body: GestureDetector(
        onTap: () {
          _incrementCounter();
        },
        child: Container(
          height: double.infinity,
          width: double.infinity,
          child: Padding(
            padding: const EdgeInsets.only(bottom: 120),
            child: Column(
              children: [
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Padding(
                        padding: EdgeInsets.symmetric(horizontal: 20),
                        child: FittedBox(
                          child: Text(
                            '$_counter',
                            textAlign: TextAlign.center,
                            style: TextStyle(
                              fontSize: 200,
                              fontFamily: 'DS-Digital',
                              color: Color(0xFF24F3E2),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

一种方法是使用回调函数。

所以在 MySettingPage() 中,添加如下构造函数:

MySettingPage({this.callback}) 
final void Function(bool) callback;

在MySettingPage中,如果要更新MyHomePage()中isVibrate的值,可以调用widget.callback(true);

在 MyHomePage 中,您可以创建一个方法来更新 isVibrate 变量。

void _updateIsVibrate(bool isVibrate){//...}

当你调用MySettingsPage时,你可以传入你创建的方法。

要继续 Allan C 的回复并更改您的代码:(未经测试)

主页:

import 'package:flutter/material.dart';
import 'package:vibration/vibration.dart';
import 'mysettingpage.dart';

class MyHomePage extends StatefulWidget {
  final bool isVibrate;
  MyHomePage({Key key, this.isVibrate}) : super(key: key);
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  bool _isVibrate;

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

    _isVibrate = widget.isVibrate;
  }

  void _onVibrateChange(bool value) {
    setState(() {
      _isVibrate = value;
    })
  }

  void _incrementCounter() {
    setState(() {
      _counter++;
      if (_isVibrate) {
        Vibration.vibrate(duration: 70);
      }
      if (_isVibrate) {
        Vibration.cancel();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("My Homepage"),
        titleSpacing: 0,
        leading: IconButton(
          icon: Icon(Icons.settings),
          onPressed: () {
            Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (BuildContext context) => MySettingPage(
                    onChange: _onVibrateChange
                  ),
                ));
          },
        ),
      ),
      body: GestureDetector(
        onTap: () {
          _incrementCounter();
        },
        child: Container(
          height: double.infinity,
          width: double.infinity,
          child: Padding(
            padding: const EdgeInsets.only(bottom: 120),
            child: Column(
              children: [
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Padding(
                        padding: EdgeInsets.symmetric(horizontal: 20),
                        child: FittedBox(
                          child: Text(
                            '$_counter',
                            textAlign: TextAlign.center,
                            style: TextStyle(
                              fontSize: 200,
                              fontFamily: 'DS-Digital',
                              color: Color(0xFF24F3E2),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

使用 initState() 可以根据 widget.isVibrate.

的传递值设置默认值 _isVibrate

方法 _onVibrateChange(bool value)(作为回调)将更新状态内的局部变量。此方法也需要传递给 MySettingsPage。

我的设置页面:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class MySettingPage extends StatefulWidget {
  const MySettingPage({Key key, this.onChange}) : super(key: key);

  final Function(bool value) onChange;

  @override
  _MySettingPageState createState() => _MySettingPageState();
}

class _MySettingPageState extends State<MySettingPage> {
  bool isVibrate = false;

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

  getSwitchValues() async {
    isVibrate = await getSwitchState();
    setState(() {});
  }

  Future<bool> saveSwitchState(bool value) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setBool("switchState", value);
    widget.onChange(value);
    return prefs.setBool("switchState", value);
  }

  Future<bool> getSwitchState() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    bool isVibrate = prefs.getBool("switchState");
    return isVibrate;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        titleSpacing: 0,
        title: Text("Pengaturan"),
        leading: IconButton(
            icon: Icon(Icons.arrow_back),
            onPressed: () {
              Navigator.of(context).pop();
            }),
      ),
      body: Container(
        padding: EdgeInsets.all(10),
        child: ListView(
          children: [
            SwitchListTile(
              title: Text("Getar"),
              value: isVibrate,
              onChanged: (bool value) async {
                setState(() {
                  isVibrate = value;
                  saveSwitchState(value);
                });
              },
            ),
            //
          ],
        ),
      ),
    );
  }
}

我已经包含了一个传递给 Statefulwidget 的新变量 (Function(bool value) onChange),这将是当开关改变它的值时。

在方法 Future saveSwitchState(bool value) async 中,使用来自 SwitchListTiles onChange 方法。

希望这能澄清他在回答中的意思。

我所有与上述布尔值相关的问题都已通过实施 MultiProvider 得到解决。感谢以上帮助过我的高手们。祝你有美好的一天