zoukankan      html  css  js  c++  java
  • 16 Flutter仿京东商城项目 跳转到搜索页面实现搜索功能 以及搜索筛选

    ProductList.dart

    import 'package:flutter/material.dart';
    import '../services/ScreenAdaper.dart';
    import '../config/Config.dart';
    import 'package:dio/dio.dart';
    import '../model/ProductModel.dart';
    import '../widget/LoadingWidget.dart';
    
    class ProductListPage extends StatefulWidget {
      Map arguments;
      ProductListPage({Key key, this.arguments}) : super(key: key);
    
      _ProductListPageState createState() => _ProductListPageState();
    }
    
    class _ProductListPageState extends State<ProductListPage> {
      //通过事件打开侧边栏,需要全局声明一下:
      final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
      //配置下拉加载更多:
      ScrollController _scrollController = ScrollController();
      //分页:
      int _page = 1;
      //每一页有多少条数据:
      int _pageSize = 10;
      //分页:
      List _productList = [];
      //排序:
      String _sort = "";
      //解决重复请求的问题:
      bool flag = true;
    
      //是否有数据:
      bool _hasMore = true;
    
      //是否有搜索的数据:
      bool _hasData = true;
      // 一级导航数据
      /*
      价格升序:sort=price_1
      价格降序:sort=price_-1
      销量升序:sort=salecount_1
      销量降序:sort=salecount_-1
       */
      List _subHeaderList = [
        {"id": 1, "title": "综合", "fileds": 'all', "sort": -1},
        {"id": 2, "title": "销量", "fileds": 'salecount', "sort": -1},
        {"id": 3, "title": "价格", "fileds": 'price', "sort": -1},
        {"id": 4, "title": "筛选"},
      ];
      int _selectHeaderId = 1;
    
      //配置search搜索框的值:
      var _initKeywordsController = new TextEditingController();
    
      //cid
      var _cid;
      var _keywords;
    
      //初始化的时候获取的生命周期函数:
      @override
      void initState() {
        super.initState();
        this._cid = widget.arguments["cid"];
        this._keywords = widget.arguments["keywords"];
    
        //给search框框赋值:
        this._initKeywordsController.text = this._keywords;
        widget.arguments['keywords'] == null
            ? this._initKeywordsController.text = ""
            : this._initKeywordsController.text = widget.arguments['keywords'];
    
        _getProductListData();
        //监听滚动条滚动事件:
        _scrollController.addListener(() {
          // _scrollController.position.pixels //获取滚动条滚动高度
          // _scrollController.position.maxScrollExtent //获取页面滚动高度:
          if (_scrollController.position.pixels >
              _scrollController.position.maxScrollExtent - 20) {
            if (this.flag && this._hasMore) {
              _getProductListData();
            }
          }
        });
      }
    
      //获取商品列表的数据:
      _getProductListData() async {
        setState(() {
          this.flag = false;
        });
        var api;
        print(widget.arguments['keywords']);
        if (this._keywords == null) {
          api =
              '${Config.domain}api/plist?cid=${this._cid}&page=${_page}&sort=${this._sort}&pageSize=${_pageSize}';
        } else {
          api =
              '${Config.domain}api/plist?search=${this._keywords}&page=${_page}&sort=${this._sort}&pageSize=${_pageSize}';
        }
    
        var result = await Dio().get(api);
        var productList = ProductModel.fromJson(result.data);
        print(productList.result);
    
        if (productList.result.length < this._pageSize) {
          setState(() {
            this._productList.addAll(productList.result);
            this._hasMore = false;
            this.flag = true;
            // this._productList = productList.result;
          });
        } else {
          setState(() {
            this._productList.addAll(productList.result);
            this._page++;
            this.flag = true;
            // this._productList = productList.result;
          });
        }
    
        //判断是否有搜索的数据:
        if (productList.result.length == 0) {
          setState(() {
            this._hasData = false;
          });
        } else {
          setState(() {
            this._hasData = true;
          });
        }
      }
    
      //显示加载中的圈圈:
      Widget _showMore(index) {
        if (this._hasMore) {
          return (index == this._productList.length - 1)
              ? LoadingWidget()
              : Text('');
        } else {
          return (index == this._productList.length - 1)
              ? Text("---暂无其他数据了--")
              : Text('');
        }
      }
    
      //商品列表:
      Widget _productListWidget() {
        if (this._productList.length > 0) {
          return Container(
            padding: EdgeInsets.all(10),
            margin: EdgeInsets.only(top: ScreenAdaper.height(80)),
            child: ListView.builder(
              controller: _scrollController,
              itemBuilder: (context, index) {
                //处理图片:
                String pic = this._productList[index].pic;
                pic = Config.domain + pic.replaceAll('\', '/');
                //获得每一个元素:
                return Column(
                  children: <Widget>[
                    Row(
                      children: <Widget>[
                        Container(
                           ScreenAdaper.width(180),
                          height: ScreenAdaper.height(180),
                          child: Image.network("${pic}", fit: BoxFit.cover),
                        ),
                        Expanded(
                          flex: 1,
                          child: Container(
                            height: ScreenAdaper.height(180),
                            margin: EdgeInsets.only(left: 10),
                            // color: Colors.red,
                            child: Column(
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: <Widget>[
                                Text(
                                  "${this._productList[index].title}",
                                  maxLines: 2,
                                  overflow: TextOverflow.ellipsis,
                                ),
                                Row(
                                  children: <Widget>[
                                    Container(
                                      height: ScreenAdaper.height(36),
                                      margin: EdgeInsets.only(right: 10),
                                      padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
                                      //注意:如果Container里面加上decoration属性,这个时候color属性必须放到BoxDecoration
                                      decoration: BoxDecoration(
                                        borderRadius: BorderRadius.circular(10),
                                        // color:Color.fromRGBO(230, 230, 230, 0.9)
                                      ),
                                      child: Text('4G'),
                                    ),
                                    Container(
                                      height: ScreenAdaper.height(36),
                                      margin: EdgeInsets.only(right: 10),
                                      padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
                                      //注意:如果Container里面加上decoration属性,这个时候color属性必须放到BoxDecoration
                                      decoration: BoxDecoration(
                                        borderRadius: BorderRadius.circular(10),
                                        // color:Color.fromRGBO(230, 230, 230, 0.3)
                                      ),
                                      child: Text('16G'),
                                    )
                                  ],
                                ),
                                Text("¥ ${this._productList[index].price}",
                                    style:
                                        TextStyle(color: Colors.red, fontSize: 16))
                              ],
                            ),
                          ),
                        )
                      ],
                    ),
                    Divider(
                      height: 20,
                    ),
                    this._showMore(index)
                  ],
                );
              },
              itemCount: this._productList.length,
            ),
          );
        } else {
          return LoadingWidget();
        }
      }
    
      //导航改变的时候触发:
      _subHeaderChange(id) {
        if (id == 4) {
          _scaffoldKey.currentState.openEndDrawer();
        }
        setState(() {
          this._selectHeaderId = id;
          this._sort =
              "${this._subHeaderList[id - 1]['fileds']}_${this._subHeaderList[id - 1]['sort']}";
    
          //重置分页:
          this._page = 1;
          //重置数据:
          this._productList = [];
    
          this._subHeaderList[id - 1]['sort'] =
              this._subHeaderList[id - 1]['sort'] * -1;
    
          //回到顶部:
          _scrollController.jumpTo(0);
    
          //重置_hasMore
          this._hasMore = true;
    
          //重新请求数据:
          this._getProductListData();
        });
      }
    
      //显示Header icon
      Widget _showIcon(id) {
        if (id == 2 || id == 3) {
          if (this._subHeaderList[id - 1]['sort'] == 1) {
            return Icon(Icons.arrow_drop_down);
          }
          return Icon(Icons.arrow_drop_up);
        }
        return Text('');
      }
    
      //筛选导航:
      Widget _subHeaderWidget() {
        return Positioned(
          top: 0,
          height: ScreenAdaper.height(80),
           ScreenAdaper.width(750),
          child: Container(
            height: ScreenAdaper.height(80),
             ScreenAdaper.width(750),
            // color: Colors.red,
            decoration: BoxDecoration(
                border: Border(
                    bottom: BorderSide(
                         1, color: Color.fromRGBO(233, 233, 233, 0.9)))),
            child: Row(
                children: this._subHeaderList.map((value) {
              return Expanded(
                flex: 1,
                child: InkWell(
                  child: Padding(
                    padding: EdgeInsets.fromLTRB(
                        0, ScreenAdaper.height(20), 0, ScreenAdaper.height(20)),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Text(
                          "${value['title']}",
                          textAlign: TextAlign.center,
                          style: TextStyle(
                              color: (this._selectHeaderId == value["id"])
                                  ? Colors.red
                                  : Colors.black),
                        ),
                        _showIcon(value['id'])
                      ],
                    ),
                  ),
                  onTap: () {
                    _subHeaderChange(value["id"]);
                  },
                ),
              );
            }).toList()),
          ),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        ScreenAdaper.init(context);
        return Scaffold(
          key: _scaffoldKey,
          appBar: AppBar(
            title: Container(
              child: TextField(
                controller: this._initKeywordsController,
                autofocus: false,
                decoration: InputDecoration(
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(30),
                        borderSide: BorderSide.none)),
                onChanged: (value) {
                  setState(() {
                    this._keywords = value;
                  });
                },
              ),
              height: ScreenAdaper.height(68),
              decoration: BoxDecoration(color: Color.fromRGBO(233, 233, 233, 0.8)),
            ),
            actions: <Widget>[
              InkWell(
                child: Container(
                  height: ScreenAdaper.height(68),
                   ScreenAdaper.width(80),
                  child: Row(
                    children: <Widget>[Text('搜索')],
                  ),
                ),
                onTap: () {
                  this._subHeaderChange(1);
                },
              )
            ],
          ),
          endDrawer: Drawer(
            child: Container(
              child: Text('实现筛选功能'),
            ),
          ),
          // body: Text("${widget.arguments}"),
          body:_hasData?Stack(
            children: <Widget>[_productListWidget(), _subHeaderWidget()],
          ):Center(
            child: Text('没有您要浏览的数据')
          ),
        );
      }
    }

    Search.dart

    import 'package:flutter/material.dart';
    import 'package:flutter_jdshop/services/ScreenAdaper.dart';
    
    class SearchPage extends StatefulWidget {
      SearchPage({Key key}) : super(key: key);
    
      _SearchPageState createState() => _SearchPageState();
    }
    
    class _SearchPageState extends State<SearchPage> {
      var _keywords;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Container(
                child: TextField(
                  autofocus: true,
                  decoration: InputDecoration(
                      border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(30),
                          borderSide: BorderSide.none)),
                          onChanged: (value){
                            this._keywords=value;
                          },
                ),
                height: ScreenAdaper.height(68),
                decoration: BoxDecoration(
                    color: Color.fromRGBO(233, 233, 233, 0.8),
                    borderRadius: BorderRadius.circular(30)),
              ),
              actions: <Widget>[
                InkWell(
                  child: Container(
                    height: ScreenAdaper.height(68),
                     ScreenAdaper.width(80),
                    child: Row(
                      children: <Widget>[Text('搜索')],
                    ),
                  ),
                  onTap: () {
                    print(896);
                    Navigator.pushReplacementNamed(context,'/productList',arguments: {
                      "keywords":this._keywords
                    });
                  },
                )
              ],
            ),
            
            body: Container(
              padding: EdgeInsets.all(10),
              child: ListView(
                children: <Widget>[
                  Container(
                    child: Text('热搜', style: Theme.of(context).textTheme.title),
                  ),
                  Divider(),
                  Wrap(
                    children: <Widget>[
                      Container(
                        padding: EdgeInsets.all(10),
                        margin: EdgeInsets.all(10),
                        decoration: BoxDecoration(
                            color: Color.fromRGBO(233, 233, 233, 0.9),
                            borderRadius: BorderRadius.circular(10)),
                        child: Text('女装'),
                      ),
                      Container(
                        padding: EdgeInsets.all(10),
                        margin: EdgeInsets.all(10),
                        decoration: BoxDecoration(
                            color: Color.fromRGBO(233, 233, 233, 0.9),
                            borderRadius: BorderRadius.circular(10)),
                        child: Text('女装'),
                      ),
                      Container(
                        padding: EdgeInsets.all(10),
                        margin: EdgeInsets.all(10),
                        decoration: BoxDecoration(
                            color: Color.fromRGBO(233, 233, 233, 0.9),
                            borderRadius: BorderRadius.circular(10)),
                        child: Text('女装'),
                      ),
                      Container(
                        padding: EdgeInsets.all(10),
                        margin: EdgeInsets.all(10),
                        decoration: BoxDecoration(
                            color: Color.fromRGBO(233, 233, 233, 0.9),
                            borderRadius: BorderRadius.circular(10)),
                        child: Text('女装'),
                      ),
                      Container(
                        padding: EdgeInsets.all(10),
                        margin: EdgeInsets.all(10),
                        decoration: BoxDecoration(
                            color: Color.fromRGBO(233, 233, 233, 0.9),
                            borderRadius: BorderRadius.circular(10)),
                        child: Text('女装'),
                      )
                    ],
                  ),
                  SizedBox(height: 10),
                  Container(
                    child: Text('历史记录', style: Theme.of(context).textTheme.title),
                  ),
                  Divider(),
                  Column(
                    children: <Widget>[
                      ListTile(
                        title: Text('女装'),
                      ),
                      Divider(),
                      ListTile(
                        title: Text('女装'),
                      ),
                      Divider(),
                      ListTile(
                        title: Text('女装'),
                      ),
                      Divider(),
                      ListTile(
                        title: Text('女装'),
                      ),
                      Divider(),
                    ],
                  ),
                  SizedBox(height: 100),
                  InkWell(
                    onTap: (){
                      
                    },
                    child: Container(
                       ScreenAdaper.width(400),
                      height: ScreenAdaper.height(64),
                      decoration: BoxDecoration(
                          border: Border.all(color: Colors.black54,  1)),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[Icon(Icons.delete), Text('清空历史记录')],
                      ),
                    ),
                  )
                ],
              ),
            ));
      }
    }

    router.dart

    import 'package:flutter/material.dart';
    import '../pages/tabs/Tabs.dart';
    import '../pages/Search.dart';
    import '../pages/ProductList.dart';
    //配置路由的地方:
    final routes = {
      '/': (context) => Tabs(),
      '/search': (context) => SearchPage(),
      '/productList': (context,{arguments}) => ProductListPage(arguments:arguments),
    };
    //固定写法:
    var onGenerateRoute = (RouteSettings settings) {
      // 统一处理
      final String name = settings.name;
      final Function pageContentBuilder = routes[name];
      if (pageContentBuilder != null) {
        if (settings.arguments != null) {
          final Route route = MaterialPageRoute(
              builder: (context) =>
                  pageContentBuilder(context, arguments: settings.arguments));
          return route;
        } else {
          final Route route =
              MaterialPageRoute(builder: (context) => pageContentBuilder(context));
          return route;
        }
      }
    };

    Tabs.dart

    import 'package:flutter/material.dart';
    import '../../services/ScreenAdaper.dart';
    
    import 'Home.dart';
    import 'Cart.dart';
    import 'Category.dart';
    import 'User.dart';
    
    class Tabs extends StatefulWidget {
      Tabs({Key key}) : super(key: key);
    
      _TabsState createState() => _TabsState();
    }
    
    class _TabsState extends State<Tabs> {
      int _currentIndex = 1;
      PageController _pageController;
      void initState() {
        super.initState();
        this._pageController = new PageController(initialPage: this._currentIndex);
      }
    
      List<Widget> _pageList = [HomePage(), CategoryPage(), CartPage(), UserPage()];
      @override
      Widget build(BuildContext context) {
        ScreenAdaper.init(context);
    
        return Container(
          child: Scaffold(
            appBar:_currentIndex!=3?AppBar(
              leading: IconButton(
                icon:
                    Icon(Icons.center_focus_weak, size: 28, color: Colors.black87),
                onPressed: null,
              ),
              title:InkWell(
                child: Container(
                  height: ScreenAdaper.height(56),
                  decoration: BoxDecoration(
                    color: Color.fromRGBO(233,233,233, 0.8),
                    borderRadius: BorderRadius.circular(30)
                  ),
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: <Widget>[
                      Icon(Icons.search),
                      Text('笔记本',style:TextStyle(
                        fontSize: ScreenAdaper.size(28)
                      ))
                    ],
                  ),
                ),
                onTap: (){
                  Navigator.pushNamed(context,'/search');
                },
              ),
              actions: <Widget>[
                IconButton(
                  icon: Icon(Icons.message,
                      size: 28, color: Colors.black87),
                  onPressed: null,
                )
              ],
            ):AppBar(
              title: Text('用户中心'),
            ),
            //页面状态保持第一种方法:
            //保持所有的页面状态,使用indexedStack
            // body:IndexedStack(
            //   index: this._currentIndex,
            //   children:_pageList
            // ),
            //保持部分页面的状态:
            //
    
            body: PageView(
              //修改的部分:
              controller: this._pageController,
              children: this._pageList,
              onPageChanged:(index){
                setState(() {
                 this._currentIndex=index; 
                });
              },
              // physics: NeverScrollableScrollPhysics(), //禁止pageView滑动
            ),
            bottomNavigationBar: BottomNavigationBar(
              currentIndex: this._currentIndex,
              onTap: (index) {
                this.setState(() {
                  this._currentIndex = index;
                  this._pageController.jumpToPage(this._currentIndex);
                });
              },
              type: BottomNavigationBarType.fixed,
              fixedColor: Colors.red,
              items: [
                BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('首页')),
                BottomNavigationBarItem(
                    icon: Icon(Icons.category), title: Text('分类')),
                BottomNavigationBarItem(
                    icon: Icon(Icons.shopping_cart), title: Text('购物车')),
                BottomNavigationBarItem(icon: Icon(Icons.people), title: Text('我的'))
              ],
            ),
          ),
        );
      }
    }

  • 相关阅读:
    Tomcat工作原理
    刚刚大学毕业,自己搭网站遇到的问题 一:tomcat中同时部署两个项目的问题
    maven常用命令
    修改redis端口号
    assert的基本用法
    Linux下mysql新建账号及权限设置
    tomcat设置http自动跳转为https访问
    spring mvc 实现文件上传下载
    svn: E155004 is already locked 解决方案
    数据库连接池druid
  • 原文地址:https://www.cnblogs.com/yiweiyihang/p/11449405.html
Copyright © 2011-2022 走看看