【问题标题】:Make DataTable Scroll Bidirectional in FlutterFlutter中让DataTable双向滚动
【发布时间】:2019-08-13 10:10:01
【问题描述】:

如何使 DataTable 双向滚动。 我让数据表水平滚动,但我的列表很大,无法向下滚动。

@override 
Widget build(BuildContext context) { 
    return Scaffold(
      appBar: AppBar(title: Text("Bills Receivable"),),
      body:SingleChildScrollView( 
        scrollDirection: Axis.horizontal, 
        child:
           DataTable(
          columns: <DataColumn>[
            DataColumn(label:Text("BNm",style: TextStyle(fontWeight: FontWeight.bold),)),
            DataColumn(label:Text("BDt",style: TextStyle(fontWeight: FontWeight.bold),)),
            DataColumn(label:Text("BPrty",style: TextStyle(fontWeight: FontWeight.bold),)),
            DataColumn(label:Text("BdueDt",style: TextStyle(fontWeight: FontWeight.bold),)),
            DataColumn(label:Text("Dys",style: TextStyle(fontWeight: FontWeight.bold),)),
            DataColumn(label:Text("BAmt",style: TextStyle(fontWeight: FontWeight.bold),)),
            DataColumn(label:Text("BPAmt",style: TextStyle(fontWeight: FontWeight.bold),)),
            DataColumn(label:Text("BBAmt",style: TextStyle(fontWeight: FontWeight.bold),))
          ], rows:  widget.rdata.bRecDtl.map((e)=>
            DataRow(
              cells:<DataCell>[
                DataCell(Text(e.bNm.toString())),
                DataCell(Text(e.bDt.toString())),
                DataCell(Text(e.bPrty.toString())),
                DataCell(Text(e.bdueDt.toString())),
                DataCell(Text(e.dys.toString())), 
                DataCell(Text(e.bAmt.toString())),
                DataCell(Text(e.bPAmt.toString())),
                DataCell(Text(e.bBAmt.toString())),
          ])).toList()
        ),
      ),
    );
  }

