Флаттер, ListView.builder онТап странное поведение

#flutter #reset

Вопрос:

При нажатии клавиши 1 ListView добавляет 1 плитку, при нажатии клавиши 2 ListView удаляет одну плитку, хотя после щелчка мышью за пределами виджета ListView или Text() клавиши клавиатуры перестают отвечать без каких-либо ошибок, отображаемых в терминале.

Я подумал, что, возможно, focusNode был удален после нажатия за пределами ListView, хотя после тестирования это, похоже, не так

 import 'package:flutter/material.dart'; import 'package:flutter/services.dart';  class OnTapWidgetIssue extends StatefulWidget {  OnTapWidgetIssue({Key? key}) : super(key: key);   String testOnTap = '';  int nOfList = 1;   @override  _OnTapWidgetIssueState createState() =gt; _OnTapWidgetIssueState(); }  class _OnTapWidgetIssueState extends Statelt;OnTapWidgetIssuegt; {  final FocusNode _focusNode = FocusNode();  @override  void dispose() {  _focusNode.dispose();  print('_focusNode.dispose()');  super.dispose();  }   void _handleKeyEvent(RawKeyEvent event) {  if (event is RawKeyDownEvent amp;amp;  event.data.logicalKey == LogicalKeyboardKey.digit1) {  widget.nOfList  = 1;  setState(() {});  }   if (event is RawKeyDownEvent amp;amp;  event.data.logicalKey == LogicalKeyboardKey.digit2) {  if (widget.nOfList gt; 1) {  widget.nOfList--;  setState(() {});  } else {}  }  }   @override  Widget build(BuildContext context) {  return Scaffold(  drawer: MenuDrawer(),  appBar: AppBar(title: Text('OnTap-widget.Issue')),  body: RawKeyboardListener(  autofocus: true,  focusNode: _focusNode, // lt;-- more magic  onKey: _handleKeyEvent,  child: Column(children: [  Text(widget.testOnTap, style: TextStyle(fontSize: 52.0)),  Text('''  press 1 to add ListTile  press 2 to remove ListTile  '''),  Expanded(  child: Row(  children: [  Expanded(  flex: 2,  child: SizedBox(),  ),  Expanded(  flex: 1,  // child: SizedBox(),  // // ),  child: ListView.builder(  itemCount: widget.nOfList,  // itemCount: widget.testOnTap.length,  itemBuilder: (_, i) {  return ListTile(  title: Text('$i'),  onTap: () {  widget.testOnTap = widget.testOnTap   i.toString();  setState(() {});  },  // Handle your onTap here.  );  },  ),  ),  Expanded(  flex: 2,  child: SizedBox(),  ),  ],  ),  ),  ]),  ),  );  } }  

Также я получаю ошибку при нажатии, чтобы перейти на новую страницу в приложении

 Error: A FocusNode was used after being disposed. Once you have called dispose() on a FocusNode, it can no longer be used.  at Object.throw_ [as throw] (http://localhost:49535/dart_sdk.js:5061:11)  at http://localhost:49535/packages/flutter/src/foundation/change_notifier.dart.lib.js:66:21  at focus_manager.FocusNode.new.[_debugAssertNotDisposed] (http://localhost:49535/packages/flutter/src/foundation/change_notifier.dart.lib.js:69:25)  at focus_manager.FocusNode.new.notifyListeners (http://localhost:49535/packages/flutter/src/foundation/change_notifier.dart.lib.js:131:41)  at focus_manager.FocusNode.new.[_notify] (http://localhost:49535/packages/flutter/src/widgets/widget_inspector.dart.lib.js:42893:12)  at focus_manager.FocusManager.new.[_applyFocusChange] (http://localhost:49535/packages/flutter/src/widgets/widget_inspector.dart.lib.js:43665:26)  at Object._microtaskLoop (http://localhost:49535/dart_sdk.js:38778:13)  at _startMicrotaskLoop (http://localhost:49535/dart_sdk.js:38784:13)  at http://localhost:49535/dart_sdk.js:34519:9  

Как бы то ни было, я не получаю эту ошибку при выборе страницы упражнений в меню ящика, только при переходе на эту новую страницу с домашней страницы. Упражнения и домашние страницы в некотором роде похожи, но все же отличаются в некоторых аспектах.

Благодарю

Ответ №1:

Технически, вы не добавляете onTap в ListView.builder , вы добавляете его к каждому ListTile добавленному строителем. 🙂

Объявите свои две переменные состояния:

 String testOnTap = ''; int nOfList = 1;  

внутри _OnTapWidgetIssueState класса, а не OnTapWidgetIssue внутри класса. Соглашение заключается в том, чтобы назвать их _testOnTap и _nOfList , соответственно, поскольку они являются частными для класса.

И обновите две переменные ВНУТРИ setState вызова, а не за его пределами.