Flutter 實現簡單搜索功能


先建立一個主文件,繼承StatelessWidget,然后在home屬性中加入SearchBarDemo,這是一個自定義的Widget,主要代碼都在這個文件中。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title:'Flutter Demo',
      theme: ThemeData.light(),
      home: SearchBarDemo()
    );
  }
}

然后是搜索頁面,里面包含數據及搜索功能。

工作中這些數據是后台傳遞給我們,或者寫成配置文件的,這里我們就以List的方式代替了。我們在這個文件中定義了兩個List:

const searchList = [
  'jiejie-大長腿',
  'jiejie-水蛇腰',
  'gege-帥氣歐巴',
  'gege-小鮮肉'
];

const recentSuggest = [
  '推薦-1',
  '推薦-2',
];

點擊搜索按鈕

class SearchBarDemo extends StatefulWidget {
  _SearchBarDemoState createState() => _SearchBarDemoState();
}

class _SearchBarDemoState extends State<SearchBarDemo> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('SearchBarDemo'),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.search),
            onPressed: (){
              showSearch(context: context,delegate: SearchBarDelegate());
            },
          )
        ],
        ),
      
    );
  }
}

在點擊圖標時執行SearchBarDelegate 類,這個類繼承與SearchDelegate類,繼承后要重寫里邊的四個方法。

重寫buildActions方法:

buildActions方法時搜索條右側的按鈕執行方法,我們在這里方法里放入一個clear圖標。 當點擊圖片時,清空搜索的內容。

buildLeading 方法重寫

這個時搜索欄左側的圖標和功能的編寫,這里我們才用AnimatedIcon,然后在點擊時關閉整個搜索頁面。

buildResults方法重寫

buildResults方法,是搜到到內容后的展現,因為我們的數據都是模擬的,所以我這里就使用最簡單的Container+Card組件進行演示了。

buildSuggestions方法重寫

這個方法主要的作用就是設置推薦,就是我們輸入一個字,然后自動為我們推送相關的搜索結果。

class SearchBarDelegate extends SearchDelegate<String>{
  //清空按鈕
  @override
  List<Widget>buildActions(BuildContext context){
    return [
      IconButton(
        icon: Icon(Icons.clear),
        onPressed: () => query = "", //搜索值為空
      )
    ]; 
  }
  //返回上級按鈕
  @override
  Widget buildLeading(BuildContext context) {
    return IconButton(
      icon: AnimatedIcon(
        icon: AnimatedIcons.menu_arrow, progress: transitionAnimation
      ),
      onPressed: () => close(context, null)  //點擊時關閉整個搜索頁面
    );
  }
  //搜到到內容后的展現
  @override
  Widget buildResults(BuildContext context){
    return Container(
      width: 100.0,
      height:100.0,
      child: Card(
        color:Colors.redAccent,
        child: Center(
          child: Text(query),
        ),
      ),
    );
  }
  //設置推薦
  @override
  Widget buildSuggestions(BuildContext context){
    final suggestionsList= query.isEmpty
      ? recentSuggest 
      : searchList.where((input)=> input.startsWith(query)).toList();

    return ListView.builder(
      itemCount:suggestionsList.length,
      itemBuilder: (context,index) => ListTile(
        title: RichText( //富文本
          text: TextSpan(
            text: suggestionsList[index].substring(0,query.length),
            style: TextStyle(color: Colors.black,fontWeight: FontWeight.bold),
            children: [
              TextSpan(
                text: suggestionsList[index].substring(query.length),
                style: TextStyle(color: Colors.grey)
              )
            ]
          ),
        ),
      ),
    );  
  }

}

完整的search_bar_demo.dart文件代碼如下:

import 'package:flutter/material.dart';

const searchList = [
  'jiejie-大長腿',
  'jiejie-水蛇腰',
  'gege-帥氣歐巴',
  'gege-小鮮肉'
];

const recentSuggest = [
  '推薦-1',
  '推薦-2',
];

class SearchBarDemo extends StatefulWidget {
 
  _SearchBarDemoState createState() => _SearchBarDemoState();
}

class _SearchBarDemoState extends State<SearchBarDemo> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('SearchBarDemo'),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.search),
            onPressed: (){
              showSearch(context: context,delegate: SearchBarDelegate());
            },
          )
        ],
        ),
      
    );
  }
}

class SearchBarDelegate extends SearchDelegate<String>{
  //清空按鈕
  @override
  List<Widget>buildActions(BuildContext context){
    return [
      IconButton(
        icon: Icon(Icons.clear),
        onPressed: () => query = "", //搜索值為空
      )
    ]; 
  }
  //返回上級按鈕
  @override
  Widget buildLeading(BuildContext context) {
    return IconButton(
      icon: AnimatedIcon(
        icon: AnimatedIcons.menu_arrow, progress: transitionAnimation
      ),
      onPressed: () => close(context, null)  //點擊時關閉整個搜索頁面
    );
  }
  //搜到到內容后的展現
  @override
  Widget buildResults(BuildContext context){
    return Container(
      width: 100.0,
      height:100.0,
      child: Card(
        color:Colors.redAccent,
        child: Center(
          child: Text(query),
        ),
      ),
    );
  }
  //設置推薦
  @override
  Widget buildSuggestions(BuildContext context){
    final suggestionsList= query.isEmpty
      ? recentSuggest 
      : searchList.where((input)=> input.startsWith(query)).toList();

    return ListView.builder(
      itemCount:suggestionsList.length,
      itemBuilder: (context,index) => ListTile(
        title: RichText( //富文本
          text: TextSpan(
            text: suggestionsList[index].substring(0,query.length),
            style: TextStyle(color: Colors.black,fontWeight: FontWeight.bold),
            children: [
              TextSpan(
                text: suggestionsList[index].substring(query.length),
                style: TextStyle(color: Colors.grey)
              )
            ]
          ),
        ),
      ),
    );  
  }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM