如何在 Flutter 的共享首选项中获取和设置两种不同数据类型的值?
How to get and set values of two different datatypes in Shared Preferences in Flutter?
我有一个名为 cardDetails
的地图,其详细信息是从 firestore 中获取的。获取数据后,我想使用 shared_preferences
通过将映射转换为字符串并将键设置为 true 来在本地保存详细信息。当用户再次打开应用程序时,我使用 getBool(key)
检查是否已读取该值,然后使用 getString(key)
.
从字符串中获取数据
问题是 getString(key) 返回的是 bool 值而不是字符串,因此我无法解码要再次映射的字符串
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following assertion was thrown building:
type 'bool' is not a subtype of type 'String'
声明和初始化
Map<String, dynamic> cardDetails;
var keys;
bool _initialSharedValue;
@override
void initState() {
super.initState();
SharedPreferences.getInstance().then((SharedPreferences sp) {
sharedPreferences = sp;
_initialSharedValue = sharedPreferences.getBool("homepage");
// will be null if never previously saved
if (_initialSharedValue == null) {
_initialSharedValue = false;
persist(_initialSharedValue); // set an initial value
}
setState(() {});
});
}
Future<void> persist(bool value) async {
setState(() {
_initialSharedValue = value;
});
await sharedPreferences?.setBool("homepage", value);
}
storeCardInSharedPreference(Map cardDetails) async {
await sharedPreferences?.setString("homepage", json.encode(cardDetails));
}
在 UI 中用于构建卡片
if (sharedPreferences.getBool("homepage"))
ListView.builder(
itemBuilder: (context, index) {
cardDetails = json.decode(sharedPreferences.getString("homepage"));
return HomepageCards(
user: widget.user,
cardDetails: cardDetails[cardDetails.keys.toList()[index]],
);
},
itemCount: 3,
scrollDirection: Axis.vertical,
controller: _controller,
shrinkWrap: true,
)
else
StreamBuilder<DocumentSnapshot>(
stream: Firestore()
.collection('homepage')
.document(widget.user.uid)
.collection('h')
.document('28032020')
.snapshots(),
builder: (context, snapshot) {
if (snapshot.data != null) {
cardDetails = {};
snapshot.data.data.forEach((index, individualDetail) {
cardDetails[index] = individualDetail;
});
storeCardInSharedPreference(cardDetails);
sharedPreferences.setBool("homepage", true);
keys = snapshot.data.data.keys;
} else {
// TODO: Convert it to Shimmer with card skeletal layout
CircularProgressIndicator();
}
return ListView.builder(
itemBuilder: (context, index) {
return HomepageCards(
user: widget.user,
cardDetails:
cardDetails[cardDetails.keys.toList()[index]],
);
},
itemCount: keys.length,
scrollDirection: Axis.vertical,
controller: _controller,
shrinkWrap: true,
);
},
)
我通过在 if 条件中使用 ?
使其成为空感知方法调用解决了这个问题。
if (sharedPreferences?.getBool("homepage"))
我有一个名为 cardDetails
的地图,其详细信息是从 firestore 中获取的。获取数据后,我想使用 shared_preferences
通过将映射转换为字符串并将键设置为 true 来在本地保存详细信息。当用户再次打开应用程序时,我使用 getBool(key)
检查是否已读取该值,然后使用 getString(key)
.
问题是 getString(key) 返回的是 bool 值而不是字符串,因此我无法解码要再次映射的字符串
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following assertion was thrown building:
type 'bool' is not a subtype of type 'String'
声明和初始化
Map<String, dynamic> cardDetails;
var keys;
bool _initialSharedValue;
@override
void initState() {
super.initState();
SharedPreferences.getInstance().then((SharedPreferences sp) {
sharedPreferences = sp;
_initialSharedValue = sharedPreferences.getBool("homepage");
// will be null if never previously saved
if (_initialSharedValue == null) {
_initialSharedValue = false;
persist(_initialSharedValue); // set an initial value
}
setState(() {});
});
}
Future<void> persist(bool value) async {
setState(() {
_initialSharedValue = value;
});
await sharedPreferences?.setBool("homepage", value);
}
storeCardInSharedPreference(Map cardDetails) async {
await sharedPreferences?.setString("homepage", json.encode(cardDetails));
}
在 UI 中用于构建卡片
if (sharedPreferences.getBool("homepage"))
ListView.builder(
itemBuilder: (context, index) {
cardDetails = json.decode(sharedPreferences.getString("homepage"));
return HomepageCards(
user: widget.user,
cardDetails: cardDetails[cardDetails.keys.toList()[index]],
);
},
itemCount: 3,
scrollDirection: Axis.vertical,
controller: _controller,
shrinkWrap: true,
)
else
StreamBuilder<DocumentSnapshot>(
stream: Firestore()
.collection('homepage')
.document(widget.user.uid)
.collection('h')
.document('28032020')
.snapshots(),
builder: (context, snapshot) {
if (snapshot.data != null) {
cardDetails = {};
snapshot.data.data.forEach((index, individualDetail) {
cardDetails[index] = individualDetail;
});
storeCardInSharedPreference(cardDetails);
sharedPreferences.setBool("homepage", true);
keys = snapshot.data.data.keys;
} else {
// TODO: Convert it to Shimmer with card skeletal layout
CircularProgressIndicator();
}
return ListView.builder(
itemBuilder: (context, index) {
return HomepageCards(
user: widget.user,
cardDetails:
cardDetails[cardDetails.keys.toList()[index]],
);
},
itemCount: keys.length,
scrollDirection: Axis.vertical,
controller: _controller,
shrinkWrap: true,
);
},
)
我通过在 if 条件中使用 ?
使其成为空感知方法调用解决了这个问题。
if (sharedPreferences?.getBool("homepage"))