美文网首页
小羊秘籍总结重点

小羊秘籍总结重点

作者: woniu | 来源:发表于2021-08-11 19:05 被阅读0次

    一、首页

    1、布局:Flexible/Expended
    • Flexible组件可以使Row、Column、Flex等子组件在主轴方向有填充可用空间的能力,但是不强制子组件填充可用空间。
    • Expanded组件可以使Row、Column、Flex等子组件在其主轴方向上展开并填充可用空间,是强制子组件填充可用空间。
    2、富文本
        new Text.rich(
                        TextSpan(children: [
                          WidgetSpan(
                            // child: ProductGetLogic.platformIcon(widget?.productItem?.mall_icon_url),
                            child: Image.network(widget?.productItem?.mall_icon_url,width: 16,height: 16,),
                          ),
    
                          TextSpan(
                            text: " ${productItem.itemTitle}",
                            style: TextStyle(
                              fontSize: 13,
                              color: Color(0xff000000),
                              fontWeight: FontWeight.w500,
                            ),
                          )
                        ]),
                        overflow: TextOverflow.ellipsis,
                        maxLines: 2,
                      ),
    
    3、Offstage、Visibility隐藏/可见
    • Offstage
    offstage  子组件是否可见,默认true(隐藏)
    child     子组件
    
    Offstage(
      offstage:
          widget.model?.orderStatus == 1,
      child: Container(),
    ),
    
    • Visibility
    child     子组件
    visible   子组件是否可见,默认true(可见)
    replacement 不可见时显示的组件(当maintainState = false)
    maintainAnimation 不可见时,是否维持子组件中的动画 
    maintainSize 不可见时是否留有空间(设置为true) 
    maintainSemantics  不可见时是否维持它的语义
    maintainInteractivity 不可见时是否具有交互性 
    
    Visibility(
      visible: true,
      child: Container(),
    ),
    
    4、CustomScrollView、Visibility&纵向滑动中的横向布局
    4.1、CustomScrollView:区头、表的联动,用到的属性控件
    • SliverAppBar (相当于区头)
    • SliverToBoxAdapter (表,里面可以设置多种控件,比如column、SliverList、Visibility)但是不能直接设置ListView,会不显示。
    4.2、Visibility:根据自身的visible属性,true显示,false直接宽高为0,后面的控件直接填充控件的空间。
    4.3、CustomScrollView纵向滑动中的横向布局:

    需SliverToBoxAdapter中添加Container,Container中设置ListView,这样就可以了。

    SliverToBoxAdapter(
                          // visible: true,
                          child: Visibility(
                            visible: false,
                            child: Container(
                              height: 100.0,
                              child: ListView.builder(
                                scrollDirection: Axis.horizontal,
                                itemCount: 10,
                                itemBuilder: (context, index) {
                                  return Container(
                                    width: 200.0,
                                    child: Card(
                                      child: Text('data'),
                                    ),
                                  );
                                },
                              ),
                            ),
                          ),
                        ),
    
    5、渐变色

    1、LinearGradient 线性渐变
    2、RadialGradient:放射状渐变
    3、SweepGradient:扇形渐变

    Container(
                  height: 28,
                  width: 58,
                  alignment: Alignment.center,
                  child: Text(
                    '搜索',
                    style: TextStyle(
                      fontFamily: 'Regular',
                      color: Color(0xffffffff),
                      fontSize: 13,
                    ),
                  ),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(14),
                    gradient: LinearGradient(
                        colors: [Color(0xffff353e), Color(0xfffd5537)]),
                  ),
                ),
    
    6、extends 、 with 、implements三者的区别
    • 继承(关键字 extends);
    • 混入 mixins (关键字 with);
    • 实现(关键字 implements)
      特性:这三种关系可以同时存在,但是有前后顺序:extends > with > implements
      1、extends 表示继承。Dart 中的继承和 Java 一样。

    使用关键字 extends 继承一个类
    子类继承父类可见的属性和方法,不会继承父类的构造方法
    子类可以覆写父类的方法,方法上要加 @override
    子类可以调用父类的方法,用 super 关键字
    单继承,多态性

    2、with 表示 mixins (混入),就是在类中混入其他功能。使用 mixins 可以实现类似于多继承的功能。mixins 和接口完全不一样,是一个全新的特性。

    mixins 只能继承 Object
    mixins 没有构造函数
    mixins 和接口实现一样可以在 with 后面使用多个 mixins,用逗号隔开

    3、implements 表示示接口实现。Dart 不使用 interface 关键字,但是 Dart 中每个类都是一个隐性的接口,这个隐性的接口里面包含了类的所有成员变量和方法。
    如果一个类被当做接口来用,那么实现这个接口的类必须实现接口所有的成员变量和方法。

    二、界面滑动TabBar

    1、TabBar属性
    属性 说明
    tabs 一系列标签控件
    controller 标签选择变化控制器
    isScrollable 是否可滚动,默认false
    indicatorColor 指示器颜色
    indicatorWeight 指示器粗细
    indicator 指示器,可自定义形状等样式
    indicatorSize 指示器长短,tab:和tab一样长,label:和标签label 一样长
    labelColor 标签颜色
    labelStyle 标签样式
    labelPadding 标签padding
    unselectedLabelColor 未选中标签颜色
    unselectedLabelStyle 未选中标签样式
    2、TabBarView属性

    TabBar 一般情况下和TabBarView一起使用,TabBarView用于选择不同的TabBar,TabBarView显示对应的View

    属性 说明
    children 一系列子控件,如果和TabBar一起使用注意和TabBar的长度一样
    controller 控制器,如果和TabBar一起使用注意和TabBar使用同一个controller
    1311659522856_.pic.jpg
    import 'package:flutter/material.dart';
    
    class TabBarDemo extends StatefulWidget {
      @override
      State<StatefulWidget> createState() => _TabBar();
    }
    
    class _TabBar extends State<TabBarDemo> {
      final List<String> _tabValues = [
        '语文',
        '英语',
        '化学',
        '物理',
        '数学',
        '生物',
        '体育',
        '经济',
      ];
    
      TabController _controller;
    
      @override
      void initState() {
        super.initState();
        _controller = TabController(
          length: _tabValues.length,
          vsync: ScrollableState(),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Scaffold(
          appBar: AppBar(
            title: Text('TabBar'),
            bottom: TabBar(
              tabs: _tabValues.map((f) {
                return Text(f);
              }).toList(),
              controller: _controller,
              indicatorColor: Colors.red,
              indicatorSize: TabBarIndicatorSize.tab,
              isScrollable: true,
              labelColor: Colors.red,
              unselectedLabelColor: Colors.black,
              indicatorWeight: 5.0,
              labelStyle: TextStyle(height: 2),
            ),
          ),
          body: TabBarView(
            controller: _controller,
            children: _tabValues.map((f) {
              return Center(
                child: Text(f),
              );
            }).toList(),
          ),
        );
      }
    }
    
    3、文字中间添加横线
    Text(
                            '${productItem.originPrice}',
                            style: TextStyle(
                              fontSize: 12,
                              color: Color(0xff929292),
                              decoration: TextDecoration.lineThrough,
                              decorationColor: Color(0xff929292),
                            ),
    
    4、页面布局和自自定义
    class ProductsListHomeB extends StatefulWidget {
      String tabKey;
      int index;
      ProductsListHomeB(this.tabKey, this.index);
      @override
      State<StatefulWidget> createState() {
        return ProductsListHomeBState();
      }
    }
    
    class ProductsListHomeBState extends State<ProductsListHomeB>
        with AutomaticKeepAliveClientMixin {
      String tabKey;
      emptyStyle emptyType = emptyStyle.firstLoad;
      bool hasMore;
      bool firstLoad;
      var pageNum = 1;
      var _productslist = <Product>[]; //数据源
      final ratio = window.physicalSize.width / window.devicePixelRatio / 375.0;
      EasyRefreshController _refreshController = EasyRefreshController();
      var _midBlack = Platform.isAndroid ? FontWeight.w600 : FontWeight.w500;
    
      String platform = TAOBAO_PLAT;
      int index;
    //1、初始化数据&&&&请求数据
      @override
      void initState() {
        super.initState();
        _buildData();
        index = widget.index;
      }
    // 2、网络请求数据
      Future<Widget> _buildData() async {
        // setState(() {
        firstLoad = true;
        tabKey = widget.tabKey;
        print('tabkey=${widget.tabKey}');
        ProductModel model =
            await ProductListModel().getProductList(tabKey, pageNum, platform);
        hasMore = model.hasMore;
        _buildEmptyText(model);
        firstLoad = false;
        print('获取到的数据=${model.productlist.length}');
        setState(() {
          _productslist = model.productlist;
        });
      }
    // 3、下拉刷新数据只更新第一个页面,其余的数据都被替换
      Future<void> _onRefresh() async {
        pageNum = 1;
        ProductModel model =
            await ProductListModel().getProductList(tabKey, pageNum, platform);
        hasMore = model.hasMore;
        _buildEmptyText(model);
        setState(() {
          _productslist = model.productlist;
          print('长度 = ${_productslist.length}');
        });
        _refreshController.finishRefresh();
      }
    //4、上拉加载更多的数据,这里要添加数据_productslist.addAll(model.productlist);
      Future<void> _onLoad() async {
        if ((hasMore == false || hasMore == null)) {
          await _refreshController.finishRefresh();
          return;
        }
        pageNum++;
        if (_productslist.length <= 0) {
          return; //避免刚加载页面就出发上拉加载
        }
        ProductModel model =
            await ProductListModel().getProductList(tabKey, pageNum, platform);
        hasMore = model.hasMore;
        _buildEmptyText(model);
        setState(() {
          _productslist.addAll(model.productlist);
          print('长度 = ${_productslist.length}');
        });
    
        _refreshController.finishRefresh();
      }
    //5、数据空的判断
      Widget _buildEmptyText(ProductModel model) {
        if (model.productlist.length == 0) {
          if (model.hasNet == true) {
            emptyType = emptyStyle.noData;
          } else {
            emptyType = emptyStyle.noNet;
          }
        }
      }
    
      Widget _emptyWidget() {
        return ProductsEmptyWidget(emptyType, () {
          _buildData();
        });
      }
    
      @override
      Widget build(BuildContext context) {
        print('tabkeyb=${widget.tabKey}');
        final double inset = 10 * ratio;
        return Column(
          children: [
            _buildSelectPlatView(),
            Container(
              height: 8,
            ),
            Expanded(
              child: EasyRefresh(
                onRefresh: _onRefresh,
                onLoad: _onLoad,
                header: RefreshHeader(),
                footer: ClassicalFooter(
                    loadingText: '正在拉取更多数据...',
                    loadedText: '哎呀,亲爱的,已经到底啦~',
                    showInfo: false),
                emptyWidget: (_productslist.length == 0) ? _emptyWidget() : null,
                firstRefresh: false,
                controller: _refreshController,
                // header: RefreshHeader(color: Color(0xFF2A263A)),
                //6、GridView 的布局,使用代理
                child: GridView.builder(
                    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        //横轴元素个数
                        crossAxisCount: 2,
                        //纵轴间距
                        mainAxisSpacing: inset,
                        //横轴间距
                        crossAxisSpacing: inset,
                        //子组件宽高长度比例
                        childAspectRatio: 175 / 258),
                    itemCount: _productslist.length,
                    itemBuilder: (context, i) {
                      final product = _productslist.elementAt(i);
                    //7、cell传参展示
                      return GestureDetector(
                        child: ProductsListHomeCellB(product, isTaoBaoSelected),    
                    //8、点击跳转页面
                        onTap: () {
                          print('点击列表b');
                          // routerOpenUrl(context: Get.context, urlStr: "${product.couponShareUrl}");
                          routerOpenURLExp(
                              context: Get.context, urlStr: "${product.detailUrl}");
                        },
                      );
                    }),
              ),
            )
          ],
        );
      }
    
      bool isTaoBaoSelected = true;
      bool isPddSelected = false;
      //9、淘宝京东以及中间的分割线
      Widget _buildSelectPlatView() {
        return Container(
          height: 36,
          alignment: Alignment.center,
          color: Colors.white,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              GestureDetector(
                onTap: () {
                  platform = TAOBAO_PLAT;
                  Map arg = {'platform': platform, 'index': index};
                  //eventBus事件订阅触发
                  WTBus.sendBroadcast(TYPE_PLATFORM_SELECT, arg);
                  Map extMap = {'tab_key': tabKey, 'type': platform};
                  //9.0打点
                  WTDataAnalysis.clickEvent(
                      eventId: "home_sort_click", extMap: extMap);
                  // 9.1、点击更新数据
                  _buildData();
                  setState(() {
                    isTaoBaoSelected = true;
                    isPddSelected = false;
                  });
                },
                //  UI 竖线
                child: Text(
                  '淘宝',
                  style: TextStyle(
                      color: isTaoBaoSelected ? Color(0xFFFF353E) : Colors.black,
                      fontSize: 15,
                      fontWeight: isTaoBaoSelected ? _midBlack : FontWeight.normal),
                ),
              ),
              Container(
                width: 0.5,
                margin: EdgeInsets.only(top: 10, bottom: 10),
                color: Color(0xFFE5E5E5),
              ),
              GestureDetector(
                onTap: () {
                  platform = PDD_PLAT;
                  Map map = {'platform': platform, 'index': index};
                  WTBus.sendBroadcast(TYPE_PLATFORM_SELECT, map);
                  Map extMap = {'tab_key': tabKey, 'type': platform};
                  WTDataAnalysis.clickEvent(
                      eventId: "home_sort_click", extMap: extMap);
                   //9.1、点击更新数据
                  _buildData();
                  setState(() {
                    isTaoBaoSelected = false;
                    isPddSelected = true;
                  });
                },
                child: Text(
                  '拼多多',
                  style: TextStyle(
                      color: !isTaoBaoSelected ? Color(0xFFFF353E) : Colors.black,
                      fontSize: 15,
                      fontWeight: isPddSelected ? _midBlack : FontWeight.normal),
                ),
              )
            ],
          ),
        );
      }
    
      @override
      // TODO: implement wantKeepAlive
      bool get wantKeepAlive => true;
    }
    
    
    5、EventBus事件订阅、监听和销毁
    5.1事件订阅
     platform = TAOBAO_PLAT;
     Map arg = {'platform': platform, 'index': index};
      //eventBus事件订阅触发
     WTBus.sendBroadcast(TYPE_PLATFORM_SELECT, arg);
    
    5.2 事件监听

    在Home页面中监听传参,然后记录用以后的使用。

      WTBus.addListener(TYPE_PLATFORM_SELECT, (arg) {
      platform = arg['platform'];
          platforms[arg['index']] = platform;
        });
    
    5.3 事件在dispose中移除
     @override
      void dispose() {
        super.dispose();
        WTBus.removeListener(TYPE_PLATFORM_SELECT);
        WTJSPluginManager().unRegisterListener('JSMembersOpenSuccessful');
        tabController.dispose();
      }
    
    • 重点:

    • 1、布局:Flexible/Expended

    • Flexible组件可以使Row、Column、Flex等子组件在主轴方向有填充可用空间的能力,但是不强制子组件填充可用空间。

    • Expanded组件可以使Row、Column、Flex等子组件在其主轴方向上展开并填充可用空间,是强制子组件填充可用空间。

    • 2、富文本 text.rich: TextSpan(图文混合: widgetSpan(),text)

    相关文章

      网友评论

          本文标题:小羊秘籍总结重点

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