如何在列表颤动中创建SearchView [英] How Create SearchView in List Flutter

查看:40
本文介绍了如何在列表颤动中创建SearchView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要你的建议.我有代码可以从api到ListView提取数据.

i need yur advice . I Have code to fetch data from api to ListView .

问题是,如何在此listview中创建searchview.

The question is , how to create searchview in this listview .

class PM extends StatefulWidget {
  @override
  _PMState createState() => _PMState();
}

class _PMState extends State<PM> {
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

  void showInSnackBar(String value) {
    _scaffoldKey.currentState.showSnackBar(new SnackBar(
      content: new Text(value),
      backgroundColor: Colors.blueAccent,
    ));
  }

  final GlobalKey<RefreshIndicatorState> _refresh =
      GlobalKey<RefreshIndicatorState>();

  ModelPM modelPM;
  ModelPM _modelPM;

  bool loading = false;

  Future<Null> _fetchData() async {
    setState(() => loading = true);
    var value;

    SharedPreferences preferences = await SharedPreferences.getInstance();
    setState(() {
      value = preferences.getString("id");
    });

    final response = await http.post(BaseURL.systemTicket, body: {
      "key": BaseURL.apiKey,
      "method": "get",
      "resource": "tabel_pm",
      "filters[adminidtabelpm]": value,
    });

    if (response.statusCode == 200) {
      final data = jsonDecode(response.body);
      final pmModelFromJson = ModelPM.fromJson(data);

      setState(() {
        modelPM = pmModelFromJson;
        loading = false;
      });
    } else {
      showInSnackBar("Data Gagal Load");
    }
  }

  @override
  void initState() {
    super.initState();
    _fetchData();
  }

  _listPM(i) {
    final x = modelPM.results[i];
    return Card(
      elevation: 8.0,
      margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0),
      child: ListTile(
        onTap: () {
          Navigator.of(context).push(
              MaterialPageRoute(builder: (context) => DetilPM(x, _fetchData)));
        },
        contentPadding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0),


        title: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text(
              x.name,
              textAlign: TextAlign.start,
              style: TextStyle(
                  fontSize: 12,
                  color: x.status == "Not Yet"
                      ? Colors.blue
                      : x.status == "Pending" ? Colors.red : Colors.green,
                  fontWeight: FontWeight.bold),
            ),
            Text(
              'Status : ' + x.status,
              textAlign: TextAlign.start,
              style: TextStyle(
                  fontSize: 12,
                  color: x.status == "Not Yet"
                      ? Colors.blue
                      : x.status == "Pending" ? Colors.red : Colors.green,
                  fontWeight: FontWeight.bold),
            ),
            SizedBox(
              height: 10,
            ),
          ],
        ),

        subtitle: Column(
          children: <Widget>[
            Row(
              children: <Widget>[
                Expanded(
                  flex: 4,
                  child: Padding(
                      padding: EdgeInsets.only(left: 0.0),
                      child: Text("MIDTID",
                          style: TextStyle(color: Colors.black, fontSize: 10))),
                ),
                Expanded(
                  flex: 4,
                  child: Padding(
                      padding: EdgeInsets.only(left: 0.0),
                      child: Text("TID",
                          style: TextStyle(color: Colors.black, fontSize: 10))),
                ),
                Expanded(
                  flex: 4,
                  child: Padding(
                      padding: EdgeInsets.only(left: 0.0),
                      child: Text("CSI",
                          style: TextStyle(color: Colors.black, fontSize: 10))),
                ),
              ],
            ),
            Row(
              children: <Widget>[
                Expanded(
                  flex: 4,
                  child: Padding(
                      padding: EdgeInsets.only(left: 0.0),
                      child: Text(x.midtid,
                          style: TextStyle(color: Colors.black, fontSize: 10))),
                ),
                Expanded(
                  flex: 4,
                  child: Padding(
                      padding: EdgeInsets.only(left: 0.0),
                      child: Text(x.tid,
                          style: TextStyle(color: Colors.black, fontSize: 10))),
                ),
                Expanded(
                  flex: 4,
                  child: Padding(
                      padding: EdgeInsets.only(left: 0.0),
                      child: Text(x.csi,
                          style: TextStyle(color: Colors.black, fontSize: 10))),
                ),
              ],
            )
          ],
        ),
        trailing:
            Icon(Icons.keyboard_arrow_right, color: Colors.black, size: 30.0),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('PM CIMB List'),
      ),
      key: _scaffoldKey,

      body: RefreshIndicator(
        onRefresh: _fetchData,
        key: _refresh,
        child: loading
            ? Center(child: CircularProgressIndicator())
            : ListView.builder(
                itemCount: modelPM.results.length,
                itemBuilder: (context, i) {
                  return _listPM(i);
                },
              ),
      ),
    );
  }
}

并在此模型类PM以下.

and below this model class PM .

class ModelPM {
  final int status;
  final String status_message;
  final List<ModelPMResult> results;

  ModelPM({this.status, this.status_message, this.results});
  factory ModelPM.fromJson(Map<String, dynamic> json) {
    List<ModelPMResult> results = (json['result'] as List)
        .map((resultTicketJson) => ModelPMResult.fromJson(resultTicketJson))
        .toList();

    return ModelPM(
      status: json['status'],
      status_message: json['status_message'],
      results: results,
    );
  }
}

class ModelPMResult {
  final String id;
  final String admintabelpm;
  final String namaitfs;
  final String serial;
  final String merchantid;
  final String assetid;
  final String kondisi_edc;
  final String status;
  final String detail_edc;
  final String note;
  final String foto_struk;
  final String foto_mesin;
  final String foto_toko;
  final String kondisi_merchant;
  final String request_merchant;
  final String tgl_pm;
  final String name;
  final String batch;
  final String idmerchant;
  final String midtid;
  final String tid;
  final String csi;
  final String sign;

  ModelPMResult({
    this.id,
    this.admintabelpm,
    this.namaitfs,
    this.serial,
    this.merchantid,
    this.assetid,
    this.kondisi_edc,
    this.status,
    this.detail_edc,
    this.kondisi_merchant,
    this.request_merchant,
    this.tgl_pm,
    this.name,
    this.batch,
    this.idmerchant,
    this.midtid,
    this.tid,
    this.csi,
    this.foto_mesin,
    this.foto_struk,
    this.foto_toko,
    this.note,
    this.sign,
  });

  factory ModelPMResult.fromJson(Map<String, dynamic> json) {
    return new ModelPMResult(
      id: json['id'],
      admintabelpm: json['id'],
      namaitfs: json['namaitfs'],
      serial: json['serial'],
      merchantid: json['merchantid'],
      assetid: json['assetid'],
      kondisi_edc: json['kondisi_edc'],
      status: json['status'],
      detail_edc: json['detail_edc'],
      kondisi_merchant: json['kondisi_merchant'],
      request_merchant: json['request_merchant'],
      tgl_pm: json['tgl_pm'],
      name: json['name'],
      batch: json['batch'],
      idmerchant: json['idmerchant'],
      midtid: json['midtid'],
      tid: json['tid'],
      csi: json['csi'],
      note: json['note'],
      foto_mesin: json['foto_mesin'],
      foto_toko: json['foto_toko'],
      foto_struk: json['foto_struk'],
      sign: json['sign'],





    );
  }
}

请提供有关如何在我的Page Flutter中创建listview菜单的建议.谢谢你的建议 .以及在搜索菜单中删除数据后,API中的数据如何返回列表

Please advice for , how to create listview menu in my Page Flutter . Thanks for your advice . and also how after the data is deleted in the search menu, data from the API returns to the list

推荐答案

两种解决方案:您可以在下面复制粘贴运行完整代码
解决方案1:使用当前ListView页面进行搜索,在itemBuilder中返回的数据仅适合您的条件,例如字符串包含,否则不返回Container()

