最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Flutter中布局实现:线性、弹性、流式和层叠布局

    正文概述 掘金(天涯一角)   2021-04-09   716

    Flutter中通过Row和Column来实现线性布局,类似于Android中的LinearLayout控件。Row和Column都继承自Flex,弹性布局Flex允许子组件按照一定比例来分配父容器空间。超出屏幕显示范围会自动折行的布局称为流式布局。Flutter中通过Wrap和Flow来支持流式布局。层叠布局和Android中的Frame布局是相似的,子组件可以根据距父容器四个角的位置来确定自身的位置。绝对定位允许子组件堆叠起来(按照代码中声明的顺序)。Flutter中使用Stack和Positioned这两个组件来配合实现绝对定位。Stack允许子组件堆叠,而Positioned用于根据Stack的四个角来确定子组件的位置。

    一、线性布局

    1.1 主轴和交叉轴

    对于线性布局,有主轴和交叉轴之分,如果布局是沿水平方向,那么主轴就是指水平方向,而交叉轴即垂直方向;如果布局沿垂直方向,那么主轴就是指垂直方向,而交叉轴就是水平方向。在线性布局中,有两个定义对齐方式的枚举类MainAxisAlignment和CrossAxisAlignment,分别代表主轴对齐和交叉轴对齐。

    主轴对齐 ---- MainAxisAlignment

    交叉轴对齐 ---- CrossAxisAlignment

    下面是MainAxisAlignment,它也是一个枚举类。

    enum MainAxisAlignment {
      start,
      end,
      center,
      spaceBetween,
      spaceAround,
      spaceEvenly,
    }
    

    start ---- 将子Widget放置在尽可能靠近主轴起点的位置。如果在水平方向上使用此值,则[TextDirection]必须可用以确定起点是左侧还是右侧;如果在垂直方向上使用此值,则[VerticalDirection]必须可用以确定起点是顶部还是底部。

    end ---- 将子Widget放置在尽可能靠近主轴末端的位置。如果在水平方向上使用此值,则[TextDirection]必须可用以确定结尾是左侧还是右侧;如果在垂直方向上使用此值,则必须使用[VerticalDirection]来确定末端是顶部还是底部。

    center ---- 将子Widget放置在尽可能靠近主轴中心的位置。

    spaceBetween ---- 将空闲空间均匀地放在子Widget之间。

    spaceAround ---- 在子Widget之间以及第一个和最后一个子Widget之前和之后的一半空间之间均匀地放置可用空间。这段文字有点绕,接下来看实例就非常清晰了。

    spaceEvenly ---- 将空闲空间均匀地放在子Widget之间以及第一个和最后一个子Widget子之前和之后。

    下面是CrossAxisAlignment,它也是一个枚举类。

    enum CrossAxisAlignment {
      start,
      end,
      center,
      stretch,
      baseline,
    }
    

    start ---- 将子项的起始边缘与交叉轴的起始侧对齐。如果在水平方向上使用此值,则[TextDirection]必须可用以确定起点是左侧还是右侧;如果在垂直方向上使用此值,则[VerticalDirection]必须可用以确定起点是顶部还是底部。

    end ---- 将子Widget放置在尽可能靠近交叉轴末端的位置。如果在水平方向上使用此值,则[TextDirection]必须可用以确定结尾是左侧还是右侧;如果在垂直方向上使用此值,则必须使用[VerticalDirection]来确定末端是顶部还是底部。

    center ---- 放置子Widget使其中心与交叉轴的中心对齐。这是默认的横轴对齐方式。

    stretch ---- 要求子Widget填满交叉轴。

    baseline ---- 沿交叉轴放置子Widget,使其基线匹配。如果主轴是垂直的,则将此值视为[start](因为基线始终是水平的)。

    1.2 Row 和 Column

    Flutter中通过Row和Column来实现线性布局。

    1.2.1 Row

    Row也就是行布局。

    Row({
        Key key,
        MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
        MainAxisSize mainAxisSize = MainAxisSize.max,
        CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
        TextDirection textDirection,
        VerticalDirection verticalDirection = VerticalDirection.down,
        TextBaseline textBaseline,
        List<Widget> children = const <Widget>[],
      })
    

    mainAxisAlignment ---- 表示子组件在Row所占用的水平空间内对齐方式,如果mainAxisSize值为MainAxisSize.min,则此属性无意义,因为子组件的宽度等于Row的宽度。只有当mainAxisSize的值为MainAxisSize.max时,此属性才有意义。

    textDirection ---- 表示水平方向子组件的布局顺序(是从左往右还是从右往左),默认为系统当前Locale环境的文本方向(如中文、英语都是从左往右,而阿拉伯语是从右往左)。

    mainAxisSize ---- 表示Row在主轴(水平)方向占用的空间,默认是MainAxisSize.max,表示尽可能多的占用水平方向的空间,此时无论子widgets实际占用多少水平空间,Row的宽度始终等于水平方向的最大宽度;而MainAxisSize.min表示尽可能少的占用水平空间,当子组件没有占满水平剩余空间,则Row的实际宽度等于所有子组件占用的的水平空间。

    verticalDirection ---- 表示Row垂直的对齐方向,默认是VerticalDirection.down,表示从上到下。

    crossAxisAlignment ---- 表示子组件在纵轴方向的对齐方式,Row的高度等于子组件中最高的子元素高度。

    children ---- 子组件数组。

    textBaseline ---- 用于对齐文本的水平线。

    TextBaseline是一个枚举类,它包括alphabetic和ideographic。

    enum TextBaseline {
      alphabetic,
      ideographic,
    }
    

    alphabetic ---- 用于对齐字母字符的字形底部的水平线。

    ideographic ---- 用于对齐表意字符的水平线。

    1.2.2 Column

    和Row类似,Column是列布局。

    Column({
        Key key,
        MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
        MainAxisSize mainAxisSize = MainAxisSize.max,
        CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
        TextDirection textDirection,
        VerticalDirection verticalDirection = VerticalDirection.down,
        TextBaseline textBaseline,
        List<Widget> children = const <Widget>[],
      }) 
    

    下面来看一个例子。

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text("Home Page"),
            ),
            body: Column(mainAxisAlignment: MainAxisAlignment.start, children: <
                Widget>[
              Row(mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[
                Text(
                  'Test1',
                ),
                Text(
                  'Test2',
                ),
                Text(
                  'Test3',
                ),
                Text(
                  'Test4',
                )
              ]),
              Row(mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[
                Text(
                  'Test1',
                ),
                Text(
                  'Test2',
                ),
                Text(
                  'Test3',
                ),
                Text(
                  'Test4',
                )
              ]),
              Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
                Text(
                  'Test1',
                ),
                Text(
                  'Test2',
                ),
                Text(
                  'Test3',
                ),
                Text(
                  'Test4',
                )
              ]),
              Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    Text(
                      'Test1',
                    ),
                    Text(
                      'Test2',
                    ),
                    Text(
                      'Test3',
                    ),
                    Text(
                      'Test4',
                    )
                  ]),
              Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: <Widget>[
                    Text(
                      'Test1',
                    ),
                    Text(
                      'Test2',
                    ),
                    Text(
                      'Test3',
                    ),
                    Text(
                      'Test4',
                    )
                  ]),
              Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    Text(
                      'Test1',
                    ),
                    Text(
                      'Test2',
                    ),
                    Text(
                      'Test3',
                    ),
                    Text(
                      'Test4',
                    )
                  ]),
            ]));
      }
    }
    

    下面是对应的截图,对于Row行布局MainAxisAlignment理解就会一目了然。
    Flutter中布局实现:线性、弹性、流式和层叠布局
    接下来修改Demo,看看交叉轴控制。

    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text("Home Page"),
            ),
            body: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                children: <Widget>[
                  Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[
                        Text(
                          'Test1',
                          textScaleFactor: 3.0,
                        ),
                        Text(
                          'Test2',
                        ),
                        Text(
                          'Test3',
                        ),
                        Text(
                          'Test4',
                        )
                      ]),
                  Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text(
                          'Test1',
                          textScaleFactor: 3.0,
                        ),
                        Text(
                          'Test2',
                        ),
                        Text(
                          'Test3',
                        ),
                        Text(
                          'Test4',
                        )
                      ]),
                  Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      crossAxisAlignment: CrossAxisAlignment.end,
                      children: <Widget>[
                        Text(
                          'Test1',
                          textScaleFactor: 3.0,
                        ),
                        Text(
                          'Test2',
                        ),
                        Text(
                          'Test3',
                        ),
                        Text(
                          'Test4',
                        )
                      ]),
                ]));
      }
    }
    

    Flutter中布局实现:线性、弹性、流式和层叠布局
    再来研究一下交叉轴crossAxisAlignment设置为CrossAxisAlignment.stretch的效果,它要求子Widget填满交叉轴。对于Row来说交叉轴就是垂直方向。

    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text("Home Page"),
            ),
            body: Row(
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  Text(
                    'Test1',
                    textScaleFactor: 3.0,
                  ),
                  Text(
                    'Test2',
                  ),
                  Text(
                    'Test3',
                  ),
                  Text(
                    'Test4',
                  )
                ]));
      }
    }
    

    Flutter中布局实现:线性、弹性、流式和层叠布局

    二、弹性布局

    我们先来看一下Flex如何使用,接着来看搭配Expanded组件使用方法。

    2.1 Flex

    Flex组件可以沿着水平或垂直方向排列子组件,如果你知道主轴方向,使用Row或Column会方便一些,因为Row和Column都继承自Flex,参数基本相同,所以能使用Flex的地方基本上都可以使用Row或Column。Flex本身功能是很强大的,它也可以和Expanded组件配合实现弹性布局。

    Flex({
        Key key,
        @required this.direction,
        this.mainAxisAlignment = MainAxisAlignment.start,
        this.mainAxisSize = MainAxisSize.max,
        this.crossAxisAlignment = CrossAxisAlignment.center,
        this.textDirection,
        this.verticalDirection = VerticalDirection.down,
        this.textBaseline,
        List<Widget> children = const <Widget>[],
      })
    

    和Row、Column比起来多了一个direction,它是弹性布局的方向, Row默认为水平方向,Column默认为垂直方向。修改上面的例子把Row和Column替换为Flex,可以看出效果的确是一样的。

    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text("Home Page"),
            ),
            body: Flex(
                mainAxisAlignment: MainAxisAlignment.start,
                direction: Axis.vertical,
                children: <Widget>[
                  Flex(
                      mainAxisAlignment: MainAxisAlignment.start,
                      direction: Axis.horizontal,
                      children: <Widget>[
                        Text(
                          'Test1',
                        ),
                        Text(
                          'Test2',
                        ),
                        Text(
                          'Test3',
                        ),
                        Text(
                          'Test4',
                        )
                      ]),
                  Flex(
                      mainAxisAlignment: MainAxisAlignment.end,
                      direction: Axis.horizontal,
                      children: <Widget>[
                        Text(
                          'Test1',
                        ),
                        Text(
                          'Test2',
                        ),
                        Text(
                          'Test3',
                        ),
                        Text(
                          'Test4',
                        )
                      ]),
                ]));
      }
    }
    

    来看上面代码的运行结果:
    Flutter中布局实现:线性、弹性、流式和层叠布局

    2.2 Expanded

    可以按比例“扩伸” Row、Column和Flex子组件所占用的空间。这和android里面控件的weight类似。

    const Expanded({
        Key key,
        int flex = 1,
        @required Widget child,
      })
    

    flex ---- 为弹性系数,如果为0或null,则child是没有弹性的,即不会被扩伸占用的空间。如果大于0,所有的Expanded按照其flex的比例来分割主轴的全部可用空间。

    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text("Home Page"),
            ),
            body: Flex(
                mainAxisAlignment: MainAxisAlignment.start,
                direction: Axis.vertical,
                children: <Widget>[
                  Expanded(
                    flex: 2,
                    child: Flex(
                        mainAxisAlignment: MainAxisAlignment.start,
                        direction: Axis.horizontal,
                        children: <Widget>[
                          Text(
                            'Test1',
                          ),
                          Text(
                            'Test2',
                          ),
                          Text(
                            'Test3',
                          ),
                          Text(
                            'Test4',
                          )
                        ]),
                  ),
                  Expanded(
                    flex: 2,
                    child: Flex(
                        mainAxisAlignment: MainAxisAlignment.end,
                        direction: Axis.horizontal,
                        children: <Widget>[
                          Text(
                            'Test1',
                          ),
                          Text(
                            'Test2',
                          ),
                          Text(
                            'Test3',
                          ),
                          Text(
                            'Test4',
                          )
                        ]),
                  )
                ]));
      }
    }
    

    来看运行结果
    Flutter中布局实现:线性、弹性、流式和层叠布局

    三、流式布局

    在使用Row和Colum时,如果子widget超出屏幕范围,则会报溢出错误。我们把超出屏幕显示范围会自动折行的布局称为流式布局,Flutter中通过Wrap和Flow来支持流式布局。

    略微调整上个例子中的代码,我们就会看到溢出问题。

    Text(
        'Test1'* 200,
    ),
    

    Flutter中布局实现:线性、弹性、流式和层叠布局

    3.1 Wrap

    wrap这个单词本身就是包裹的意思,使用Wrap包裹子Widget以后就能实现流式布局。

    Wrap({
        Key key,
        this.direction = Axis.horizontal,
        this.alignment = WrapAlignment.start,
        this.spacing = 0.0,
        this.runAlignment = WrapAlignment.start,
        this.runSpacing = 0.0,
        this.crossAxisAlignment = WrapCrossAlignment.start,
        this.textDirection,
        this.verticalDirection = VerticalDirection.down,
        List<Widget> children = const <Widget>[],
      }) 
    

    大部分Field我们都已经见过了。

    spacing ---- 主轴方向子widget的间距

    runSpacing ---- 交叉轴方向的间距

    runAlignment ---- 交叉轴方向的对齐方式

    下面是Demo代码

    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text("Home Page"),
            ),
            body: Flex(
                mainAxisAlignment: MainAxisAlignment.start,
                direction: Axis.vertical,
                children: <Widget>[
                  Expanded(
                    flex: 2,
                    child: Wrap(
                        spacing: 8.0,
                        runSpacing: 4.0,
                        alignment: WrapAlignment.start,
                        runAlignment: WrapAlignment.center,
                        children: <Widget>[
                          Text(
                            'Test1' * 30,
                          ),
                          Text(
                            'Test2',
                          ),
                          Text(
                            'Test3',
                          ),
                          Text(
                            'Test4',
                          )
                        ]),
                  ),
                  Expanded(
                    flex: 2,
                    child: Flex(
                        mainAxisAlignment: MainAxisAlignment.end,
                        direction: Axis.horizontal,
                        children: <Widget>[
                          Text(
                            'Test1',
                          ),
                          Text(
                            'Test2',
                          ),
                          Text(
                            'Test3',
                          ),
                          Text(
                            'Test4',
                          )
                        ]),
                  )
                ]));
      }
    }
    

    运行效果如下
    Flutter中布局实现:线性、弹性、流式和层叠布局

    3.2 Flow

    Flow需要自己实现子widget的位置转换。

    Flow({
        Key key,
        @required this.delegate,
        List<Widget> children = const <Widget>[],
      }) 
    

    delegate ---- 控制流布局外观的委托

    比如下面的代码实现色块绘制,只画一行。

    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text("Home Page"),
            ),
            body: Flow(
              delegate: TestFlowDelegate(margin: EdgeInsets.all(10.0)),
              children: <Widget>[
                new Container(
                  width: 50.0,
                  height: 50.0,
                  color: Colors.red,
                ),
                new Container(
                  width: 50.0,
                  height: 50.0,
                  color: Colors.green,
                ),
                new Container(
                  width: 50.0,
                  height: 50.0,
                  color: Colors.blue,
                ),
                new Container(
                  width: 50.0,
                  height: 50.0,
                  color: Colors.yellow,
                ),
                new Container(
                  width: 50.0,
                  height: 50.0,
                  color: Colors.brown,
                ),
                new Container(
                  width: 50.0,
                  height: 50.0,
                  color: Colors.purple,
                ),
              ],
            ));
      }
    }
    
    class TestFlowDelegate extends FlowDelegate {
      EdgeInsets margin = EdgeInsets.zero;
    
      TestFlowDelegate({this.margin});
    
      @override
      void paintChildren(FlowPaintingContext context) {
        var x = margin.left;
        var y = margin.top;
        //计算每一个子widget的位置
        for (int i = 0; i < context.childCount; i++) {
          if (x < context.size.width) {
            context.paintChild(i,
                transform: new Matrix4.translationValues(x, y, 0.0));
          }
          x += context.getChildSize(i).width + margin.left + margin.right;
        }
      }
    
      @override
      getSize(BoxConstraints constraints) {
        //指定Flow的大小
        return Size(double.infinity, 70.0);
      }
    
      @override
      bool shouldRepaint(FlowDelegate oldDelegate) {
        return oldDelegate != this;
      }
    }
    

    运行效果如下:
    Flutter中布局实现:线性、弹性、流式和层叠布局

    四、层叠布局

    层叠布局包括Stack、Positioned。

    4.1 Stack

    Stack这个词对程序员来说一点都不陌生,先进后出是栈的特性。那么在Flutter中意味着Stack布局是可以堆叠的,顶层会浮在底层之上。

    Stack({
        Key key,
        this.alignment = AlignmentDirectional.topStart,
        this.textDirection,
        this.fit = StackFit.loose,
        this.overflow = Overflow.clip,
        List<Widget> children = const <Widget>[],
      }) 
    

    alignment ---- 如何对齐Stack中未定位和部分定位的子Widget。所谓部分定位,在这里特指没有在某一个轴上定位:left、right为横轴,top、bottom为纵轴,只要包含某个轴上的一个定位属性就算在该轴上有定位。

    fit ---- 确定没有定位的子Widget如何去适应Stack的大小

    enum StackFit {
      /// 从其父级传递到Stack的约束被放松。
      /// 例如,如果Stack具有将其强制为350x600的约束,
      /// 则这将允许Stack中未定位的子Widget具有从0到350的任何宽度和从0到600的任何高度。
      loose,
      /// 从其父级传递到Stack的约束被收缩到允许的最大限制。
      /// 例如,如果Stack具有宽松的约束,其宽度在10到100的范围内,高度在0到600的范围内,
      /// 那么Stack中未定位的子元素的大小将全部设置为100像素宽和600高。 
      expand,
      /// 从其父级传递到Stack的约束将未经修改地传递给未定位的子Widget。
      passthrough,
    }
    

    overflow ---- 决定如何显示超出Stack显示空间的子Widget

    enum Overflow {
      ///超出部分可见
      visible,
      /// 超出部分会被剪裁
      clip,
    }
    

    下面来看一个例子学习Stack如何使用。

    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text("Home Page"),
            ),
            body: ConstrainedBox(
              constraints: BoxConstraints.expand(),
              child: Stack(
                alignment: Alignment.center,
                children: <Widget>[
                  Container(
                    child: Text(
                      "Text1",
                      style: TextStyle(color: Colors.white),
                      textScaleFactor: 3.0,
                    ),
                    color: Colors.red,
                  ),
                  Container(
                    child:
                        Text("Text2", style: TextStyle(color: Colors.white)),
                    color: Colors.blue,
                  ),
                ],
              ),
            ));
      }
    }
    

    运行截图如下
    Flutter中布局实现:线性、弹性、流式和层叠布局

    4.1 Positioned

    Positioned就是可以定位的意思,所以它的Field包括了left、top、width和height,另外还有right和bottom,按照我们的理解前四个就够了。

    const Positioned({
        Key key,
        this.left,
        this.top,
        this.right,
        this.bottom,
        this.width,
        this.height,
        @required Widget child,
      }) 
    

    Positioned的width、height 和其它地方的意义稍微有点区别,此处用于配合left、top 、right和bottom来定位组件,举个例子,在水平方向时,你只能指定left、right、width三个属性中的两个,如指定left和width后,right会自动算出(left + width),如果同时指定三个属性则会报错,垂直方向同理。

    下面是使用Demo示例,由于Positioned存在部分定位,所以Stack alignment属性不在生效。

    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text("Home Page"),
            ),
            body: ConstrainedBox(
              constraints: BoxConstraints.expand(),
              child: Stack(
                alignment: Alignment.center,
                overflow: Overflow.clip,
                children: <Widget>[
                  Container(
                    child: Text(
                      "Text1",
                      style: TextStyle(color: Colors.white),
                      textScaleFactor: 3.0,
                    ),
                    color: Colors.red,
                  ),
                  Container(
                    child: Text("Text2", style: TextStyle(color: Colors.white)),
                    color: Colors.blue,
                  ),
                  Positioned(
                    left: 20.0,
                    top: 20.0,
                    child: Text("Text3"),
                  ),
                  Positioned(
                    right: 20.0,
                    child: Text("Text4"),
                  )
                ],
              ),
            ));
      }
    }
    

    运行结果
    Flutter中布局实现:线性、弹性、流式和层叠布局


    起源地下载网 » Flutter中布局实现:线性、弹性、流式和层叠布局

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元