#class #flutter #listview #dart
#класс #flutter #listview #dart
Вопрос:
Я использовал некоторые классы онлайн, чтобы отредактировать их и создать то, что мне было нужно, вот что я получил, однако мне нужно получить данные с помощью функции onChange, чтобы я мог использовать их в разных формах в приложении.
Как бы я мог это сделать? Это код класса:
import 'package:flutter/material.dart';
import 'package:sembast/sembast.dart';
import 'flutter_search_pannel/flutter_search_panel.dart';
import 'flutter_search_pannel/search_item.dart';
class SuspendedListPicker extends StatefulWidget {
SuspendedListPicker({
this.data,
this.onChanged,
});
List<SearchItem<int>> data = [];
final Function onChanged;
@override
_MyAppState createState() => new _MyAppState(data);
}
class _MyAppState extends State<SuspendedListPicker> {
_MyAppState(this.data);
List<SearchItem<int>> data = [];
var selected;
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width * 0.55,
child: FlutterSearchPanel<int>(
title: "Selecione",
data: data,
//padding: EdgeInsets.all(10.0),
icon: Icon(Icons.label, color: Colors.blue[300]),
color: Colors.white,
textStyle: TextStyle(
color: Colors.black,
fontSize: 28.0,
// onChanged: (value) {
// print(value);
// },
),
));
}
}
И вот ресурс Flutter_search_panel, который я также изменил (это импорт изhttps://pub.dev/packages/flutter_search_panel)
import 'package:flutter/material.dart';
import 'search_page.dart';
import 'search_item.dart';
class FlutterSearchPanel<TValue> extends StatefulWidget {
@required
final Function onChanged;
@required
final List<SearchItem<TValue>> data;
final String title;
final Icon icon;
final TextStyle textStyle;
final Color color;
final EdgeInsetsGeometry padding;
final TValue selected;
FlutterSearchPanel(
{this.onChanged,
this.title,
this.data,
this.icon,
this.textStyle,
this.selected,
this.padding,
this.color});
@override
State<StatefulWidget> createState() {
return new _FlutterSearchPanelState<TValue>();
}
}
class _FlutterSearchPanelState<TValue>
extends State<FlutterSearchPanel<TValue>> {
SearchItem<TValue> selection;
final _defaultIcon = Icons.label;
final TextStyle _defaultTextStyle =
new TextStyle(color: Colors.red, fontSize: 22.0);
final Color _defaultColor = Colors.red;
final EdgeInsetsGeometry _defaultPadding = EdgeInsets.all(10.0);
@override
void initState() {
super.initState();
if (widget.selected != null) {
selection = widget.data.firstWhere(
(item) => item.value == widget.selected,
orElse: () => selection = widget.data[0]);
} else {
selection = widget.data[0];
}
}
@override
void dispose() {
super.dispose();
}
_openSearchPage() async {
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SearchPage(
title: widget.title,
data: widget.data,
icon: widget.icon ?? _defaultIcon,
padding: widget.padding ?? _defaultPadding,
color: widget.color ?? _defaultColor,
textStyle: widget.textStyle ?? _defaultTextStyle)),
);
if (result != null) {
setState(() {
selection = resu<
});
if (widget.onChanged != null) {
widget.onChanged((result as SearchItem<TValue>).value);
}
}
}
@override
Widget build(BuildContext context) => new InkWell(
onTap: _openSearchPage,
child: SizedBox(
//height: MediaQuery.of(context).size.height,
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black)),
child: Text(
selection.text,
textAlign: TextAlign.right,
style: widget.textStyle ?? Theme.of(context).textTheme.button,
),
),
),
);
}
// RaisedButton(
// color: widget.color ?? Colors.blue,
// child: Flex(
// direction: Axis.horizontal,
// mainAxisSize: MainAxisSize.min,
// children: <Widget>[
// Flexible(
// child: Padding(
// padding: const EdgeInsets.all(10.0),
// child: Text(
// selection.text,
// style: widget.textStyle ?? Theme.of(context).textTheme.button, textAlign: TextAlign.right,
// ),
// ),
// ),
// ],
// ),
// padding: widget.padding,
// onPressed: _openSearchPage,
// );
Комментарии:
1. Этот список searchitem<int>, откуда он берется?
2. панель поиска flutter, разрешите обновить с помощью ресурса, который мне также пришлось изменить, но импорт оттуда
3. По сути, значением будет выбор, сделанный пользователем. Затем вы можете просто установить свойство onchanged для вашей функции onchanged, передающей значение. OnChanged: (значение) => OnChanged(значение). Убедитесь, что вы приняли значение в качестве типа в параметрах для вашего OnChanged souce. Кстати, ваше свойство data установлено как в вашем виджете, так и в классах состояний. Удалите тот, который находится в вашем классе состояния, поскольку он передается в вашем конструкторе виджетов.
Ответ №1:
Вы можете скопировать вставить запустить полный код ниже,
вы можете в onChanged
вызове widget.onChanged(value)
И определите переменную currentValue
для получения этого value
фрагмент кода
class _SuspendedListPickerState extends State<SuspendedListPicker> {
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width * 0.55,
child: FlutterSearchPanel<int>(
title: "Selecione",
data: widget.data,
//padding: EdgeInsets.all(10.0),
icon: Icon(Icons.label, color: Colors.blue[300]),
color: Colors.white,
textStyle: TextStyle(color: Colors.black, fontSize: 28.0),
onChanged: (value) {
widget.onChanged(value);
},
));
}
}
...
int currentValue;
...
SuspendedListPicker(
data: data,
onChanged: (value) {
setState(() {
currentValue = value;
});
},
),
Text('current value $currentValue'),
рабочая демонстрация
полный код
import 'package:flutter/material.dart';
class SearchItem<TValue> {
/// Item value
final TValue value;
/// Item display text
final String text;
SearchItem(this.value, this.text);
}
class SearchPage extends StatefulWidget {
final List<SearchItem> data;
final Icon icon;
final TextStyle textStyle;
final Color color;
final EdgeInsetsGeometry padding;
final String title;
SearchPage(
{this.data,
this.icon,
this.textStyle,
this.padding,
this.color,
this.title});
@override
State<StatefulWidget> createState() {
return new _SearchPageState();
}
}
class _SearchPageState extends State<SearchPage> {
TextEditingController controller = new TextEditingController();
List<SearchItem> _searchList = [];
List<SearchItem> _dataList = [];
@override
void initState() {
super.initState();
_dataList = widget.data;
}
@override
void dispose() {
_searchList.clear();
controller.dispose();
super.dispose();
}
_onChange(SearchItem selection) {
Navigator.pop(context, selection);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
backgroundColor: widget.color,
title: new Text(widget.title ?? 'Search Page'),
elevation: 0.0,
),
body: new Column(
children: <Widget>[
new Container(
color: widget.color,
child: new Padding(
padding: widget.padding,
child: new Card(
child: new ListTile(
leading: new Icon(Icons.search),
title: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Search', border: InputBorder.none),
onChanged: onSearchTextChanged,
),
trailing: new IconButton(
icon: new Icon(Icons.cancel),
onPressed: () {
controller.clear();
onSearchTextChanged('');
},
),
),
),
),
),
new Expanded(
child: _searchList.length != 0 || controller.text.isNotEmpty
? new ListView.builder(
itemCount: _searchList.length,
itemBuilder: (context, i) {
return new Card(
color: widget.color,
child: FlatButton(
onPressed: () {
Navigator.pop(context, _searchList[i]);
},
child: new ListTile(
leading: widget.icon,
title: new Text(_searchList[i].text,
style: widget.textStyle),
),
),
margin: const EdgeInsets.all(0.0),
);
},
)
: new ListView.builder(
itemCount: _dataList.length,
itemBuilder: (context, index) {
return new Card(
color: widget.color,
child: FlatButton(
onPressed: () {
_onChange(_dataList[index]);
},
child: new ListTile(
leading: widget.icon,
title: new Text(
_dataList[index].text,
style: widget.textStyle,
),
)),
margin: const EdgeInsets.all(0.0),
);
},
),
),
],
),
);
}
onSearchTextChanged(String text) async {
_searchList.clear();
if (text.isEmpty) {
setState(() {});
return;
}
_dataList.forEach((userDetail) {
if (userDetail.text.startsWith(text.toLowerCase()) ||
userDetail.text.toLowerCase().startsWith(
text.toLowerCase())) if (_searchList.contains(userDetail) ==
false) {
_searchList.add(userDetail);
}
});
setState(() {});
}
}
class FlutterSearchPanel<TValue> extends StatefulWidget {
@required
final Function onChanged;
@required
final List<SearchItem<TValue>> data;
final String title;
final Icon icon;
final TextStyle textStyle;
final Color color;
final EdgeInsetsGeometry padding;
final TValue selected;
FlutterSearchPanel(
{this.onChanged,
this.title,
this.data,
this.icon,
this.textStyle,
this.selected,
this.padding,
this.color});
@override
State<StatefulWidget> createState() {
return new _FlutterSearchPanelState<TValue>();
}
}
class _FlutterSearchPanelState<TValue>
extends State<FlutterSearchPanel<TValue>> {
SearchItem<TValue> selection;
final _defaultIcon = Icons.label;
final TextStyle _defaultTextStyle =
new TextStyle(color: Colors.red, fontSize: 22.0);
final Color _defaultColor = Colors.red;
final EdgeInsetsGeometry _defaultPadding = EdgeInsets.all(10.0);
@override
void initState() {
super.initState();
if (widget.selected != null) {
selection = widget.data.firstWhere(
(item) => item.value == widget.selected,
orElse: () => selection = widget.data[0]);
} else {
selection = widget.data[0];
}
}
@override
void dispose() {
super.dispose();
}
_openSearchPage() async {
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SearchPage(
title: widget.title,
data: widget.data,
icon: widget.icon ?? _defaultIcon,
padding: widget.padding ?? _defaultPadding,
color: widget.color ?? _defaultColor,
textStyle: widget.textStyle ?? _defaultTextStyle)),
);
if (result != null) {
setState(() {
selection = resu<
});
if (widget.onChanged != null) {
widget.onChanged((result as SearchItem<TValue>).value);
}
}
}
@override
Widget build(BuildContext context) => new InkWell(
onTap: _openSearchPage,
child: SizedBox(
//height: MediaQuery.of(context).size.height,
child: Container(
decoration: BoxDecoration(border: Border.all(color: Colors.black)),
child: Text(
selection.text,
textAlign: TextAlign.right,
style: widget.textStyle ?? Theme.of(context).textTheme.button,
),
),
),
);
}
class SuspendedListPicker extends StatefulWidget {
SuspendedListPicker({
Key key,
this.data,
this.onChanged,
}) : super(key: key);
List<SearchItem<int>> data = [];
final Function onChanged;
@override
_SuspendedListPickerState createState() => _SuspendedListPickerState();
}
class _SuspendedListPickerState extends State<SuspendedListPicker> {
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width * 0.55,
child: FlutterSearchPanel<int>(
title: "Selecione",
data: widget.data,
//padding: EdgeInsets.all(10.0),
icon: Icon(Icons.label, color: Colors.blue[300]),
color: Colors.white,
textStyle: TextStyle(color: Colors.black, fontSize: 28.0),
onChanged: (value) {
widget.onChanged(value);
},
));
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int currentValue;
List<SearchItem<int>> data = [
SearchItem(0, 'This'),
SearchItem(1, 'is'),
SearchItem(2, 'a'),
SearchItem(3, 'test'),
SearchItem(4, '.'),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SuspendedListPicker(
data: data,
onChanged: (value) {
setState(() {
currentValue = value;
});
},
),
Text('current value $currentValue'),
],
),
),
);
}
}