Two solutions : you can copy paste run full code below
Solution 1 : Search use current ListView page, In itemBuilder return data only fit your condition, such as string contains, if not return Container()

ListView.builder(
            itemCount: modelPM.results.length,
            itemBuilder: (context, i) {
              if (myController.text == "") return _listPM(i);
              if (myController.text != "" &&
                  modelPM.results[i].tid.contains(myController.text)) {
                return _listPM(i);
              } else {
                return Container();
              }
            },
          ),

演示1

完整代码1

import 'package:flutter/material.dart';
import 'dart:convert';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: PM(),
    );
  }
}

class PM extends StatefulWidget {
  @override
  _PMState createState() => _PMState();
}

class _PMState extends State<PM> {
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

  void showInSnackBar(String value) {
    _scaffoldKey.currentState.showSnackBar(new SnackBar(
      content: new Text(value),
      backgroundColor: Colors.blueAccent,
    ));
  }

  final GlobalKey<RefreshIndicatorState> _refresh =
      GlobalKey<RefreshIndicatorState>();

  ModelPM modelPM;
  ModelPM _modelPM;

  bool loading = false;

  Future<Null> _fetchData() async {
    setState(() => loading = true);
    var value;

    /*SharedPreferences preferences = await SharedPreferences.getInstance();
    setState(() {
      value = preferences.getString("id");
    });

    final response = await http.post(BaseURL.systemTicket, body: {
      "key": BaseURL.apiKey,
      "method": "get",
      "resource": "tabel_pm",
      "filters[adminidtabelpm]": value,
    });*/

    /* if (response.statusCode == 200) {
      final data = jsonDecode(response.body);
      final pmModelFromJson = ModelPM.fromJson(data);

      setState(() {
        modelPM = pmModelFromJson;
        loading = false;
      });
    } else {
      showInSnackBar("Data Gagal Load");
    }*/
    String responsebody = '''
     { 
"status": 200,
"status_message" : "OK",
"result" : [
    {
    "id": "123",
    "name" : "name1",
    "notes" : "notes1",
    "midtid" : "midtid1",
    "tid" : "tid1",
    "csi" : "csi1",
    "status" : "abc"
    }
    ,
    {
    "id": "456",
    "name" : "name2",
    "notes" : "notes2",
    "midtid" : "midtid2",
    "tid" : "tid2",
    "csi" : "csi2",
     "status" : "def"
    }
]
}
    ''';
    final data = jsonDecode(responsebody);
    final pmModelFromJson = ModelPM.fromJson(data);
    setState(() {
      modelPM = pmModelFromJson;
      loading = false;
    });
  }

  @override
  void initState() {
    super.initState();
    _fetchData();
  }

  _listPM(i) {
    final x = modelPM.results[i];
    return Card(
      elevation: 8.0,
      margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0),
      child: ListTile(
        onTap: () {
          /*Navigator.of(context).push(
              MaterialPageRoute(builder: (context) => DetilPM(x, _fetchData)));*/
        },
        contentPadding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0),
        title: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text(
              x.name,
              textAlign: TextAlign.start,
              style: TextStyle(
                  fontSize: 12,
                  color: x.status == "Not Yet"
                      ? Colors.blue
                      : x.status == "Pending" ? Colors.red : Colors.green,
                  fontWeight: FontWeight.bold),
            ),
            Text(
              'Status : ' + x.status,
              textAlign: TextAlign.start,
              style: TextStyle(
                  fontSize: 12,
                  color: x.status == "Not Yet"
                      ? Colors.blue
                      : x.status == "Pending" ? Colors.red : Colors.green,
                  fontWeight: FontWeight.bold),
            ),
            SizedBox(
              height: 10,
            ),
          ],
        ),
        subtitle: Column(
          children: <Widget>[
            Row(
              children: <Widget>[
                Expanded(
                  flex: 4,
                  child: Padding(
                      padding: EdgeInsets.only(left: 0.0),
                      child: Text("MIDTID",
                          style: TextStyle(color: Colors.black, fontSize: 10))),
                ),
                Expanded(
                  flex: 4,
                  child: Padding(
                      padding: EdgeInsets.only(left: 0.0),
                      child: Text("TID",
                          style: TextStyle(color: Colors.black, fontSize: 10))),
                ),
                Expanded(
                  flex: 4,
                  child: Padding(
                      padding: EdgeInsets.only(left: 0.0),
                      child: Text("CSI",
                          style: TextStyle(color: Colors.black, fontSize: 10))),
                ),
              ],
            ),
            Row(
              children: <Widget>[
                Expanded(
                  flex: 4,
                  child: Padding(
                      padding: EdgeInsets.only(left: 0.0),
                      child: Text(x.midtid,
                          style: TextStyle(color: Colors.black, fontSize: 10))),
                ),
                Expanded(
                  flex: 4,
                  child: Padding(
                      padding: EdgeInsets.only(left: 0.0),
                      child: Text(x.tid,
                          style: TextStyle(color: Colors.black, fontSize: 10))),
                ),
                Expanded(
                  flex: 4,
                  child: Padding(
                      padding: EdgeInsets.only(left: 0.0),
                      child: Text(x.csi,
                          style: TextStyle(color: Colors.black, fontSize: 10))),
                ),
              ],
            )
          ],
        ),
        trailing:
            Icon(Icons.keyboard_arrow_right, color: Colors.black, size: 30.0),
      ),
    );
  }

  final myController = TextEditingController();

  @override
  void dispose() {
    // Clean up the controller when the widget is removed from the
    // widget tree.
    myController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: TextField(
          controller: myController,
          decoration:
              InputDecoration(border: InputBorder.none, hintText: 'Search'),
          onChanged: (value) {
            setState(() {});
          },
        ),
      ),
      key: _scaffoldKey,
      body: RefreshIndicator(
        onRefresh: _fetchData,
        key: _refresh,
        child: loading
            ? Center(child: CircularProgressIndicator())
            : ListView.builder(
                itemCount: modelPM.results.length,
                itemBuilder: (context, i) {
                  if (myController.text == "") return _listPM(i);
                  if (myController.text != "" &&
                      modelPM.results[i].tid.contains(myController.text)) {
                    return _listPM(i);
                  } else {
                    return Container();
                  }
                },
              ),
      ),
    );
  }
}

class ModelPM {
  final int status;
  final String status_message;
  final List<ModelPMResult> results;

  ModelPM({this.status, this.status_message, this.results});
  factory ModelPM.fromJson(Map<String, dynamic> json) {
    List<ModelPMResult> results = (json['result'] as List)
        .map((resultTicketJson) => ModelPMResult.fromJson(resultTicketJson))
        .toList();

    return ModelPM(
      status: json['status'],
      status_message: json['status_message'],
      results: results,
    );
  }
}

class ModelPMResult {
  final String id;
  final String admintabelpm;
  final String namaitfs;
  final String serial;
  final String merchantid;
  final String assetid;
  final String kondisi_edc;
  final String status;
  final String detail_edc;
  final String note;
  final String foto_struk;
  final String foto_mesin;
  final String foto_toko;
  final String kondisi_merchant;
  final String request_merchant;
  final String tgl_pm;
  final String name;
  final String batch;
  final String idmerchant;
  final String midtid;
  final String tid;
  final String csi;
  final String sign;

  ModelPMResult({
    this.id,
    this.admintabelpm,
    this.namaitfs,
    this.serial,
    this.merchantid,
    this.assetid,
    this.kondisi_edc,
    this.status,
    this.detail_edc,
    this.kondisi_merchant,
    this.request_merchant,
    this.tgl_pm,
    this.name,
    this.batch,
    this.idmerchant,
    this.midtid,
    this.tid,
    this.csi,
    this.foto_mesin,
    this.foto_struk,
    this.foto_toko,
    this.note,
    this.sign,
  });

  factory ModelPMResult.fromJson(Map<String, dynamic> json) {
    return new ModelPMResult(
      id: json['id'],
      admintabelpm: json['id'],
      namaitfs: json['namaitfs'],
      serial: json['serial'],
      merchantid: json['merchantid'],
      assetid: json['assetid'],
      kondisi_edc: json['kondisi_edc'],
      status: json['status'],
      detail_edc: json['detail_edc'],
      kondisi_merchant: json['kondisi_merchant'],
      request_merchant: json['request_merchant'],
      tgl_pm: json['tgl_pm'],
      name: json['name'],
      batch: json['batch'],
      idmerchant: json['idmerchant'],
      midtid: json['midtid'],
      tid: json['tid'],
      csi: json['csi'],
      note: json['note'],
      foto_mesin: json['foto_mesin'],
      foto_toko: json['foto_toko'],
      foto_struk: json['foto_struk'],
      sign: json['sign'],
    );
  }
}

解决方案2:使用 SearchDelegate 搜索,数据实际上显示在另一页中
单击搜索按钮时,打开另一页
演示

Solution 2 : Search with SearchDelegate, data actually display in another page
When click search button, open another page
demo

完整的演示代码

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: SearchDemo(),
    );
  }
}


class SearchDemo extends StatefulWidget {
  static const String routeName = '/material/search';

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

class _SearchDemoState extends State<SearchDemo> {
  final _SearchDemoSearchDelegate _delegate = _SearchDemoSearchDelegate();
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  int _lastIntegerSelected;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        leading: IconButton(
          tooltip: 'Navigation menu',
          icon: AnimatedIcon(
            icon: AnimatedIcons.menu_arrow,
            color: Colors.white,
            progress: _delegate.transitionAnimation,
          ),
          onPressed: () {
            _scaffoldKey.currentState.openDrawer();
          },
        ),
        title: const Text('Numbers'),
        actions: <Widget>[
          IconButton(
            tooltip: 'Search',
            icon: const Icon(Icons.search),
            onPressed: () async {
              final int selected = await showSearch<int>(
                context: context,
                delegate: _delegate,
              );
              if (selected != null && selected != _lastIntegerSelected) {
                setState(() {
                  _lastIntegerSelected = selected;
                });
              }
            },
          ),
          //MaterialDemoDocumentationButton(SearchDemo.routeName),
          IconButton(
            tooltip: 'More (not implemented)',
            icon: Icon(
              Theme.of(context).platform == TargetPlatform.iOS
                  ? Icons.more_horiz
                  : Icons.more_vert,
            ),
            onPressed: () { },
          ),
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            MergeSemantics(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: const <Widget>[
                      Text('Press the '),
                      Tooltip(
                        message: 'search',
                        child: Icon(
                          Icons.search,
                          size: 18.0,
                        ),
                      ),
                      Text(' icon in the AppBar'),
                    ],
                  ),
                  const Text('and search for an integer between 0 and 100,000.'),
                ],
              ),
            ),
            const SizedBox(height: 64.0),
            Text('Last selected integer: ${_lastIntegerSelected ?? 'NONE' }.'),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton.extended(
        tooltip: 'Back', // Tests depend on this label to exit the demo.
        onPressed: () {
          Navigator.of(context).pop();
        },
        label: const Text('Close demo'),
        icon: const Icon(Icons.close),
      ),
      drawer: Drawer(
        child: Column(
          children: <Widget>[
            const UserAccountsDrawerHeader(
              accountName: Text('Peter Widget'),
              accountEmail: Text('peter.widget@example.com'),
              currentAccountPicture: CircleAvatar(
                backgroundImage: AssetImage(
                  'people/square/peter.png',
                  package: 'flutter_gallery_assets',
                ),
              ),
              margin: EdgeInsets.zero,
            ),
            MediaQuery.removePadding(
              context: context,
              // DrawerHeader consumes top MediaQuery padding.
              removeTop: true,
              child: const ListTile(
                leading: Icon(Icons.payment),
                title: Text('Placeholder'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _SearchDemoSearchDelegate extends SearchDelegate<int> {
  final List<int> _data = List<int>.generate(100001, (int i) => i).reversed.toList();
  final List<int> _history = <int>[42607, 85604, 66374, 44, 174];

  @override
  Widget buildLeading(BuildContext context) {
    return IconButton(
      tooltip: 'Back',
      icon: AnimatedIcon(
        icon: AnimatedIcons.menu_arrow,
        progress: transitionAnimation,
      ),
      onPressed: () {
        close(context, null);
      },
    );
  }

  @override
  Widget buildSuggestions(BuildContext context) {

    final Iterable<int> suggestions = query.isEmpty
        ? _history
        : _data.where((int i) => '$i'.startsWith(query));

    return _SuggestionList(
      query: query,
      suggestions: suggestions.map<String>((int i) => '$i').toList(),
      onSelected: (String suggestion) {
        query = suggestion;
        showResults(context);
      },
    );
  }

  @override
  Widget buildResults(BuildContext context) {
    final int searched = int.tryParse(query);
    if (searched == null || !_data.contains(searched)) {
      return Center(
        child: Text(
          '"$query"\n is not a valid integer between 0 and 100,000.\nTry again.',
          textAlign: TextAlign.center,
        ),
      );
    }

    return ListView(
      children: <Widget>[
        _ResultCard(
          title: 'This integer',
          integer: searched,
          searchDelegate: this,
        ),
        _ResultCard(
          title: 'Next integer',
          integer: searched + 1,
          searchDelegate: this,
        ),
        _ResultCard(
          title: 'Previous integer',
          integer: searched - 1,
          searchDelegate: this,
        ),
      ],
    );
  }

  @override
  List<Widget> buildActions(BuildContext context) {
    return <Widget>[
      if (query.isEmpty)
        IconButton(
          tooltip: 'Voice Search',
          icon: const Icon(Icons.mic),
          onPressed: () {
            query = 'TODO: implement voice input';
          },
        )
      else
        IconButton(
          tooltip: 'Clear',
          icon: const Icon(Icons.clear),
          onPressed: () {
            query = '';
            showSuggestions(context);
          },
        ),
    ];
  }
}

class _ResultCard extends StatelessWidget {
  const _ResultCard({this.integer, this.title, this.searchDelegate});

  final int integer;
  final String title;
  final SearchDelegate<int> searchDelegate;

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    return GestureDetector(
      onTap: () {
        searchDelegate.close(context, integer);
      },
      child: Card(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            children: <Widget>[
              Text(title),
              Text(
                '$integer',
                style: theme.textTheme.headline.copyWith(fontSize: 72.0),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _SuggestionList extends StatelessWidget {
  const _SuggestionList({this.suggestions, this.query, this.onSelected});

  final List<String> suggestions;
  final String query;
  final ValueChanged<String> onSelected;

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    return ListView.builder(
      itemCount: suggestions.length,
      itemBuilder: (BuildContext context, int i) {
        final String suggestion = suggestions[i];
        return ListTile(
          leading: query.isEmpty ? const Icon(Icons.history) : const Icon(null),
          title: RichText(
            text: TextSpan(
              text: suggestion.substring(0, query.length),
              style: theme.textTheme.subhead.copyWith(fontWeight: FontWeight.bold),
              children: <TextSpan>[
                TextSpan(
                  text: suggestion.substring(query.length),
                  style: theme.textTheme.subhead,
                ),
              ],
            ),
          ),
          onTap: () {
            onSelected(suggestion);
          },
        );
      },
    );
  }
}

这篇关于如何在列表颤动中创建SearchView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