颤振SearchDelegate |在搜索中,我必须在获得响应后制作API,我已经构建了一个小部件

时间:2019-03-13 20:03:37

标签: dart flutter

我正在尝试在搜索上进行API调用,因此我必须构建一个小部件。

这正确吗?

class DataSearch extends SearchDelegate<Future<Widget>> {

  Future serachdb(searchData) async {    
    var url = '$_globalUrl/api/searchdata';
    var param = {'searchby': searchData};
    var result = await http.post(url, body: param);
    if (result.body != '') {
      userData = json.decode(result.body);
    }
  }

  @override
  Widget buildResults(BuildContext context) {
    serachdb(query);  // it doesn't wait untill this completes  
    return resultContent();
  }

  Widget resultContent(){
    return new Scaffold(
      /*
      some code
      */
    );
  }
}

1 个答案:

答案 0 :(得分:2)

为了等待Future完成,可以从FutureBuilder方法返回buildResults。我已经修改了您的代码示例以显示其工作方式。

class DataSearch extends SearchDelegate<Future<Widget>> {

  Future serachdb(searchData) async {
    var url = '$_globalUrl/api/searchdata';
    var param = {'searchby': searchData};
    var result = await http.post(url, body: param);
    return result.body != '' ? json.decode(result.body) : null;
  }

  @override
  Widget buildResults(BuildContext context) {
    return FutureBuilder(
      future: serachdb(query),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          return resultContent();
        } else {
          return CircularProgressIndicator();
        }
      },
    );
  }

  Widget resultContent(){
    return new Scaffold(
      /*
      some code
      */
    );
  }
}

为了完整起见,我还在下面提供了完整的代码示例,其中显示了如何从API获取搜索结果并将其显示在应用程序中。

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

Future<void> main() async {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
        actions: [
          IconButton(
            icon: Icon(Icons.search),
            onPressed: () async {
              final toDo = await showSearch<ToDo>(
                context: context,
                delegate: ToDoSearchDelegate(),
              );
            },
          ),
        ],
      ),
    );
  }
}

class ToDo {
  int id;
  String title;
  bool completed;

  ToDo({
    this.id,
    this.title,
    this.completed,
  });

  factory ToDo.fromJson(Map<String, dynamic> json) => ToDo(
        id: json['id'],
        title: json['title'],
        completed: json['completed'],
      );

  Map<String, dynamic> toJson() => {
        'id': id,
        'title': title,
        'completed': completed,
      };
}

class ToDoSearchDelegate extends SearchDelegate<ToDo> {
  @override
  List<Widget> buildActions(BuildContext context) {
    return <Widget>[];
  }

  @override
  Widget buildLeading(BuildContext context) {
    return IconButton(
      icon: Icon(Icons.arrow_back),
      onPressed: () {
        close(context, null);
      },
    );
  }

  @override
  Widget buildResults(BuildContext context) {
    return FutureBuilder<List<ToDo>>(
      future: _search(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          return ListView.builder(
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(snapshot.data[index].title),
                onTap: () {
                  close(context, snapshot.data[index]);
                },
              );
            },
            itemCount: snapshot.data.length,
          );
        } else {
          return Center(
            child: CircularProgressIndicator(),
          );
        }
      },
    );
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    return Container();
  }

  Future<List<ToDo>> _search() async {
    final authority = 'jsonplaceholder.typicode.com';
    final path = 'todos';
    final queryParameters = <String, String>{'title': query};
    final uri = Uri.https(authority, path, queryParameters);
    final result = await http.get(uri);
    final list = json.decode(result.body) as List;
    return list.map((e) => ToDo.fromJson(e)).toList();
  }
}