屏幕外flutter_swiper幻灯片布局,堆栈/定位小部件

时间:2019-08-18 04:10:05

标签: flutter dart slider flutter-layout

我正在尝试使用Flutter实现这种布局和内容:

https://i.imgur.com/oqiZqHb.png

如果我尝试使用“定位”小部件偏移-20,以使flutter_swiper程序包的粘性滚动功能隐藏在屏幕的一部分上,并在其顶部放置侧面标题以覆盖它,那么我得到:

I/flutter ( 6060): Another exception was thrown: A RenderFlex overflowed by Infinity pixels on the bottom.

删除“定位的小部件”使布局起作用,在此示例中,我可能需要一张额外的卡片,但我正在努力使滑块偏移,并且在堆栈上具有正确的可滑动项目比例141x118,右边有12个填充,第三个略微显示在右侧,但小部件起点也剪切了第一个。

https://i.imgur.com/AfjqIag.jpg

这是我的水平滑块小部件代码:

import 'package:flutter/cupertino.dart';
import '../../../theme/styles.dart';

import 'package:flutter_swiper/flutter_swiper.dart';

import 'dart:math';

class HorizontalIndicator extends StatefulWidget {
  const HorizontalIndicator({
    Key key,
  }) : super(key: key);

  @override
  _HorizontalIndicatorState createState() => _HorizontalIndicatorState();
}

class _HorizontalIndicatorState extends State<HorizontalIndicator> {
  @override
  Widget build(BuildContext context) {
    var rnd = new Random();
    var next = rnd.nextInt(10) * 1;
    double screenWidth = MediaQuery.of(context).size.width;
    return Container(
      height: 120,
      padding: EdgeInsets.only(top: 0),
      width: screenWidth,
      child: Stack(
          overflow: Overflow.visible,
          fit: StackFit.expand,
          children: <Widget>[
            Container(
                child: new Swiper(
                    itemBuilder: (BuildContext context, int index) {
                      return Container(
                        margin: EdgeInsets.symmetric(vertical: 6),
                        decoration: new BoxDecoration(
                          borderRadius: BorderRadius.all(Radius.circular(26)),
                          boxShadow: [
                            BoxShadow(
                              color: ThemeColor.shadowColor,
                              blurRadius:
                                  3.0, 
                              spreadRadius:
                                  0, 
                            )
                          ],
                        ),
                        child: Padding(
                          padding: const EdgeInsets.only(right: 12),
                          child: ClipRRect(
                            borderRadius: BorderRadius.circular(26),
                            child: Image.network(
                              "https://picsum.photos/150/120?" +
                                  "$index" +
                                  "$next",
                              fit: BoxFit.cover,
                            ),
                          ),
                        ),
                      );
                    },
                    itemCount: 10,
                    viewportFraction: 0.43,
                    scale: 1,
                    itemWidth: 150,
                    itemHeight: 120,
                    layout: SwiperLayout.DEFAULT)),
          ]),
    );
  }
}


这就是我的定位方式

...

 Stack(
        alignment: AlignmentDirectional.topStart,
        fit: StackFit.loose,
        overflow: Overflow.visible,
        children: [
          ListView(children: <Widget>[
            Padding(
              padding: const EdgeInsets.only(top: 85, left: 50),
              child: Column(
                children: <Widget>[
                  HorizontalIndicator(),
                  HorizontalIndicator(),
                  HorizontalIndicator(),
                  HorizontalIndicator(),
                ],
              ),
            ),
          ]),
          //ProgressBarLarge2(),
        ],
      ),

...

1 个答案:

答案 0 :(得分:0)

我终于有了这种布局。

这是我放置物品的方式:

 Stack(
    alignment: AlignmentDirectional.topStart,
    fit: StackFit.loose,
    children: [
      ListView(physics: ClampingScrollPhysics(), children: <Widget>[
        Padding(
          padding: const EdgeInsets.only(top: 80, left: 0),
          child: Column(
            children: <Widget>[
              HorizontalIndicator(),
              HorizontalIndicator(),
              HorizontalIndicator(),
            ],
          ),
        ),
      ]),
      ProgressBarLarge(
          context, ThemeColor.primaryColor, 0.5, 48, 11, "Done", "Pending"),
    ],
  ),

