반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- KakaoMap
- FirebaseAnalytics
- code editor
- uint8array
- jszip
- node
- Three-fiber
- web track
- androidId
- identifierForVender
- Raycasting
- Game js
- methodChannel
- typescript
- Excel
- userevent_tracker
- Prism.js
- webrtc
- Flutter
- Completer
- REST API
- Babel standalone
- RouteObserver
- uint16array
- Three js
- swagger-typescript-api
- Redux
- Image Resize typescript
- react
- babel
Archives
- Today
- Total
Never give up
Flutter 2.0 - Hive fixed length list problem and solution 본문
반응형
이전에 Migration을 하면서 fixed length list에 대한 문제에 대해 말씀드린적 있습니다
(링크 : devmemory.tistory.com/55)
그래서 issue에 올려보니 제작자가 다른 소리만 하고 해결할 의지가 별로 없어보였습니다..
먼저 간단한 예제 코드와 설명으로 시작해보겠습니다
Splash
class TestSplash extends StatefulWidget {
@override
_TestSplashState createState() => _TestSplashState();
}
class _TestSplashState extends State<TestSplash> {
@override
void initState() {
super.initState();
init();
}
void init() async {
await Hive.initFlutter();
await Hive.openBox('test');
ListData data = ListData();
await data.init();
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ListTest(title: 'List test example', data: data)));
}
@override
Widget build(BuildContext context) {
return Scaffold();
}
main
class ListTest extends StatefulWidget {
final String title;
final ListData data;
ListTest({required this.data, required this.title});
@override
_ListTestState createState() => _ListTestState();
}
class _ListTestState extends State<ListTest> {
late ListData _data;
@override
void initState() {
super.initState();
_data = widget.data;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: ListView.builder(
itemCount: _data.list.length,
itemBuilder: (_, index) {
String title = _data.list[index];
return Card(
child: ListTile(
leading: CircleAvatar(child: Text(index.toString())),
title: Text(title),
onTap: () {
setState(() {
_data.removeData(index);
});
},
),
);
}),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.edit),
onPressed: () {
showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text('Add'),
content: TextField(onChanged: (value) {
_data.title = value;
}),
actions: [
TextButton(
onPressed: () {
_data.title = '';
Navigator.pop(context);
},
child: Text('Cancel')),
TextButton(
onPressed: () {
setState(() {
_data.addData();
});
Navigator.pop(context);
},
child: Text('Confirm')),
]));
}),
);
}
}
data
class ListData {
List<String> list = [];
String title = '';
late Box box;
Future<void> init() async {
box = Hive.box('test');
list = box.get('list') ?? [];
}
void addData() {
list.add(title);
box.put('list', list);
}
void removeData(int index) {
list.removeAt(index);
box.put('list', list);
}
}
간단한 ListView와 Hive를 이용한 예제입니다
2.0 이전 버전에서는 문제없이 잘 작동하는 코드입니다
그런데 2.0 업데이트된 이후로 Hive도 null safety버전으로 올라가면서
코드에 문제가 생긴거 같습니다
이대로 작동하면 처음에는 잘 작동합니다만
재부팅 후 리스트를 조작해보면 이런 에러들이 환영(?)을 해줄겁니다
Unsupported operation: Cannot add to a fixed-length list
Unsupported operation: Cannot remove from a fixed-length list
에러를 보면 알겠듯이 크기가 고정된 list를 변경할 때 발생하는 문제입니다
이번에 업데이트 되면서 List를 box에서 가져올 때 Fixed length List 형태로 가져오는 문제가 있습니다
그래서 새로운 버전으로 업데이트 될 때, 이 부분도 업데이트 해줄줄 알았는데 안해주더군요..
그래서 임시방편으로 해결방법을 고민해보게 되었고
필자가 생각하기에 가장 합리적이라고 생각한 방식은 reference 대신 value로 저장하는것이였고
테스트 해보니 정상적으로 작동이 되었습니다
Future<void> init() async {
box = Hive.box('test');
//list = box.get('list') ?? []; 이거 대신
list.addAll(box.get('list') ?? []); // 이거
}
사실 이것도 제작자가 조금만 더 신경써주면 해결되는 문제인데
조금 아쉬운거 같습니다..
반응형
'Flutter' 카테고리의 다른 글
Flutter - FCM device to device, device to all devices (3) | 2021.04.24 |
---|---|
Flutter - Loop PageView (0) | 2021.04.17 |
Flutter - ListView inside ListView with shrinkwrap (3) | 2021.03.28 |
Flutter 2.0 - ButtonStyle (feat. Deprecated Buttons) (0) | 2021.03.06 |
Flutter 2.0 - Null safety에 대한 이해 (0) | 2021.03.06 |
Comments