【问题标题】:Flutter - TextField how to filter listFlutter - TextField 如何过滤列表
【发布时间】:2020-06-10 12:56:49
【问题描述】:

我是 Flutter 的新手,我正在努力了解事情的运作方式。
我创建了一个应该显示商店列表的简单应用程序,我需要整个屏幕滚动,据我所知我不能使用ListView

我还添加了TextField,我想用它来过滤内容,以便用户可以看到他想要的商店。

这是我的代码:

import 'package:testapp/models/maison.dart';
import 'package:testapp/widgets/maison_card.dart';
import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  TextEditingController _searchTextController = new TextEditingController();
  String filter;
  List<Maison> _maisons = maisons;

  @override
  void initState() {
    super.initState();
    _searchTextController.addListener(() {
      print(_searchTextController.text);
      filter = _searchTextController.text;
    });
  }

  @override
  void dispose() {
    _searchTextController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        children: <Widget>[
          Container(
            height: MediaQuery.of(context).size.width * 0.70,
            decoration: BoxDecoration(
              boxShadow: [
                BoxShadow(
                  color: Colors.black26,
                  offset: Offset(0.0, 2.0),
                  blurRadius: 6.0,
                )
              ],
            ),
            child: Image(
              image: AssetImage('assets/images/bg-home.png'),
              fit: BoxFit.cover,
            ),
          ),
          Transform.translate(
            offset: Offset(0, -25),
            child: Container(
              height: 60.0,
              padding: EdgeInsets.only(left: 20, top: 8),
              margin: EdgeInsets.symmetric(horizontal: 16),
              decoration: BoxDecoration(
                color: Colors.white,
                boxShadow: [
                  BoxShadow(
                    color: Colors.grey[350],
                    blurRadius: 20.0,
                    offset: Offset(0, 10.0),
                  ),
                ],
              ),
              child: TextField(
                controller: _searchTextController,
                decoration: InputDecoration(
                  suffixIcon: Icon(
                    Icons.search,
                    color: Colors.black,
                    size: 20.0,
                  ),
                  border: InputBorder.none,
                  hintText: 'Cerca la maison',
                ),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 16.0,
              right: 16.0,
            ),
            child: Row(
              children: <Widget>[
                Text(
                  "Le Maison",
                  style: Theme.of(context).textTheme.headline1,
                ),
                Spacer(),
              ],
            ),
          ),
          ..._maisons.map((Maison m) {
            return filter == null || filter == ''
                ? MaisonCard(maison: m)
                : m.name.toLowerCase().contains(filter.toLowerCase())
                    ? MaisonCard(maison: m)
                    : Container();
          }).toList(),
        ],
      ),
    );
  }
}

最后我有这个:

..._maisons.map((Maison m) {
            return filter == null || filter == ''
                ? MaisonCard(maison: m)
                : m.name.toLowerCase().contains(filter.toLowerCase())
                    ? MaisonCard(maison: m)
                    : Container();
          }).toList(),

应该根据filter 值打印商店列表。
我认为问题在于小部件树已经构建,所以如果我输入一些文本,树就不会再次打印。
还有其他方法可以完成这项任务吗?

Maisons 是一个简单的类:

import 'package:flutter/material.dart';

class Maison {
  final String id;
  final String name;
  final String imageUrl;

  Maison({
    @required this.id,
    @required this.name,
    @required this.imageUrl,
  });
}

List<Maison> maisons = [
  Maison(
    id: '1',
    name: 'Armani',
    imageUrl:
        'https://images.unsplash.com/photo-1495562569060-2eec283d3391?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1500&q=80',
  ),
  Maison(
    id: '2',
    name: 'Dolce & Gabbana',
    imageUrl:
        'https://images.unsplash.com/photo-1582559934353-2e47140e7501?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1788&q=80',
  ),
  Maison(
    id: '3',
    name: 'Zegna',
    imageUrl:
        'https://images.unsplash.com/photo-1553355617-f7342d67a95f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1500&q=80',
  ),
  Maison(
    id: '4',
    name: 'Cavalli',
    imageUrl:
        'https://images.unsplash.com/photo-1555141816-810dd5692b6a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1789&q=80',
  ),
];

