簡體   English   中英

如何在本地保存用戶名並在每個頁面顫動中顯示

[英]How to save a username locally and display it in every page flutter

我試圖在我制作的 flutter 應用程序的每個頁面中添加一個用戶名。 我的意思是在我的頁面的 sidedrawers 中我是新手,所以我在這方面遇到了很大的困難來幫助我

我嘗試使用共享首選項,但我不能像變量所說的那樣做,因為它是一個未來的字符串。 我讓它在一個人登錄時保存用戶名,當我試圖找回它時它起作用了,我不能

  Future<String> getuname() async {
    final prefs = await SharedPreferences.getInstance();
    final name = "username";
    var user = prefs.getString(name);
    var username = '${user[0].toUpperCase()}${user.substring(1)}';
    print('get $username');
    return username;
  }

我把這個添加到 sidedrawer

ListTile(
              leading: Icon(Icons.user),
              title: Text(_get()),
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => MyProfilePage()),
                );
              }),
  String uname = '';
  @override
  void initState() {

    getuname().then((value) {
    setState(() {
      uname = value;
    });
  });
    _selectedDay = DateTime.now();
    _events = {
      _selectedDay.subtract(Duration(days: 30)): ['Event A0', 'Event B0', 'Event C0'],
      _selectedDay.subtract(Duration(days: 27)): ['Event A1'],
      _selectedDay.subtract(Duration(days: 20)): ['Event A2', 'Event B2', 'Event C2', 'Event D2'],
      _selectedDay.subtract(Duration(days: 16)): ['Event A3', 'Event B3'],
      _selectedDay.subtract(Duration(days: 10)): ['Event A4', 'Event B4', 'Event C4'],
      _selectedDay.subtract(Duration(days: 4)): ['Event A5', 'Event B5', 'Event C5'],
      _selectedDay.subtract(Duration(days: 2)): ['Event A6', 'Event B6'],
      _selectedDay: [uname, 'Event B7', 'Event C7', 'Event D7'],
      _selectedDay.add(Duration(days: 1)): ['Event A8v', 'Event B8', 'Event C8', 'Event D8'],
      _selectedDay.add(Duration(days: 3)): Set.from(['Event A9', 'Event A9', 'Event B9']).toList(),
      _selectedDay.add(Duration(days: 7)): ['Event A10', 'Event B10', 'Event C10'],
      _selectedDay.add(Duration(days: 11)): ['Event A11', 'Event B11'],
      _selectedDay.add(Duration(days: 17)): ['Event A12', 'Event B12', 'Event C12', 'Event D12'],
      _selectedDay.add(Duration(days: 22)): ['Event A13', 'Event B13'],
      _selectedDay.add(Duration(days: 26)): ['Event A14', 'Event B14', 'Event C14'],
    };

    _selectedEvents = _events[_selectedDay] ?? [];
    _visibleEvents = _events;
    _visibleHolidays = _holidays;

    _controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 400),
    );

    _controller.forward();

    super.initState();
  }

我無法獲得用戶名的值,但它可以在小部件中使用,但不能在 initstate 中使用。 幫我

SharedPreferences 適合存儲數據,但正如您所見,它不適用於任何地方——主要問題是它需要異步加載。 您可以在應用程序開始運行時簡單地獲取它,然后將它傳遞到您需要的任何地方,但這並不是特別理想。

我在我的應用程序中所做的,感覺有點像作弊,但到目前為止效果很好,是將 SharedPreferences 包裝到ScopedModel 包中的模型中。

這使我可以編寫一些非常方便的包裝器。 由於從作用域模型中獲取數據是同步的,因此使用 SharePreferences 非常容易。

看起來像這樣:

abstract class _PreferenceKeys {
  static const USERNAME = 'username';
}

class PreferenceModel extends Model {
  static PreferenceModel of(BuildContext context, {bool rebuildOnChange = false}) => ScopedModel.of<PreferenceModel>(context, rebuildOnChange: rebuildOnChange);


  final SharedPreferences sharedPreferences;

  PreferenceModel(this.sharedPreferences);

  // Helpers to set in values which ensure that notifyListeners gets called
  Future<bool> _setString(String key, String value, {bool notify = true}) async {
    final val = await sharedPreferences.setString(key, value);
    if (notify) notifyListeners();
    return val;
  }
  Future<bool> _setBool(String key, bool value, {bool notify = true}) async {
    final fut = await sharedPreferences.setBool(key, value);
    if (notify) notifyListeners();
    return fut;
  }

  String get username => sharedPreferences.getString(_PreferenceKeys.USERNAME);

  void set username(String username) => _setString(_PreferenceKeys.USERNAME, userName);

這種方法的最大缺點是 _setString 方法中的任何錯誤都不會傳播回來 - 如果這是您想要處理的問題,您可以使用 Future 函數來設置用戶名,或者在 _setString 中做一些事情來處理它。 不過我個人沒有遇到任何問題。

還有一個與此相關的技巧。 您可以使應用程序的主要功能異步,這意味着您可以這樣做:

main() async {
  final sharedPreferences = await SharedPreferences.getInstance();

  runApp(
    ScopedModel<PreferenceModel>(
      model: PreferenceModel(sharedPreferences),
      child: ...
    ),
  )
}

然后在你的代碼中使用它,你可以簡單地使用:

PreferenceModel.of(context).userName

 or

PreferenceModel.of(context, rebuildOnChange: true).userName

or

child: ScopedModelDescendant<PreferenceModel>(
  child: ...
  builder: (context, model, child) {
    // do whatever with model
    return ...
  }
)

如果您想完全按照自己的方式進行操作 - 您可以將Text包裝在FutureBuilder

Future<String> _get() async {
    final prefs = await SharedPreferences.getInstance();
    final name = "username";
    var username = prefs.getString(name);
    return username;
  }

ListTile(
  title: FutureBuilder(builder: (context, snapshot) {
    if (snapshot.hasData) return Text(snapshot.data);
    else return Text('');
  }, future: _get(),),.....),

更新:

用於在變量中保存名稱

String name = '';

@override
void initState() {
  super.initState();
  _get().then((value) {
    setState(() {
      name = value;
    });
  });
}

您可以做的是在 initstate 中您獲取數據並使用“then”關鍵字為變量分配一個用戶名,並在整個存儲中使用該變量,並在“then”中構建您的應用程序。 它會等到您獲得數據,然后構建您的應用程序

為什么不使用安全存儲插件?

// Create storage
final storage = new FlutterSecureStorage();

// Read value 
String value = await storage.read(key: key);

// Read all values
Map<String, String> allValues = await storage.readAll();

// Delete value 
await storage.delete(key: key);

// Delete all 
await storage.deleteAll();

// Write value 
await storage.write(key: key, value: value);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM