CelestialCosmic / themeblog

blog articles by Celestial_Cosmic,source code by chanshiyucx
0 stars 0 forks source link

flutter 异步踩坑记录 #48

Open CelestialCosmic opened 9 months ago

CelestialCosmic commented 9 months ago

两天时间研究出来的东西

本地存储

首先用 shared_preferences 定义一个存储类

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

class SharedPref {
  read(String key) async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString(key);
  }

  save(String key, value) async {
    final prefs = await SharedPreferences.getInstance();
    prefs.setString(key, value);
  }

  remove(String key) async {
    final prefs = await SharedPreferences.getInstance();
    prefs.remove(key);
  }
  loadWidget() async{
    List<String> tiles = [];
    final prefs = await SharedPreferences.getInstance();
    for (String key in prefs.getKeys()){
      tiles.add(key);
    }
    return tiles;
  }
}

是的,loadWidget 本来希望返回组件的,然后发现事情没有那么简单

保存输入

然后是一个保存输入的文本框和按钮

_addFeedButton(context) {
    return Stack(
      children: [
        Align(
            alignment: Alignment.bottomRight,
            child: Padding(
              padding: const EdgeInsets.all(35.0),
              child: FloatingActionButton(
                  child: const Icon(Icons.add),
                  onPressed: () {
                    showDialog(
                        context: context,
                        builder: (context) {
                          return AlertDialog(
                            title: const Text("添加订阅源"),
                            content: Column(
                              children: [
                                SizedBox(
                                  child: TextField(
                                    controller: rssNameController,
                                    maxLines: 1,
                                    decoration: const InputDecoration(
                                      hintText: '名字',
                                    ),
                                  ),
                                ),
                                SizedBox(
                                  child: TextField(
                                    controller: rssUrlController,
                                    maxLines: 1,
                                    decoration: const InputDecoration(
                                      hintText: '网站的rssurl',
                                    ),
                                  ),
                                ),
                                const Padding(padding: EdgeInsets.all(5.0)),
                                ElevatedButton(
                                  child: const Text("添加"),
                                  onPressed: () {
                                    if (rssUrlController.text.isEmpty) {
                                      showDialog(
                                          context: context,
                                          builder: (context) {
                                            return const AlertDialog(
                                              title: Text("提示"),
                                              content: Text("不能为空!"),
                                            );
                                          });
                                    } else {
                                      var instance = SharedPref();
                                      instance.save(rssNameController.text,
                                          rssUrlController.text);
                                      showDialog(
                                          context: context,
                                          builder: (context) {
                                            return const AlertDialog(
                                              title: Text("提示"),
                                              content: Text("添加成功!"),
                                            );
                                          });
                                    }
                                  },
                                ),
                              ],
                            ),
                          );
                        });
                  }),
            ))
      ],
    );
  }

最后的括号简直是地狱。调整一些内容就需要大量时间才能进行下一次热重载

这个按钮实现了点击以后储存内容,没什么好说的

读取内容并显示

然后读取内容,并显示在屏幕上

  _wait() async {
    var i = SharedPref();
    final values = await i.loadWidget();
    return values;
  }

  _future(context) {
    return FutureBuilder(
        future: _wait(),
        builder: (context,snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            return Text(snapshot.data.toString());
          }
          else return Text("loading");
        });
  }

  Widget build(BuildContext context) {
    List tiles = [];

    return Stack(children: [
      // _wait(),
      _future(context),
      _addFeedButton(context),
    ]);
  }
}

这里面,如果直接用 print 的话,只有 _wait 里面才能在控制台打印数组内容,其他所有地方都是 future,它们定义不能添加关键字 static,这会影响其他的东西。直接返回又会导致返回 future 类型,导致报错。

所以就有了这么扭曲的实现:_wait 读取数组,FutureBuilder 构建组件,最后 build