这是水平窗口小部件的结构方式(很抱歉,长代码!)。 我只使用了Stack和Positioned.fill小部件,其正确值为-100,并调整了viewportFraction值:

Container(
      height: 124,
      padding: EdgeInsets.only(top: 0),
      child: Stack(alignment: Alignment.centerLeft, children: <Widget>[
        Positioned.fill(
          left: 47,
          right: -100,
          child: Container(
              child: new Swiper(
                  itemBuilder: (BuildContext context, move) {
                    return Container(
                        padding: EdgeInsets.symmetric(vertical: 0),
                        decoration: new BoxDecoration(
                          borderRadius:
                              BorderRadius.all(Radius.circular(26)),
                          boxShadow: [
                            BoxShadow(
                              color: ThemeColor.shadowColor.withOpacity(0),
                              offset: Offset(0, 2),
                              blurRadius:
                                  87.0, // has the effect of softening the shadow
                              spreadRadius:
                                  0, // has the effect of extending the shadow
                            )
                          ],
                        ),
                        child: Padding(
                          padding: const EdgeInsets.all(0),
                          child: Container(
                            margin: EdgeInsets.all(5),
                            child: MaterialButton(
                              elevation: 0,
                              highlightElevation: 2,
                              shape: RoundedRectangleBorder(
                                  borderRadius:
                                      BorderRadius.circular(26.0)),
                              padding: EdgeInsets.fromLTRB(0, 0.0, 0, 0.0),

                              color: Colors.grey.shade800,
                              onPressed: () {
                                Navigator.push(
                                  context,
                                  CupertinoPageRoute(
                                      builder: (context) => SeatsPage()),
                                );
                              },

                              child: Container(

                                child: Column(
                                  crossAxisAlignment:
                                      CrossAxisAlignment.start,
                                  mainAxisAlignment:
                                      MainAxisAlignment.center,
                                  children: <Widget>[
                                    Padding(
                                      padding: const EdgeInsets.all(0),
                                      child: Column(
                                        crossAxisAlignment:
                                            CrossAxisAlignment.start,
                                        children: <Widget>[
                                          Padding(
                                            padding: const EdgeInsets.only(
                                                left: 24,
                                                top: 12,
                                                right: 24),
                                            child: FittedBox(
                                              fit: BoxFit.scaleDown,
                                              child: Row(
                                                mainAxisAlignment:
                                                    MainAxisAlignment
                                                        .spaceBetween,
                                                children: <Widget>[
                                                  Padding(
                                                    padding:
                                                        const EdgeInsets
                                                                .only(
                                                            top: 0,
                                                            right: 0),
                                                    child: Opacity(
                                                      opacity: 0.90,
                                                      child: Text(
                                                        "84",
                                                        style: ThemeText
                                                            .cardHeaderNumber,
                                                        textAlign:
                                                            TextAlign.left,
                                                      ),
                                                    ),
                                                  ),
                                                  //  Icon(
                                                  //    Icons.more_vert,
                                                  //    color: Colors.grey.withAlpha(0), // More
                                                  // ),
                                                ],
                                              ),
                                            ),
                                          ),
                                          Padding(
                                              padding:
                                                  const EdgeInsets.fromLTRB(
                                                      24, 2, 16, 2),
                                              child: Row(
                                                mainAxisAlignment:
                                                    MainAxisAlignment
                                                        .spaceBetween,
                                                children: <Widget>[
                                                  Opacity(
                                                    opacity: 0.50,
                                                    child: Text(
                                                      "Available",
                                                      style: ThemeText
                                                          .cardText,
                                                    ),
                                                  ),
                                                  Icon(
                                                    Icons
                                                        .fiber_smart_record,
                                                    color: ThemeColor
                                                        .primaryColor,
                                                  ),
                                                ],
                                              ))
                                        ],
                                      ),
                                    ),
                                  ],
                                ),
                              ),
                            ),
                          ),
                        ));
                  },
                  itemCount: 4,
                  viewportFraction: viewportFraction,
                  scale: 1,
                  itemWidth: 140,
                  itemHeight: 120,
                  layout: SwiperLayout.DEFAULT)),
        ),
      ]),
    ),