Я пытаюсь создать автозаполнение TextField
. Этот работает, когда я использовал приведенный ниже жестко закодированный List
.
List<String> suggestions = [
"Apple",
"Actual",
"Actuary",
"America",
"Argentina",
];
Но когда я получал данные из SQLite и фильтровал, это не фильтрация. Не работает. Список SQLite также получает тот же формат, что и приведенный выше. Но это не призыв к itemFilter
расставанию. Пожалуйста помоги. Я новичок в флаттере.
static Future<List<String>> selectItems() async {
var db = await _openDB();
final usersData = await db.query("albums");
return usersData.map((Map<String, dynamic> row) {
return row["albumname"] as String;
}).toList();}
List<String> itemsList;
void selectItems() async {
itemsList = await DBManager.selectItems();
}
Это текстовый код
Container(
width: _width * 2,
height: 50,
padding: const EdgeInsets.symmetric(horizontal: 10),
child: AutoCompleteTextField(
controller: txtAlbumSuggest,
suggestions: itemsList,
clearOnSubmit: false,
style: TextStyle(color: Colors.black,fontSize: 15),
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.5)
)
),
itemFilter: (item,query){
return item.toLowerCase().startsWith(query.toLowerCase());
},
itemSorter: (a,b){
return a.compareTo(b);
},
itemSubmitted: (item){
txtAlbumSuggest.text=item;
},
itemBuilder: (context,item){
return Container(
padding: EdgeInsets.all(20.0),
child: Row(
children: <Widget>[
Text(
item,
style: TextStyle(color: Colors.black),
)
],
),
);
},
),
),
Предполагая, что этот код находится в вашем классе DBManager
:
static Future<List<String>> selectItems() async {
var db = await _openDB();
final usersData = await db.query("albums");
return usersData.map((Map<String, dynamic> row) {
return row["albumname"] as String;
}).toList();
}
Вы должны использовать setState()
для обновления состояния вашего класса Widget
:
List<String> _itemsList;
void _loadItems() async {
setState(() => _itemsList = await DBManager.selectItems());
}
В противном случае ваш Container
не получит уведомление об асинхронном обновлении данных.
Кроме того, важно вызвать _loadItems()
в классе Widget
сразу после загрузки макета, чтобы убедиться, что данные получены:
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => _loadItems(context));
}
Следует полному коду примера:
void main() {
runApp(MaterialApp(home: HomeScreen(), title: 'Flutter Example'));
}
class HomeScreen extends StatefulWidget {
HomeScreen({Key key}) : super(key: key);
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<String> _itemsList;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => _loadItems(context));
}
void _loadItems() async {
setState(() => _itemsList = await DBManager.selectItems());
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
width: _width * 2,
height: 50,
padding: const EdgeInsets.symmetric(horizontal: 10),
child: AutoCompleteTextField(
controller: txtAlbumSuggest,
suggestions: _itemsList,
clearOnSubmit: false,
style: TextStyle(color: Colors.black, fontSize: 15),
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.5))),
itemFilter: (item, query) {
return item.toLowerCase().startsWith(query.toLowerCase());
},
itemSorter: (a, b) {
return a.compareTo(b);
},
itemSubmitted: (item) {
txtAlbumSuggest.text = item;
},
itemBuilder: (context, item) {
return Container(
padding: EdgeInsets.all(20.0),
child: Row(
children: <Widget>[
Text(
item,
style: TextStyle(color: Colors.black),
)
],
),
);
},
),
),
),
);
}
}
void selectItems() async
переименуйте этот метод, и вам может понадобиться setstate.