【问题讨论】:

标签: flutter


【解决方案1】:

您可以在下面复制粘贴运行完整代码
您可以在addListener 中拨打setState(() {});
代码 sn -p

 _searchTextController.addListener(() {
      print(_searchTextController.text);
      filter = _searchTextController.text;
      setState(() {});
    });

工作演示

完整代码

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  TextEditingController _searchTextController = new TextEditingController();
  String filter;
  List<Maison> _maisons = maisons;

  @override
  void initState() {
    super.initState();
    _searchTextController.addListener(() {
      print(_searchTextController.text);
      filter = _searchTextController.text;
      setState(() {});
    });
  }

  @override
  void dispose() {
    _searchTextController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        children: <Widget>[
          Container(
            height: MediaQuery.of(context).size.width * 0.70,
            decoration: BoxDecoration(
              boxShadow: [
                BoxShadow(
                  color: Colors.black26,
                  offset: Offset(0.0, 2.0),
                  blurRadius: 6.0,
                )
              ],
            ),
            child: Image(
              image: NetworkImage('https://picsum.photos/250?image=9'),
              fit: BoxFit.cover,
            ),
          ),
          Transform.translate(
            offset: Offset(0, -25),
            child: Container(
              height: 60.0,
              padding: EdgeInsets.only(left: 20, top: 8),
              margin: EdgeInsets.symmetric(horizontal: 16),
              decoration: BoxDecoration(
                color: Colors.white,
                boxShadow: [
                  BoxShadow(
                    color: Colors.grey[350],
                    blurRadius: 20.0,
                    offset: Offset(0, 10.0),
                  ),
                ],
              ),
              child: TextField(
                controller: _searchTextController,
                decoration: InputDecoration(
                  suffixIcon: Icon(
                    Icons.search,
                    color: Colors.black,
                    size: 20.0,
                  ),
                  border: InputBorder.none,
                  hintText: 'Cerca la maison',
                ),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 16.0,
              right: 16.0,
            ),
            child: Row(
              children: <Widget>[
                Text(
                  "Le Maison",
                  style: Theme.of(context).textTheme.headline2,
                ),
                Spacer(),
              ],
            ),
          ),
          ..._maisons.map((Maison m) {
            return filter == null || filter == ''
                ? MaisonCard(maison: m)
                : m.name.toLowerCase().contains(filter.toLowerCase())
                    ? MaisonCard(maison: m)
                    : Container();
          }).toList(),
        ],
      ),
    );
  }
}

Widget MaisonCard({Maison maison}) {
  return Card(
    child: Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        ListTile(
          leading: Icon(Icons.album),
          title: Text('${maison.name}'),
          subtitle: Text('${maison.id}'),
        ),
      ],
    ),
  );
}

class Maison {
  final String id;
  final String name;
  final String imageUrl;

  Maison({
    @required this.id,
    @required this.name,
    @required this.imageUrl,
  });
}

List<Maison> maisons = [
  Maison(
    id: '1',
    name: 'Armani',
    imageUrl:
        'https://images.unsplash.com/photo-1495562569060-2eec283d3391?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1500&q=80',
  ),
  Maison(
    id: '2',
    name: 'Dolce & Gabbana',
    imageUrl:
        'https://images.unsplash.com/photo-1582559934353-2e47140e7501?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1788&q=80',
  ),
  Maison(
    id: '3',
    name: 'Zegna',
    imageUrl:
        'https://images.unsplash.com/photo-1553355617-f7342d67a95f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1500&q=80',
  ),
  Maison(
    id: '4',
    name: 'Cavalli',
    imageUrl:
        'https://images.unsplash.com/photo-1555141816-810dd5692b6a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1789&q=80',
  ),
];

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: "test",
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: HomePage(),
    );
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 2023-02-22
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    相关资源
    最近更新 更多