Flutter:共享首选项,更改通知程序

时间:2020-09-06 10:38:20

标签: flutter

这是带有更改通知程序和共享首选项的加计数应用程序的代码。 我希望它将计数器保存在模型中,并在打开时显示最后一个计数器,但是它不起作用。 当它打开时,它显示为0。点击添加按钮后,它将显示最后一个计数器加1。 请告诉我为什么它不起作用以及如何解决。

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

void main() {
  runApp(
    ChangeNotifierProvider<MyHomePageModel>(
      create: (_) => MyHomePageModel(),
      child: MyApp(),
    )
  );
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Consumer<MyHomePageModel>(builder: (context, model, child) {
      int _counter = model.getCounter();
      return Scaffold(
          appBar: AppBar(
            title: Text('FlutteR Demo Home Page'),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'You have pushed the button this many times:',
                ),
                Text(
                  '$_counter',
                  style: Theme.of(context).textTheme.headline4,
                ),
              ],
            ),
          ),
          floatingActionButton: Button());
    });
  }
}

class Button extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final model = Provider.of<MyHomePageModel>(context, listen: false);
    return FloatingActionButton(
      onPressed: () => model.addCounter(),
      tooltip: 'Increment',
      child: Icon(Icons.add),
    );
  }
}

class MyHomePageModel extends ChangeNotifier {
  int _counter = 0;

  void _setPrefItems() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setInt('counter', _counter);
  }

  void _getPrefItems() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    _counter = prefs.getInt('counter') ?? 0;
  }

  void addCounter() {
    _counter++;
    _setPrefItems();
    notifyListeners();
  }

  int getCounter() {
    _getPrefItems();
    return _counter;
  }
}

2 个答案:

答案 0 :(得分:0)

我在这里发现了两件事。

  1. 您的HomePageModel中的计数器没有吸气剂。您在窗口小部件中调用getCounter()方法,但是该方法返回void而不是计数器值。

  2. 您有一个ChangeNotifier,但从不调用notifyListeners。

我建议为您的计数器设置一个吸气剂,并在您的方法中调用notifyListeners。

void _getPrefItems() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
_counter = prefs.getInt('counter') ?? 0;
notifyListeners();
}

int get counter => _counter

答案 1 :(得分:0)

void _getPrefItems() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  _counter = prefs.getInt('counter') ?? 0;
}

int getCounter() {
  _getPrefItems();
  return _counter;
}

_getPrefItems是异步函数,当您调用getCounter时,_counter尚未被重新分配,因此它返回_counter的默认值0。

因此,您要做的就是将getCounter函数更改为异步函数

Future<int> getCounter() async {
  await _getPrefItems();
  return _counter;
}

我建议您将SharePreferences置于模型之外,然后使用FutureProvider,查看完整的代码,我没有对其进行测试,但是您明白了。

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

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return FutureProvider(
      create: (_) => SharedPreferences.getInstance(),
      lazy: false,
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        home: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Provider(
      create: (_) => MyHomePageModel(prefs: Provider.of(context)),
      child: Scaffold(
        appBar: AppBar(
          title: Text('FlutteR Demo Home Page'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'You have pushed the button this many times:',
              ),
              Consumer<MyHomePageModel>(
                builder: (context, model, child) => Text(
                  '${model.getCounter()}',
                  style: Theme.of(context).textTheme.headline4,
                ),
              ),
            ],
          ),
        ),
        floatingActionButton: Button(),
      ),
    );
  }
}

class Button extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final model = Provider.of<MyHomePageModel>(context, listen: false);
    return FloatingActionButton(
      onPressed: () => model.addCounter(),
      tooltip: 'Increment',
      child: Icon(Icons.add),
    );
  }
}

class MyHomePageModel extends ChangeNotifier {
  final SharedPreferences prefs;
  int _counter = 0;

  MyHomePageModel({@required this.prefs});

  void _setPrefItems() {
    prefs.setInt('counter', _counter);
  }

  void _getPrefItems() {
    _counter = prefs.getInt('counter') ?? 0;
  }

  void addCounter() {
    _counter++;
    _setPrefItems();
    notifyListeners();
  }

  int getCounter() {
    _getPrefItems();
    return _counter;
  }
}