flutterbooleansettingsandroid-vibration

Flutter How to set Boolean from Settingpage


How to turn On/Off vibration on Homepage from Settings page with boolean SwitchListTile?

I want if the SwitchListTile in the Settings page is On, the Homepage will vibrate every time I tap it, and vice versa. basically I don't know how to control certain pages from other pages

this is MySettingPage

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);
                });
              },
            ),
            //
          ],
        ),
      ),
    );
  }
}

this is MyHomePage

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),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Solution

  • To continue on the response from Allan C with the changes to your code: (untested)

    HomePage:

    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),
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      }
    }
    

    using the initState() you set a default value of _isVibrate from the passed value from the widget.isVibrate.

    The method _onVibrateChange(bool value) (as a callback) will update the local variable within the state. This method needs to be passed to the MySettingsPage also.

    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);
                    });
                  },
                ),
                //
              ],
            ),
          ),
        );
      }
    }
    

    I have included a new variable passed to the Statefulwidget (Function(bool value) onChange), this will be the callback for when the switch changes it's value.

    In the method Future saveSwitchState(bool value) async there is a call to the passed callback with the updated value from the SwitchListTiles onChange method.

    Hope this clarifies what he meant in his answer.