美文网首页
Flower_gift 简单的Flutter实战app(四)

Flower_gift 简单的Flutter实战app(四)

作者: 浮桥小麦 | 来源:发表于2019-08-07 17:23 被阅读0次
    0001.jpg
    项目git地址:flower_gift
    tabBar-分类界面:

    效果:


    11324.gif
    头部搜索栏的搭建:
    //顶部搜索框;
      Widget _buildSearchBar(){
        return Container(
                  margin: EdgeInsets.symmetric(horizontal: 10.0,vertical: 8.0),
                  decoration: BoxDecoration(
                     color: Colors.black12,
                     borderRadius: BorderRadius.all(Radius.circular(22.0)),
                  ),
                  child: Row(
                     crossAxisAlignment: CrossAxisAlignment.start,
                     children: <Widget>[
                        Expanded(
                          flex: 1,
                          child: Container(
                            padding: EdgeInsets.symmetric(horizontal: 8.0),
                            child: TextFormField(
                                decoration: InputDecoration(
                                    border: InputBorder.none,
                                    hintText: "请输入关键字",
                                    hintStyle: TextStyle(
                                      color: Colors.black
                                    ),
                                    icon: Icon(Icons.search,color:Colors.black)
                                ),
                              ),
                          ) 
                          
                        ),
                        
                     ],
                  ),
        );
      }
    
    

    使用:

     return Scaffold(
            appBar: AppBar(
               backgroundColor: Colors.white,
               title: _buildSearchBar()
            ),
            body: ...
    

    这里就是说,开始我以为这个Scaffold的title属性只能是这个Text组件控制这个导航栏title.原来这个也是完全可以自定义的。

    body布局部分:
     body: FutureBuilder(
                future: _getCategoryPage(context),
                builder: (context,snapshot){
                  if(snapshot.hasData){
                    return Container(
                        color: Colors.white,
                        child: Row(
                            children: <Widget>[
                              Expanded(
                                flex: 2,
                                child: CategoryLeftNav()
                              ),
                              Expanded(
                                flex: 5,
                                child: CategoryRightCategory()
                              )
                            ],
                          ),  
                    );  
                  }else{
                    return Center(
                      child: Text("暂无数据"),
                    );
                  }
                },
            ),
    
    
     
      //网络请求
       Future _getCategoryPage(BuildContext context) async{
         await Provide.value<CategoryPageProvide>(context).getCategoryPageData();
         return "完成加载....";
      }
    

    整体布局我把这个作为左右两部分吧,所以这个就直接用Row,然后里面嵌套这个Expanded组件,用flex来控制所占宽度比。

    左边导航栏
    import 'package:flutter/material.dart';
    import 'package:flutter_screenutil/flutter_screenutil.dart';
    import '../../model/categoryPage_model_entity.dart';
    import 'package:provide/provide.dart';
    import '../../provide/categoryPage_provide.dart';
    
    class CategoryLeftNav extends StatelessWidget {
      
      @override
      Widget build(BuildContext context) {
        return Provide<CategoryPageProvide>(
            builder: (context,child,val){
              var categoryPageModelEntity = val.categoryModelEntity;
              return  Container(
                decoration: BoxDecoration(
                  border: Border(
                    right: BorderSide(
                        color: Colors.black12,
                        width: 1.0,
                        style: BorderStyle.solid
                    )
                  )
                ),
                child: ListView.builder(
                  itemCount: categoryPageModelEntity.categorys.length,
                  itemBuilder:(context,index){
                      return Container(
                          color: Colors.white,
                          child: InkWell(
                              //设置点击闪烁那一下的文字颜色
                              splashColor: Colors.redAccent.withOpacity(0.5),
                              onTap: (){
                                 Provide.value<CategoryPageProvide>(context).switchCategory(index);
                              },
                              child: Column(
                                children: <Widget>[
                                  SizedBox(height: 15.0,),
                                    Container(
                                      alignment: Alignment.center,
                                      padding: const EdgeInsets.symmetric(vertical: 4.0),
                                      decoration: (Provide.value<CategoryPageProvide>(context).currentIndex == index) ?  BoxDecoration(
                                          border: Border(
                                              left: BorderSide(
                                                color: Colors.orange,
                                                width: 3.0,
                                                style: BorderStyle.solid
                                              )
                                          )
                                        ) : null,
                                        child: Text(
                                            categoryPageModelEntity.categorys[index].type,
                                            style: TextStyle(fontSize: 18.0),
                                          ),
                                  ),
                                  SizedBox(height: 15.0,),
                                  
                                ],
                              ) 
                            
                              
                          )
                          
                      );
                  },
                ),
                
            );
          }
       );
      }
    }
    

    这个布局就比较简单的,主要就是利用Provide来管理了当前点击的分类项,然后左边的指示条我就直接用的这个边框来做的。

    右边分类布局部分:
    import 'package:flutter/material.dart';
    import 'package:flutter_screenutil/flutter_screenutil.dart';
    import '../../model/categoryPage_model_entity.dart';
    import 'package:provide/provide.dart';
    import '../../provide/categoryPage_provide.dart';
    
    class CategoryRightCategory extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Provide<CategoryPageProvide>(
            builder: (context,child,val){
               var currentIndex = Provide.value<CategoryPageProvide>(context).currentIndex;
               var categoryModelCategory = val.categoryModelEntity.categorys[currentIndex];
               var categoryBanners = categoryModelCategory.categoryBanner;
               var areasItem = categoryModelCategory.areas[0];//默认只做第一排的商品分类详情了
               var head = areasItem.head;//看看是否有头部标题栏
               var contents = areasItem.contents;
               return Container(
                  child:ListView(
                    
                       children: <Widget>[
                          _buildTopBanner(context, categoryModelCategory.banner),
                        (categoryBanners != null) ? _buildCategoryBanner(context, categoryBanners) : SizedBox(height: 1.0,),
                        (head != null) ? _buildTitle(head) : SizedBox(height: 1.0,),
                        Divider(),
                        _buildCategoryShow(context, contents),
                       ],
                     
                  )
                 
               );
            },
        );
        
      }
    
      //顶部banner
      Widget _buildTopBanner(BuildContext context,CategoryModelCategorysBanner banner){
          return Padding(
             padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
             child: Container(
                height: MediaQuery.of(context).size.height / 7,
                child: Image.network(banner.imageUrl,fit:BoxFit.fill,),
             ), 
          );
       }
    
       //分类banner -- 需要判断显示否
       Widget _buildCategoryBanner(BuildContext context,List<CategoryModelCategorysCategorybanner> categoryBanners){
          return Padding(
            padding: const EdgeInsets.symmetric(horizontal: 10.0),
            child: Container(
               height: MediaQuery.of(context).size.height / 7,
               child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: _categoryBanners(context, categoryBanners)
               ),
            ),
          );
       }
       List<Widget> _categoryBanners(BuildContext context, List<CategoryModelCategorysCategorybanner> categoryBanners){
           List<Widget> list = new List();
            for(var i = 0; i < categoryBanners.length; i++){
              list.add(
                  Container(
                    width: (MediaQuery.of(context).size.width / 7 * 5  - 40.0)/3,
                    child: Image.network(categoryBanners[i].imageUrl,fit:BoxFit.fill),
                  )
                  
              ); 
         }
         return list;
       }
     
       //标题栏
       Widget _buildTitle(dynamic head){
          return Padding(
            padding: const EdgeInsets.symmetric(horizontal: 10.0,vertical: 5.0),
            child: Row(
               mainAxisAlignment: MainAxisAlignment.spaceBetween,
               children: <Widget>[
                  Text(head["Title"]),
                  Text(head["UrlDesc"])
               ],
            ),
          );
    
       }
      //分类展示
       Widget _buildCategoryShow(BuildContext context,List<CategoryModelCategorysAreasContent> contents){
         return Padding(
                padding: const EdgeInsets.symmetric(horizontal: 10.0),
                child: Wrap(
                   alignment: WrapAlignment.spaceBetween,
                   children: _categoryShow(context, contents)
                ),
            
         );
         
       }
       //分类展示遍历
       List<Widget> _categoryShow(BuildContext context,List<CategoryModelCategorysAreasContent> contents){
           List<Widget> list = new List();
            for(var i = 0; i < contents.length; i++){
              list.add(
                  Container(
                    //  height:  MediaQuery.of(context).size.height / 7 + 20.0,
                     width:  (MediaQuery.of(context).size.width / 7 * 5 - 30.0)/3,
                     child: Column(
                         mainAxisAlignment: MainAxisAlignment.center,
                         children: <Widget>[
                            SizedBox(height:25.0),
                           (contents[i].text != null) ? CircleAvatar(
                               child: Image.network(contents[i].imageUrl),
                            ) : Padding(
                               padding: const EdgeInsets.symmetric(horizontal: 5.0),
                               child:Image.network(contents[i].imageUrl),
                            ),
                            SizedBox(height: 15.0,),
                            (contents[i].text != null) ? Text(
                              contents[i].text
                            ) : SizedBox(height: 1.0,),
                             
                         ],
    
                     ),
                  )
                  
              ); 
         }
         return list;
       }
    }
    

    这边布局也是比较简单的,主要就是考虑这个数据是否为null,来确定显示哪一部分。

    结尾:这个页面的分类项点击的逻辑还没做,这个路由的配置就利用首页来做就好了,具体的分类列表项布局还算简单,就是其中的逻辑比较杂。其次这个搜索逻辑也没有做,看后面有时间补上。商品详情页

    相关文章

      网友评论

          本文标题:Flower_gift 简单的Flutter实战app(四)

          本文链接:https://www.haomeiwen.com/subject/ukradctx.html