颤振动态文本方向性问题
flutter dynamic text directionality issue
重现错误的代码:
class TestWidget extends StatefulWidget {
@override
_TestWidgetState createState() => _TestWidgetState();
}
class _TestWidgetState extends State<TestWidget> {
bool isRtl = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Directionality(
child: TextField(),
textDirection: isRtl ? TextDirection.rtl : TextDirection.ltr,
),
RaisedButton(
child: Text('click me!'),
onPressed: () => setState(() => isRtl = !isRtl),
),
],
),
),
);
}
}
重现步骤:
- 在文本字段中输入 'some thing'
- 删除它 #它工作正常
- 点击按钮
- 在文本字段中输入“سلام دنیا”
- 尝试删除它 #see 错误!
是否有针对此错误的解决方法或修复方法?
解决方案1.在TextField
中将minLines
设置为1
,将maxLines
设置为null
:
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Directionality(
child: TextField(
minLines: 1, // this is new
maxLines: null, // this is new
),
textDirection: isRtl ? TextDirection.rtl : TextDirection.ltr,
),
RaisedButton(
child: Text('click me!'),
onPressed: () => setState(() => isRtl = !isRtl),
),
],
),
),
);
}
解决方案 2. 删除在 rtl 中点击 space 键时插入的额外字符:
TextEditingController _textEditingController = TextEditingController();
var isRtl = false;
var _text = '';
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Directionality(
textDirection: isRtl ? TextDirection.rtl : TextDirection.ltr,
child: TextFormField(
onChanged: (val) {
if (val.codeUnitAt(val.length - 1) == 8207 ||
val.codeUnitAt(val.length - 1) == 8206) {
setState(() {
_text = val.replaceAll(String.fromCharCode(8207), '');
_text = _text.replaceAll(String.fromCharCode(8206), '');
_textEditingController =
new TextEditingController.fromValue(
new TextEditingValue(
text: _text,
selection: new TextSelection.collapsed(
offset: _text.length)));
});
}
else {
setState(() {
_text = val;
});
}
},
controller: _textEditingController,
),
),
RaisedButton(
child: Text('click me!'),
onPressed: () => setState(() {
isRtl = !isRtl;
}),
),
],
),
),
);
}
我稍微修改了@Mobina的回答:
TextEditingController _textEditingController = TextEditingController();
var isRtl = false;
var _text = '';
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Directionality(
textDirection: isRtl ? TextDirection.rtl : TextDirection.ltr,
child: TextFormField(
onChanged: (val) {
if (val.codeUnitAt(val.length - 1) == 8207 ||
val.codeUnitAt(val.length - 1) == 8206) {
setState(() {
_text = val.replaceAll(String.fromCharCode(8207), '');
_text = _text.replaceAll(String.fromCharCode(8206), '');
_textEditingController.value = TextEditingValue(
text: _text,
selection: TextSelection.collapsed(offset: _text.length),
); //changed here!
});
}
else {
setState(() {
_text = val;
});
}
},
controller: _textEditingController,
),
),
RaisedButton(
child: Text('click me!'),
onPressed: () => setState(() {
isRtl = !isRtl;
}),
),
],
),
),
);
}
重现错误的代码:
class TestWidget extends StatefulWidget {
@override
_TestWidgetState createState() => _TestWidgetState();
}
class _TestWidgetState extends State<TestWidget> {
bool isRtl = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Directionality(
child: TextField(),
textDirection: isRtl ? TextDirection.rtl : TextDirection.ltr,
),
RaisedButton(
child: Text('click me!'),
onPressed: () => setState(() => isRtl = !isRtl),
),
],
),
),
);
}
}
重现步骤:
- 在文本字段中输入 'some thing'
- 删除它 #它工作正常
- 点击按钮
- 在文本字段中输入“سلام دنیا”
- 尝试删除它 #see 错误!
是否有针对此错误的解决方法或修复方法?
解决方案1.在TextField
中将minLines
设置为1
,将maxLines
设置为null
:
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Directionality(
child: TextField(
minLines: 1, // this is new
maxLines: null, // this is new
),
textDirection: isRtl ? TextDirection.rtl : TextDirection.ltr,
),
RaisedButton(
child: Text('click me!'),
onPressed: () => setState(() => isRtl = !isRtl),
),
],
),
),
);
}
解决方案 2. 删除在 rtl 中点击 space 键时插入的额外字符:
TextEditingController _textEditingController = TextEditingController();
var isRtl = false;
var _text = '';
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Directionality(
textDirection: isRtl ? TextDirection.rtl : TextDirection.ltr,
child: TextFormField(
onChanged: (val) {
if (val.codeUnitAt(val.length - 1) == 8207 ||
val.codeUnitAt(val.length - 1) == 8206) {
setState(() {
_text = val.replaceAll(String.fromCharCode(8207), '');
_text = _text.replaceAll(String.fromCharCode(8206), '');
_textEditingController =
new TextEditingController.fromValue(
new TextEditingValue(
text: _text,
selection: new TextSelection.collapsed(
offset: _text.length)));
});
}
else {
setState(() {
_text = val;
});
}
},
controller: _textEditingController,
),
),
RaisedButton(
child: Text('click me!'),
onPressed: () => setState(() {
isRtl = !isRtl;
}),
),
],
),
),
);
}
我稍微修改了@Mobina的回答:
TextEditingController _textEditingController = TextEditingController();
var isRtl = false;
var _text = '';
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Directionality(
textDirection: isRtl ? TextDirection.rtl : TextDirection.ltr,
child: TextFormField(
onChanged: (val) {
if (val.codeUnitAt(val.length - 1) == 8207 ||
val.codeUnitAt(val.length - 1) == 8206) {
setState(() {
_text = val.replaceAll(String.fromCharCode(8207), '');
_text = _text.replaceAll(String.fromCharCode(8206), '');
_textEditingController.value = TextEditingValue(
text: _text,
selection: TextSelection.collapsed(offset: _text.length),
); //changed here!
});
}
else {
setState(() {
_text = val;
});
}
},
controller: _textEditingController,
),
),
RaisedButton(
child: Text('click me!'),
onPressed: () => setState(() {
isRtl = !isRtl;
}),
),
],
),
),
);
}