mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-07-01 12:23:44 +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;
|
var prevItem = items.last;
|
||||||
item.lineNo = prevItem.lineNo + 1;
|
item.lineNo = prevItem.lineNo + 1;
|
||||||
|
items.add(item);
|
||||||
_lines.insert(item.lineNo, item.toString());
|
_lines.insert(item.lineNo, item.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,6 +184,7 @@ class Checklist {
|
|||||||
if (index == items.length) {
|
if (index == items.length) {
|
||||||
var prevItem = items.last;
|
var prevItem = items.last;
|
||||||
item.lineNo = prevItem.lineNo + 1;
|
item.lineNo = prevItem.lineNo + 1;
|
||||||
|
items.add(item);
|
||||||
_lines.insert(item.lineNo, item.toString());
|
_lines.insert(item.lineNo, item.toString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,9 @@ class ChecklistEditor extends StatefulWidget implements Editor {
|
|||||||
class ChecklistEditorState extends State<ChecklistEditor>
|
class ChecklistEditorState extends State<ChecklistEditor>
|
||||||
implements EditorState {
|
implements EditorState {
|
||||||
Checklist checklist;
|
Checklist checklist;
|
||||||
var focusNodes = <ChecklistItem, FocusScopeNode>{};
|
var focusNodes = <UniqueKey, FocusScopeNode>{};
|
||||||
|
var keys = <UniqueKey, ChecklistItem>{};
|
||||||
|
|
||||||
TextEditingController _titleTextController = TextEditingController();
|
TextEditingController _titleTextController = TextEditingController();
|
||||||
bool _noteModified;
|
bool _noteModified;
|
||||||
|
|
||||||
@ -67,9 +69,8 @@ class ChecklistEditorState extends State<ChecklistEditor>
|
|||||||
var item = checklist.buildItem(false, "");
|
var item = checklist.buildItem(false, "");
|
||||||
checklist.addItem(item);
|
checklist.addItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var item in checklist.items) {
|
for (var item in checklist.items) {
|
||||||
focusNodes[item] = FocusScopeNode();
|
keys[UniqueKey()] = item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,6 +80,29 @@ class ChecklistEditorState extends State<ChecklistEditor>
|
|||||||
super.dispose();
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var itemTiles = <Widget>[];
|
var itemTiles = <Widget>[];
|
||||||
@ -92,13 +116,14 @@ class ChecklistEditorState extends State<ChecklistEditor>
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
_noteTextChanged();
|
_noteTextChanged();
|
||||||
setState(() {
|
setState(() {
|
||||||
var fn = FocusScopeNode();
|
|
||||||
var item = checklist.buildItem(false, "");
|
var item = checklist.buildItem(false, "");
|
||||||
|
var fn = _getFn(item);
|
||||||
|
|
||||||
checklist.addItem(item);
|
checklist.addItem(item);
|
||||||
focusNodes[item] = fn;
|
|
||||||
|
|
||||||
// FIXME: Make this happen on the next build
|
// FIXME: Make this happen on the next build
|
||||||
Timer(const Duration(milliseconds: 50), () {
|
Timer(const Duration(milliseconds: 50), () {
|
||||||
|
FocusScope.of(context).requestFocus();
|
||||||
FocusScope.of(context).requestFocus(fn);
|
FocusScope.of(context).requestFocus(fn);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -156,7 +181,7 @@ class ChecklistEditorState extends State<ChecklistEditor>
|
|||||||
return ChecklistItemTile(
|
return ChecklistItemTile(
|
||||||
key: UniqueKey(),
|
key: UniqueKey(),
|
||||||
item: item,
|
item: item,
|
||||||
focusNode: focusNodes[item],
|
focusNode: _getFn(item),
|
||||||
isNewNote: autofocus,
|
isNewNote: autofocus,
|
||||||
statusChanged: (bool newVal) {
|
statusChanged: (bool newVal) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -181,16 +206,19 @@ class ChecklistEditorState extends State<ChecklistEditor>
|
|||||||
FocusNode fn;
|
FocusNode fn;
|
||||||
if (nextIndex >= 0) {
|
if (nextIndex >= 0) {
|
||||||
var nextItemForFocus = checklist.items[nextIndex];
|
var nextItemForFocus = checklist.items[nextIndex];
|
||||||
fn = focusNodes[nextItemForFocus];
|
fn = _getFn(nextItemForFocus);
|
||||||
print("Giving focus to $nextItemForFocus");
|
print("Giving focus to $nextItemForFocus");
|
||||||
}
|
}
|
||||||
|
|
||||||
focusNodes.remove(item);
|
var k = _getKey(item);
|
||||||
|
focusNodes.remove(k);
|
||||||
|
keys.remove(k);
|
||||||
checklist.removeItem(item);
|
checklist.removeItem(item);
|
||||||
|
|
||||||
// FIXME: Make this happen on the next build
|
// FIXME: Make this happen on the next build
|
||||||
Timer(const Duration(milliseconds: 300), () {
|
Timer(const Duration(milliseconds: 200), () {
|
||||||
if (fn != null) {
|
if (fn != null) {
|
||||||
|
FocusScope.of(context).requestFocus();
|
||||||
FocusScope.of(context).requestFocus(fn);
|
FocusScope.of(context).requestFocus(fn);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -199,14 +227,14 @@ class ChecklistEditorState extends State<ChecklistEditor>
|
|||||||
itemFinished: () {
|
itemFinished: () {
|
||||||
_noteTextChanged();
|
_noteTextChanged();
|
||||||
setState(() {
|
setState(() {
|
||||||
var fn = FocusScopeNode();
|
|
||||||
var item = checklist.buildItem(false, "");
|
var item = checklist.buildItem(false, "");
|
||||||
|
var fn = _getFn(item);
|
||||||
checklist.insertItem(index + 1, item);
|
checklist.insertItem(index + 1, item);
|
||||||
focusNodes[item] = fn;
|
|
||||||
|
|
||||||
// FIXME: Make this happen on the next build
|
// FIXME: Make this happen on the next build
|
||||||
Timer(const Duration(milliseconds: 50), () {
|
Timer(const Duration(milliseconds: 50), () {
|
||||||
print("Asking focus to ${index + 1}");
|
print("Asking focus to ${index + 1}");
|
||||||
|
FocusScope.of(context).requestFocus();
|
||||||
FocusScope.of(context).requestFocus(fn);
|
FocusScope.of(context).requestFocus(fn);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -252,6 +280,7 @@ class _ChecklistItemTileState extends State<ChecklistItemTile> {
|
|||||||
_textController.addListener(() {
|
_textController.addListener(() {
|
||||||
widget.textChanged(_textController.value.text);
|
widget.textChanged(_textController.value.text);
|
||||||
});
|
});
|
||||||
|
assert(widget.focusNode != null);
|
||||||
widget.focusNode.addListener(_onFocus);
|
widget.focusNode.addListener(_onFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,8 +293,7 @@ class _ChecklistItemTileState extends State<ChecklistItemTile> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _onFocus() {
|
void _onFocus() {
|
||||||
setState(() {}); // rebuild to hide close button
|
setState(() {}); // rebuild to show/hide close button
|
||||||
SystemChannels.textInput.invokeMethod('TextInput.show');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
Reference in New Issue
Block a user