Flutter | SearchDelegate | При поиске я должен создать API после получения ответа, я должен создать виджет

#dart #flutter

#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. Вы нашли решение?

2. вы нашли какую-нибудь работу вслух

3. Любое решение, которое кто-либо действительно оценил…

Ответ №1:

Чтобы дождаться 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();
  }
}