mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-30 03:19:11 +08:00
ChecklistEditor: Improve focus handling
It's still a bit of a mess. I seem to be hitting this bug - https://github.com/flutter/flutter/issues/20706 which others are also hitting, but it seems to be closed despite a clearly reproduce test case.
This commit is contained in:
@ -158,6 +158,7 @@ class Checklist {
|
||||
|
||||
var prevItem = items.last;
|
||||
item.lineNo = prevItem.lineNo + 1;
|
||||
items.add(item);
|
||||
_lines.insert(item.lineNo, item.toString());
|
||||
}
|
||||
|
||||
@ -183,6 +184,7 @@ class Checklist {
|
||||
if (index == items.length) {
|
||||
var prevItem = items.last;
|
||||
item.lineNo = prevItem.lineNo + 1;
|
||||
items.add(item);
|
||||
_lines.insert(item.lineNo, item.toString());
|
||||
return;
|
||||
}
|
||||
|
@ -49,7 +49,9 @@ class ChecklistEditor extends StatefulWidget implements Editor {
|
||||
class ChecklistEditorState extends State<ChecklistEditor>
|
||||
implements EditorState {
|
||||
Checklist checklist;
|
||||
var focusNodes = <ChecklistItem, FocusScopeNode>{};
|
||||
var focusNodes = <UniqueKey, FocusScopeNode>{};
|
||||
var keys = <UniqueKey, ChecklistItem>{};
|
||||
|
||||
TextEditingController _titleTextController = TextEditingController();
|
||||
bool _noteModified;
|
||||
|
||||
@ -67,9 +69,8 @@ class ChecklistEditorState extends State<ChecklistEditor>
|
||||
var item = checklist.buildItem(false, "");
|
||||
checklist.addItem(item);
|
||||
}
|
||||
|
||||
for (var item in checklist.items) {
|
||||
focusNodes[item] = FocusScopeNode();
|
||||
keys[UniqueKey()] = item;
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,6 +80,29 @@ class ChecklistEditorState extends State<ChecklistEditor>
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
UniqueKey _getKey(ChecklistItem item) {
|
||||
for (var e in keys.entries) {
|
||||
if (e.value == item) {
|
||||
return e.key;
|
||||
}
|
||||
}
|
||||
|
||||
var key = UniqueKey();
|
||||
keys[key] = item;
|
||||
return key;
|
||||
}
|
||||
|
||||
FocusScopeNode _getFn(ChecklistItem item) {
|
||||
var key = _getKey(item);
|
||||
|
||||
var fn = focusNodes[key];
|
||||
if (fn == null) {
|
||||
fn = FocusScopeNode();
|
||||
focusNodes[key] = fn;
|
||||
}
|
||||
return fn;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var itemTiles = <Widget>[];
|
||||
@ -92,13 +116,14 @@ class ChecklistEditorState extends State<ChecklistEditor>
|
||||
onPressed: () {
|
||||
_noteTextChanged();
|
||||
setState(() {
|
||||
var fn = FocusScopeNode();
|
||||
var item = checklist.buildItem(false, "");
|
||||
var fn = _getFn(item);
|
||||
|
||||
checklist.addItem(item);
|
||||
focusNodes[item] = fn;
|
||||
|
||||
// FIXME: Make this happen on the next build
|
||||
Timer(const Duration(milliseconds: 50), () {
|
||||
FocusScope.of(context).requestFocus();
|
||||
FocusScope.of(context).requestFocus(fn);
|
||||
});
|
||||
});
|
||||
@ -156,7 +181,7 @@ class ChecklistEditorState extends State<ChecklistEditor>
|
||||
return ChecklistItemTile(
|
||||
key: UniqueKey(),
|
||||
item: item,
|
||||
focusNode: focusNodes[item],
|
||||
focusNode: _getFn(item),
|
||||
isNewNote: autofocus,
|
||||
statusChanged: (bool newVal) {
|
||||
setState(() {
|
||||
@ -181,16 +206,19 @@ class ChecklistEditorState extends State<ChecklistEditor>
|
||||
FocusNode fn;
|
||||
if (nextIndex >= 0) {
|
||||
var nextItemForFocus = checklist.items[nextIndex];
|
||||
fn = focusNodes[nextItemForFocus];
|
||||
fn = _getFn(nextItemForFocus);
|
||||
print("Giving focus to $nextItemForFocus");
|
||||
}
|
||||
|
||||
focusNodes.remove(item);
|
||||
var k = _getKey(item);
|
||||
focusNodes.remove(k);
|
||||
keys.remove(k);
|
||||
checklist.removeItem(item);
|
||||
|
||||
// FIXME: Make this happen on the next build
|
||||
Timer(const Duration(milliseconds: 300), () {
|
||||
Timer(const Duration(milliseconds: 200), () {
|
||||
if (fn != null) {
|
||||
FocusScope.of(context).requestFocus();
|
||||
FocusScope.of(context).requestFocus(fn);
|
||||
}
|
||||
});
|
||||
@ -199,14 +227,14 @@ class ChecklistEditorState extends State<ChecklistEditor>
|
||||
itemFinished: () {
|
||||
_noteTextChanged();
|
||||
setState(() {
|
||||
var fn = FocusScopeNode();
|
||||
var item = checklist.buildItem(false, "");
|
||||
var fn = _getFn(item);
|
||||
checklist.insertItem(index + 1, item);
|
||||
focusNodes[item] = fn;
|
||||
|
||||
// FIXME: Make this happen on the next build
|
||||
Timer(const Duration(milliseconds: 50), () {
|
||||
print("Asking focus to ${index + 1}");
|
||||
FocusScope.of(context).requestFocus();
|
||||
FocusScope.of(context).requestFocus(fn);
|
||||
});
|
||||
});
|
||||
@ -252,6 +280,7 @@ class _ChecklistItemTileState extends State<ChecklistItemTile> {
|
||||
_textController.addListener(() {
|
||||
widget.textChanged(_textController.value.text);
|
||||
});
|
||||
assert(widget.focusNode != null);
|
||||
widget.focusNode.addListener(_onFocus);
|
||||
}
|
||||
|
||||
@ -264,8 +293,7 @@ class _ChecklistItemTileState extends State<ChecklistItemTile> {
|
||||
}
|
||||
|
||||
void _onFocus() {
|
||||
setState(() {}); // rebuild to hide close button
|
||||
SystemChannels.textInput.invokeMethod('TextInput.show');
|
||||
setState(() {}); // rebuild to show/hide close button
|
||||
}
|
||||
|
||||
@override
|
||||
|
Reference in New Issue
Block a user