【问题讨论】:

    标签: flutter flutter-layout


    【解决方案1】:

    只需添加两个SingleChildScrollViews:

    child: SingleChildScrollView(
             scrollDirection: Axis.vertical,
             child: SingleChildScrollView(
               scrollDirection: Axis.horizontal,
               child: DataTable()
    

    【讨论】:

    • 水平滚动上的滚动条在 futter web 中不显示,如何使其可见?
    【解决方案2】:

    更新更简单的方法。

    在最新的 Flutter 更新中,您还可以将 DataTable 包装在 InteractiveViewer 小部件中,并将 constrained 属性设置为 false。与早期的解决方案不同,这将允许您同时水平和垂直滚动。它的代码也更少,可让您放大/缩小 DataTable。

    祝你好运!

    【讨论】:

    • 由于某种原因,InteractiveViewerSingleChildScrollView 相比会影响大数据表中的性能。然而 InteractiveViewer 具有更多更好的可用性。希望几个版本后情况会有所改变
    • @Alex.F 我认为快速放大和缩小功能会影响渲染过程。但是只要桌子很小并且想要一些附加功能,这个小部件就非常好!
    • @ExoticSquid 你能用flutter web实现这个吗?因为它对我不起作用...
    • @user10033434,我在 Flutter Web 上测试过。它工作得很好。
    【解决方案3】:

    我以前用这种方式编码,效果很好:

    import 'package:cloud_firestore/cloud_firestore.dart';
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:followmeifucan/constants/style_constants.dart';
    import 'package:font_awesome_flutter/font_awesome_flutter.dart';
    
    
    class RankScreen extends StatefulWidget {
    
      static String id = 'ranks_screen';
    
      @override
      _RankScreenState createState() => _RankScreenState();
    }
    
    class _RankScreenState extends State<RankScreen> {
      final _firestore = Firestore.instance;
    
      @override
      void initState() {
        super.initState();
      }
    
      List<DataCell> _createCellsForElement(DocumentSnapshot document){
        Timestamp timestamp = document.data['when'];
        return <DataCell>[
          DataCell(Text(document.data['name'].toString())),
          DataCell(Text(document.data['level'].toString())),
          DataCell(Text(document.data['round'].toString())),
          DataCell(Text(document.data['hits_ok'].toString())),
          DataCell(Text(timestamp.toDate().toString().substring(0, 16))),
          DataCell(Icon(document.data['plataform'].toString() == 'Android' ? Icons.android : FontAwesomeIcons.apple))
        ];
      }
    
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            centerTitle: true,
            backgroundColor: Colors.black,
            title: Row(
              children: <Widget>[
                Flexible(
                  child: Hero(
                    tag: 'logo',
                    child: Container(
                      height: 30.0,
                      child: Image.asset('images/default_icon.png'),
                    ),
                  ),
                ),
                SizedBox(width: 10.0,),
                Text('HIGHSOCRES'),
              ],
            ),
          ),
          body: SafeArea(
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: SingleChildScrollView(
                scrollDirection: Axis.vertical,
                child: Column(
                  children: <Widget>[
                    StreamBuilder<QuerySnapshot>(
                    stream:  _firestore.collection('ranks').snapshots(),
                    builder: (context, snapshot){
                      List<DataRow> rankLines = new List<DataRow>();
                      if(snapshot.hasData){
                        final ranks = snapshot.data.documents;
                       for(var rankData in ranks){
    
                         rankLines.add(
                             DataRow(
                                 cells: _createCellsForElement(rankData)
                             )
                         );
                       }
                      }
                      return Container(
                        child: SingleChildScrollView(
                          scrollDirection: Axis.horizontal,
                          child: DataTable(
                            sortAscending: true,
                            sortColumnIndex: 3,
    
                            columns: <DataColumn>[
                              DataColumn(label: Text('NAME', style: kRankLabelStyle,)),
                              DataColumn(label:Text('LEVEL', style: kRankLabelStyle,), numeric: true,),
                              DataColumn(label:Text('ROUND', style: kRankLabelStyle,), numeric: true,),
                              DataColumn(label:Text('HITS OK', style: kRankLabelStyle,), numeric: true,),
                              DataColumn(label:Text('WHEN', style: kRankLabelStyle,),),
                              DataColumn(label:Icon(Icons.phone_iphone)),
                            ],
                            rows: rankLines,
                          ),
                        ),
                      );
                    },
                  ),
                  ]
                ),
              ),
            ),
          ),
        );
      }
    }
    

    【讨论】:

      【解决方案4】:

      如果这里有人使用 PaginatedDataTable 或 PaginatedDataTable2,您需要设置 minWidth 属性才能使水平滚动正常工作。

      【讨论】:

        【解决方案5】:

        您可以使用两个 SingleChildScrollView 或一个 InteractiveViewer。

        但是如果你想要两个这样的固定滚动条。

        Bidirectional scrolling with fixed scrollbar

        我使用了两个 SingleChildScrollView 和adaptive_scrollbar v2.1.0 来得到这个结果。

        源代码

        import 'package:flutter/material.dart';
        import 'package:adaptive_scrollbar/adaptive_scrollbar.dart';
        
        void main() {
          runApp(const MyApp());
        }
        
        class MyApp extends StatelessWidget {
          const MyApp({Key? key}) : super(key: key);
        
          // This widget is the root of your application.
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              title: 'Flutter Bidirectional Scrollbars',
              theme: ThemeData(
                primarySwatch: Colors.blue,
              ),
              home: const MyHomePage(title: 'Flutter Demo Home Page'),
            );
          }
        }
        
        class MyHomePage extends StatefulWidget {
          const MyHomePage({Key? key, required this.title}) : super(key: key);
        
          final String title;
        
          @override
          State<MyHomePage> createState() => _MyHomePageState();
        }
        
        class _MyHomePageState extends State<MyHomePage> {
          @override
          Widget build(BuildContext context) {
            final _verticalScrollController = ScrollController();
            final _horizontalScrollController = ScrollController();
        
            return Scaffold(
              appBar: AppBar(
                title: Text(widget.title),
              ),
              body: Container(
                height: 300,
                width: 700,
                child: AdaptiveScrollbar(
                  underColor: Colors.blueGrey.withOpacity(0.3),
                  sliderDefaultColor: Colors.grey.withOpacity(0.7),
                  sliderActiveColor: Colors.grey,
                  controller: _verticalScrollController,
                  child: AdaptiveScrollbar(
                    controller: _horizontalScrollController,
                    position: ScrollbarPosition.bottom,
                    underColor: Colors.blueGrey.withOpacity(0.3),
                    sliderDefaultColor: Colors.grey.withOpacity(0.7),
                    sliderActiveColor: Colors.grey,
                    child: SingleChildScrollView(
                      controller: _verticalScrollController,
                      scrollDirection: Axis.vertical,
                      child: SingleChildScrollView(
                        controller: _horizontalScrollController,
                        scrollDirection: Axis.horizontal,
                        child: Padding(
                          padding: const EdgeInsets.only(right: 8.0, bottom: 16.0),
                          child: DataTable(
                            showCheckboxColumn: true,
                            columns: [
                              DataColumn(
                                label: Text('Name'),
                              ),
                              DataColumn(
                                label: Text('Year'),
                              ),
                              DataColumn(
                                label: Text('Year'),
                              ),
                              DataColumn(
                                label: Text('Year'),
                              ),
                              DataColumn(
                                label: Text('Year'),
                              ),
                              DataColumn(
                                label: Text('Name'),
                              ),
                              DataColumn(
                                label: Text('Year'),
                              ),
                              DataColumn(
                                label: Text('Year'),
                              ),
                              DataColumn(
                                label: Text('Year'),
                              ),
                              DataColumn(
                                label: Text('Year'),
                              ),
                            ],
                            rows: List<DataRow>.generate(
                              20,
                              (int index) => DataRow(
                                cells: <DataCell>[
                                  DataCell(
                                    Text('Row $index'),
                                  ),
                                  DataCell(
                                    Text('Row $index'),
                                  ),
                                  DataCell(
                                    Text('Row $index'),
                                  ),
                                  DataCell(
                                    Text('Row $index'),
                                  ),
                                  DataCell(
                                    Text('Row $index'),
                                  ),
                                  DataCell(
                                    Text('Row $index'),
                                  ),
                                  DataCell(
                                    Text('Row $index'),
                                  ),
                                  DataCell(
                                    Text('Row $index'),
                                  ),
                                  DataCell(
                                    Text('Row $index'),
                                  ),
                                  DataCell(
                                    Text('Row $index'),
                                  ),
                                ],
                                onSelectChanged: (bool? value) {},
                              ),
                            ),
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            );
          }
        }
        
        

        【讨论】:

          猜你喜欢
          • 2018-12-18
          • 2018-09-17
          • 1970-01-01
          • 1970-01-01
          • 2021-04-15
          • 2017-06-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多