繁体   English   中英

Flutter - TextField 如何过滤列表

[英]Flutter - TextField how to filter list

我是 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 是一个简单的 class:

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',
  ),
];

您可以在下面复制粘贴运行完整代码
你可以调用setState(() {}); addListener
代码片段

 _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(),
    );
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM