blog icon indicating copy to clipboard operation
blog copied to clipboard

flutter 实现搜索功能

Open huruji opened this issue 5 years ago • 0 comments

App 中的搜索功能非常常见,Flutter 提供了内置的搜索功能,如最常见的把搜索功能放置在 appbar 的右边:

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(
      home: MyApp(),
    ));

class MyApp extends StatelessWidget {
  const MyApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.search),
            onPressed: () {
            },
          )
        ],
      ),
    );
  }
}

使用内置的搜索功能需要实现自己的 Delegate,简单回顾一下,常见的搜索功能:常见的搜索输入文字过程中有相应的提示,输入完成后显示对应的搜索结果,实现一个简单的如下:

class SearchBarView extends SearchDelegate<String> {
  String searchHint = '请输入内容';

  @override
  List<Widget> buildActions(BuildContext context) {
    // TODO: implement buildActions
    return [Text('hello')];
  }

  @override
  Widget buildLeading(BuildContext context) {
    // TODO: implement buildLeading
    return Icon(Icons.book);
  }

  @override
  Widget buildResults(BuildContext context) {
    // TODO: implement buildResults
    return Text('world');
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    // TODO: implement buildSuggestions
    return Text('ooo');
  }
}

实现的方法主要有:

  • buildActions 显示在最右边的图标列表。

  • buildLeading 搜索栏左边的图标,一般都是返回。

  • buildResults 这个回调里进行搜索和并返回自己的搜索结果。

  • buildSuggestions 返回建议搜索结果。

void main() => runApp(MaterialApp(
      home: MyApp(),
    ));

class MyApp extends StatelessWidget {
  const MyApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.search),
            onPressed: () {
              showSearch(context: context, delegate: SearchBarView());
            },
          )
        ],
      ),
    );
  }
}

效果如下:

实现一个简单搜索qq音乐的例子,如下:

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

class hotSearch extends StatefulWidget {
  hotSearch({Key key}) : super(key: key);

  _hotSearchState createState() => _hotSearchState();
}

class _hotSearchState extends State<hotSearch> {
  List data = [];

  getData() async {
    Dio dio = new Dio();
    Response res = await dio.get(
        'https://c.y.qq.com/splcloud/fcgi-bin/gethotkey.fcg?g_tk=5381&uin=0&notice=0&platform=h5&needNewCode=1&_=1513317614040');

    var hotkey = json.decode(res.data)['data']['hotkey'];
    setState(() {
      data = hotkey;
    });
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    this.getData();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        child: ListView.builder(
      itemBuilder: (BuildContext context, int index) {
        return Text(data[index]['k']);
      },
      itemCount: data.length,
    ));
  }
}

class searchResult extends StatefulWidget {
  String keyword;
  searchResult({Key key, this.keyword}) : super(key: key);

  _searchResultState createState() => _searchResultState();
}

class _searchResultState extends State<searchResult> {
  List data = [];

  getData() async {
    Dio dio = new Dio();
    print(widget.keyword);
    String word = widget.keyword;
    Response res = await dio.get(
        'https://c.y.qq.com/soso/fcgi-bin/client_search_cp?g_tk=5381&p=1&n=20&w=$word&format=json');
    print('key');

    List songs = json.decode(res.data)['data']['song']['list'];

    setState(() {
      data = songs;
    });
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    this.getData();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        child: ListView.builder(
      itemCount: data.length,
      itemBuilder: (BuildContext context, int index) {
        return Text(data[index]['songname']);
      },
    ));
  }
}

class SearchBarView extends SearchDelegate<String> {
  String searchHint = '请输入内容';

  @override
  List<Widget> buildActions(BuildContext context) {
    // TODO: implement buildActions
    return [Text('hello')];
  }

  @override
  Widget buildLeading(BuildContext context) {
    // TODO: implement buildLeading
    return Icon(Icons.book);
  }

  @override
  Widget buildResults(BuildContext context) {
    // TODO: implement buildResults
    return searchResult(
      keyword: query,
    );
  }

  @override
  Widget buildSuggestions(BuildContext context) {
    // TODO: implement buildSuggestions
    return hotSearch();
  }
}

void main() => runApp(MaterialApp(
      home: MyApp(),
    ));

class MyApp extends StatelessWidget {
  const MyApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.search),
            onPressed: () {
              showSearch(context: context, delegate: SearchBarView());
            },
          )
        ],
      ),
    );
  }
}

huruji avatar Oct 13 '19 18:10 huruji