【问题标题】:Flutter: How to create bidirectional scrolling ListView with fixed portion of on left and bottomFlutter:如何创建具有固定部分的双向滚动 ListView 在左侧和底部
【发布时间】:2020-02-28 18:52:27
【问题描述】:

如何在 Flutter 中制作滚动视图,其中屏幕的左侧和底部是固定的(轴),然后屏幕的其余部分可以水平向右滚动或垂直向上滚动。 (想象一下滚动带有两个轴的图形.. 见图片)

【问题讨论】:

    标签: flutter graph scroll drawing bidirectional


    【解决方案1】:

    非常有趣的问题。查看文档后,我找不到适合这种情况的小部件。所以我决定在 pub.dev 上搜索一下可以实现这一点的插件。

    找到它:https://pub.dev/packages/bidirectional_scroll_view

    该插件在两个轴上滚动内容方面做得相当好,但要获得您正在寻找的内容(“左侧和底部的固定部分”),您必须相应地构建您的页面。我决定使用 Stack 和 Align 小部件,如下所示:

    See the full code on a working DartPad: https://dartpad.dev/10573c0e9bfa7f1f8212326b795d8628

    或者看看下面的代码(不要忘记在你的项目中包含 bidirectional_scroll_view):

    void main() {
      runApp(new MyApp());
    }
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => new _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      BidirectionalScrollViewPlugin _plugin;
      double fixedAxisSpace = 100.0;
      double biDirectContentWidth = 4096.0;
      double biDirectContentHeight = 4096.0;
    
      @override
      void initState() {
        super.initState();
          _plugin = new BidirectionalScrollViewPlugin(
          child: _buildWidgets(),
          velocityFactor: 0.0, 
        );
      }
    
      void _snapToZeroZero(BuildContext context){
        double yOffset = biDirectContentHeight + fixedAxisSpace - context.size.height;
        _plugin.offset = new Offset(0, yOffset);
      }
    
      @override
      Widget build(BuildContext context) { 
        final btnSnapToZeroZero = Padding(
          padding: EdgeInsets.all(10.0),
            child:FlatButton(
              color: Colors.black,
              shape: RoundedRectangleBorder(
                borderRadius: new BorderRadius.circular(12.0),
              ),
              onPressed: () { _snapToZeroZero(context); },
              child: Text(
                "Snap to 0.0",
                textAlign: TextAlign.center,
                style: TextStyle(color: Colors.white),
                ),
           )
          );
    
        return new MaterialApp(
          debugShowCheckedModeBanner: false,
          home: new Scaffold(
            body: Stack(
              children: <Widget>[
                 _plugin, // BidirectionalScrollViewPlugin, goes 1st because we want it to sit on the bottom layer
                 Align( // Y Axis goes over _plugin, it is aligned to topLeft
                  alignment: Alignment.topLeft,
                  child: Column(
                    children: <Widget> [
                      Expanded( 
                        child: Container(
                          width: fixedAxisSpace,
                          decoration: BoxDecoration(
                            color: Colors.white, // change to Colors.white70 too se what is going on "behind the scene"
                            border: Border(
                              right: BorderSide(width: 1.0, color: Colors.black),
                            ),
                          ),
                          child: Center(child: VerticalTextWidget("FIXED _ Y AXIS", 22))
                        ),
                      ),
                      SizedBox(height: fixedAxisSpace),
                    ]
                  ),
                 ),
                 Align( // X Axis goes over _plugin and Y Axis, it is aligned to bottomLeft
                  alignment: Alignment.bottomLeft,
                  child: Row(
                    children: <Widget> [
                      SizedBox(width: fixedAxisSpace),
                      Expanded( 
                        child: Container(
                          height: fixedAxisSpace,
                          decoration: BoxDecoration(
                            color: Colors.white, // change to Colors.white70 too se what is going on "behind the scene"
                            border: Border(
                              top: BorderSide(width: 1.0, color: Colors.black),
                            ),
                          ),
                          child: Center(child: Text("FIXED | X AXIS", style: TextStyle(fontSize: 22)))
                        ),
                      ),
                    ]
                  ),
                 ),
    
                 Align( // this little square is optional, I use it to put a handy little button over everything else at the bottom left corner.
                  alignment: Alignment.bottomLeft,
                    child: Container(
                      color: Colors.white, // change to Colors.white70 too se what is going on "behind the scene"
                      height: fixedAxisSpace,
                      width: fixedAxisSpace,
                      child: btnSnapToZeroZero
                  ),
                 ),
    
              ],
            )
         )
        );
      }
    
      // put your large bidirectional content here
      Widget _buildWidgets() {
        return new Padding(
          padding: EdgeInsets.fromLTRB(100, 0, 0, 100),
          child: SizedBox(
            width: biDirectContentWidth,
            height: biDirectContentHeight,
            child: Image.network(
              'https://i.stack.imgur.com/j1ItQ.png?s=328&g=1',
              repeat: ImageRepeat.repeat,
              alignment: Alignment.bottomLeft
            ),
          )
        );
      }
    }
    

    垂直文本小部件:

    class VerticalTextWidget extends StatelessWidget {
      final String text;
      final double size;
    
      const VerticalTextWidget(this.text, this.size);
    
      @override
      Widget build(BuildContext context) {
        return Wrap(
          direction: Axis.vertical,
          alignment: WrapAlignment.center,
          children: text.split("").map((string) => Text(string, style: TextStyle(fontSize: size))).toList(),
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-16
      • 2021-07-31
      • 1970-01-01
      • 2023-03-16
      • 2018-06-03
      • 1970-01-01
      • 2023-03-26
      相关资源
      最近更新 更多