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('我的'))
              ],
            ),
          ),
        );
      }
    }

  • 相关阅读:
    Eclipse 导入项目乱码问题(中文乱码)
    sql中视图视图的作用
    Java基础-super关键字与this关键字
    Android LayoutInflater.inflate(int resource, ViewGroup root, boolean attachToRoot)的参数理解
    Android View和ViewGroup
    工厂方法模式(java 设计模式)
    设计模式(java) 单例模式 单例类
    eclipse乱码解决方法
    No resource found that matches the given name 'Theme.AppCompat.Light 的完美解决方案
    【转】使用 Eclipse 调试 Java 程序的 10 个技巧
  • 原文地址:https://www.cnblogs.com/yiweiyihang/p/11449405.html
Copyright © 2011-2022 走看看