Flutter系列(八)搜索框详解

底部导航+顶部导航+图片列表的完整代码

Flutter系列(四)底部导航+顶部导航+图文列表完整代码_摸金青年v的博客-CSDN博客

目录

一、前言

二、搜索框实现方案

三、完整工程代码

1. 自定义的搜索框组件SearchAppBar   search.dart   

2. 搜索详情页 searchDetail.dart  

3. 在首页index.dart中,使用搜索框 SearchAppBar


一、前言

        本文实现当前主流app的搜索框:点击搜索框右侧滑动出搜索页,搜索页中有关键词,样式如图所示,图1是嵌入搜索框的首页,图2是点击搜索框后的搜索页

                   Flutter系列(八)搜索框详解_第1张图片                  Flutter系列(八)搜索框详解_第2张图片

 二、搜索框实现方案

            1)搜索框:使用Container组件构建一个灰色圆角框,框内嵌入搜索图标Icon+文本编辑TextField,文本编辑这里设为禁用readOnly: true,真正的搜索在搜索页输入

           2) 搜索页:是一个普通页面,同样嵌入一个搜索框这里是可以编辑的,还有搜索历史的关键词

           3)页面切换:使用了动画特效,搜索页从右侧滑出(大部分的app都是这样的效果)

三、完整工程代码

Flutter系列(八)搜索框详解_第3张图片

 1. 自定义的搜索框组件SearchAppBar   search.dart   

import 'package:flutter/material.dart';
import 'package:flutter_play/searchDetail.dart';

/*搜索页*/
class SearchAppBar extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 32,  //搜索框高度
      decoration: BoxDecoration(
        color: const Color(0xFFF2F2F2),  // 搜索框背景色-灰色
        borderRadius: BorderRadius.circular(16), // 设置搜索框圆角
      ),
      child: Row(
        children: [
          const SizedBox(
            width: 32,
            height: 24,
            child: Icon(Icons.search, size: 16, color: Color(0xFF999999)),  //搜索框图标
          ),
          TextField(
            readOnly: true,  //只读不可编辑,点击搜索框直接跳转搜索页
            decoration: const InputDecoration(
              hintText: '人工智能',  //搜索提示词
              hintStyle: TextStyle(fontSize: 12, color: Color(0xFF999999)),  //搜索框文字样式
            ),
            onTap: () {
              Navigator.of(context).push(_createRoute());  //点击搜索框,路由到搜索页(动画效果: 右侧滑出)
            }, //onTap
          ),
        ],
      ),
    );
  }

  //页面切换动画特效-右侧滑出
  Route _createRoute() {
    return PageRouteBuilder(
      pageBuilder: (context, animation, secondaryAnimation) => SearchDetail(),  //右侧弹出搜索详情页
      transitionsBuilder: (context, animation, secondaryAnimation, child) {
        var begin = const Offset(1.0, 0.0);  //页面进入的起点坐标
        var end = Offset.zero;    //页面进入的终点坐标
        const curve = Curves.ease; 
        var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve)); //
        return SlideTransition(
          position: animation.drive(tween), 
          child: child,
        );
      },
    );
  }

}

2. 搜索详情页 searchDetail.dart  

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

/*搜索详情页*/
class SearchDetail extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          backgroundColor: const Color(0xFFFBFBFB),  // 搜索框背景色
          automaticallyImplyLeading: false,  //隐藏左侧默认返回按钮
          title: Container(
            height: 32,
            decoration: BoxDecoration(
              color: const Color(0xFFF2F2F2),  // 搜索框背景色
              borderRadius: BorderRadius.circular(16), // 设置搜索框圆角
            ),
            child: Row(
              children: const [
                SizedBox(
                  width: 32,
                  height: 24,
                  child: Icon(Icons.search, size: 16, color: Color(0xFF999999)),  //搜索框图标
                ),
                TextField(
                  decoration: InputDecoration(
                    hintText: '人工智能',
                    hintStyle: TextStyle(fontSize: 12, color: Color(0xFF999999)),  //搜索框文字
                  ),
                ),
              ],
            ),
          ),
          actions: [
            Padding(
              padding: const EdgeInsets.fromLTRB(0, 8, 6, 0), //间距左,上,右,下
              child: cancelText(context),  // 取消,回退上一页
            )
          ],
      ),
      body: Column(
            crossAxisAlignment:  CrossAxisAlignment.start, //文字左对齐
            children:  [
              const Padding(
                padding: EdgeInsets.fromLTRB(10, 10, 0, 10),
                child: Text('搜索历史', style: TextStyle(fontWeight: FontWeight.w600)) //字体加粗
              ),
              Wrap(
                  spacing: 10, // 搜索关键词的间距
                  runSpacing: 10, // 搜索关键词的间距
                  children: KeyWords()  // 关键词列表
              )
            ]
      )
    );
  }

  // 取消-富文本点击方式实现
  Text cancelText(BuildContext context){
    return Text.rich(
        TextSpan(
            text: '取消',
            style: const TextStyle(height: 2, color: Colors.blue, fontSize: 14, fontWeight: FontWeight.w600),
            recognizer: TapGestureRecognizer()
              ..onTap = () {
                Navigator.pop(context);
              },
        )
    );
  }

  // 关键词列表
  List KeyWords() => List.generate(9, (index) {
     return Container(
         padding: const EdgeInsets.all(6),
         decoration: BoxDecoration(
           color: const Color(0xFFF2F2F2),  // 搜索框背景色
           borderRadius: BorderRadius.circular(4), // 设置搜索框圆角
         ),
         child: Text("关键词 $index",
           style: const TextStyle(color: Color(0xFF999999), fontSize: 14, height: 1, fontWeight: FontWeight.w300)
         )
     );
  });

}

3. 在首页index.dart中,使用搜索框 SearchAppBar

import 'package:flutter/material.dart';
import 'package:flutter_play/recommend.dart';
import 'package:flutter_play/search.dart';

/*首页
* 顶部搜索框 SearchAppBar
* 顶部导航栏 TabBar
* 导航栏嵌入推荐页:RecommendPage 是图文列表 ListView
* */
class IndexPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        appBar: AppBar(
          backgroundColor: const Color(0xFFFBFBFB), //顶部背景色
          title: SearchAppBar(),  // 顶部搜素框(自定义组件)
          bottom: const TabBar(
            labelColor: Colors.blue,  //选中时颜色
            unselectedLabelColor: Colors.black26, //未选中时颜色
            tabs: [
              Tab(text: '推荐'),
              Tab(text: '资讯'),
              Tab(text: '科技'),
            ],
          ),
        ),
        body: TabBarView(
          children: [
            RecommendPage(),  // 推荐页
            const Icon(Icons.directions_transit),
            const Icon(Icons.directions_bike),
          ],
        ),
      ),
    );
  }
}

工程中的底部导航+顶部导航+图文列表完整代码,在系列文章第四篇

Flutter系列(四)底部导航+顶部导航+图文列表完整代码_摸金青年v的博客-CSDN博客

END...

 

你可能感兴趣的:(flutter,flutter)