颤动的分页数据表

时间:2020-08-15 15:29:49

标签: flutter dart flutter-layout

我正在使用PaginatedDataTable小部件显示api中的数据。它运行良好,因此我将rowsPerPage设置为4,如果我的数据长度为例如7,则在我的第一页中获取包含数据的4行,在第二页中获取其他树和一个空行。这就是问题所在,在第二页上,我只想获取包含数据的行,而没有空行。猜猜每个人都明白我的意思。

谢谢。

我的代码=>

class DashboardScreen extends StatefulWidget {
DashboardScreen(
  {this.token,
  this.f_name,
  this.phone,
  this.l_name,
  this.type_client,
  this.email,
  this.addresse,
  this.num_client});

  String token;
  final String f_name;
  final String l_name;
  final String email;
  final String addresse;
  final String num_client;
  final String phone;
  final String type_client;

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

class _DashboardScreenState extends State<DashboardScreen>
 with SingleTickerProviderStateMixin {
 final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  AnimationController _animationController;
  Animation<double> _animateIcon;
  bool isOpened = false;

  String token;
  String f_name;
  String l_name;
  String email;
  String addresse;
  String num_client;
  String phone, type_client;

  bool showSpinner = false;
  List<Transaction> transactions = [];

  int rowsPerPAge = 4;

Future<List<Transaction>> _getTransactionsData() async {
  setState(() {
    showSpinner = true;
  });

  GetToken getToken = GetToken(token: "${widget.token}");
  var freshToken = await getToken.getTokenData();

  try {
    Map<String, String> newHeader = {'Authorization': 'Bearer $freshToken'};

   GetUserData getUserData = GetUserData(
      '${APIConstants.API_BASE_URL}/...', newHeader);
   var userData = await getUserData.getData();
   //print(userData);
   var apiError = userData['error'];
   var apiCode = userData['code'];

   try {
     if (apiError == false && apiCode == 200) {
       final items = userData['data'].cast<Map<String, dynamic>>();
       List<Transaction> listOfTransactions = items.map<Transaction> ((json)  {
         return Transaction.fromJson(json);
       }).toList();

      setState(() {
        showSpinner = false;
      });
      //print("succes: $userData");
      return listOfTransactions;
    }
    else if(apiCode == 401){

      setState(() {
        _scaffoldKey.currentState.showSnackBar(new SnackBar(
          backgroundColor: MyColor.hintColor,
          elevation: 10,
          content: new Text(SnackBarText.TIME_OUT, style: GoogleFonts.roboto(color: Colors.white, fontSize: 20)),
        ));
        showSpinner = false;
        return MaterialPageRoute(builder: (context) => LoginScreen());
      });
    }
    else {
      //print("erreur: $userData");
      setState(() {
        _scaffoldKey.currentState.showSnackBar(new SnackBar(
          backgroundColor: MyColor.hintColor,
          elevation: 10,
          content: new Text(SnackBarText.SERVER_ERROR,
              style: GoogleFonts.roboto(color: Colors.white, fontSize: 20)),
        ));
        return showSpinner = false;
      });
    }
  } catch (e) {
    print(e);
  }
} catch (e) {
  print(e);
  print('1');
  }
}

@override
void initState() {
super.initState();
token = widget.token;
f_name = widget.f_name;
l_name = widget.l_name;
email = widget.email;
addresse = widget.addresse;
num_client = widget.num_client;
phone = widget.phone;
type_client = widget.type_client;

_getTransactionsData().then((transactionsFromServer) {
  transactions = transactionsFromServer;
  //print(transactions);
});


_animationController =
    AnimationController(vsync: this, duration: Duration(milliseconds: 500))
      ..addListener(() {
        setState(() {});
      });
_animateIcon =
    Tween<double>(begin: 1.0, end: 2.0).animate(_animationController);


}



@override
Widget build(BuildContext context) {
//FactureProvider factureProvider = Provider.of<FactureProvider>(context);
   var height = MediaQuery.of(context).size.height;
   var width = MediaQuery.of(context).size.width;
   var orientation = MediaQuery.of(context).orientation;
   bool portrait = orientation == Orientation.portrait;

  return WillPopScope(
    child: Scaffold(
      key: _scaffoldKey,
      backgroundColor: MyColor.myBackgroundColor,
      appBar: AppBar(
       automaticallyImplyLeading: false,
       centerTitle: false,
       backgroundColor: Colors.white,
       leading: new IconButton(
           padding: EdgeInsets.all(0.0),
           icon: new Icon(
             Icons.apps,
             color: MyColor.menuColor,
           ),
           onPressed: () => _scaffoldKey.currentState.openDrawer()),
         title: FittedBox(
          fit: BoxFit.fitWidth,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              //SizedBox(width: 30,),
              //ImageIcon(AssetImage('images/notification.png'), color: Colors.black,),
              Text(
                Texts.DASHBOARD,
                style: GoogleFonts.roboto(
                   color: MyColor.hintColor,
                    fontWeight: FontWeight.bold,
                   fontSize: 20),
              textAlign: TextAlign.left,
            ),
            SizedBox(
              width: portrait ? width/4.0 : width/1.5,
            ),
            GestureDetector(
                onTap: _goToProfilScreen,
                child: ImageIcon(
                  AssetImage('images/noun_avatar_1.png'),
                  color: Colors.black,
                )),
          ],
        ),
      ),
    ),
    drawer: buildDrawer,
    body: Loader(
      color: Colors.white.withOpacity(0.3),
      loadIng: showSpinner,
      child: ListView(
        shrinkWrap: true,
        physics: ClampingScrollPhysics(),
                  Row(
                    children: <Widget>[
                     
                     Conditioned(
                       cases:[
                        Case( (transactions?.length == 0 || transactions?.length == null), builder: () => Padding(
                        padding: const EdgeInsets.only(left: 10.0, top: 20.0),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: <Widget>[
                            Row(
                              children: <Widget>[
                                Text(Texts.HISTO_TRANSAC, style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.w700), textAlign: TextAlign.start,)
                              ],
                            ),
                            Padding(
                              padding: const EdgeInsets.all(20.0),
                              child: Center(child: Text(Texts.NO_TRANSAC, style: GoogleFonts.roboto(color: MyColor.hintColor, fontSize: 15),),),
                            ),
                          ],
                        ),
                      )),
                    ],
                    defaultBuilder: () => Padding(
                      padding: const EdgeInsets.only(left: 1.0, right: 1.0),
                      child: FittedBox(
                        fit: BoxFit.fitWidth,
                        child: Container(
                          width: MediaQuery.of(context).size.width/1.005,
                          child: PaginatedDataTable(
                              header: Text(Texts.HISTO_TRANSAC, style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.w700), textAlign: TextAlign.start,),
                              rowsPerPage: transactions.length <= rowsPerPAge ? transactions.length : rowsPerPAge,
                              horizontalMargin: 3.7,
                              columnSpacing: 1.8,
                              headingRowHeight: 15,
                              dataRowHeight: 30,
                              columns: [
                                DataColumn(label: Text(Texts.dATE, style: GoogleFonts.roboto(fontSize: 8, fontWeight: FontWeight.w900))),
                                DataColumn(label: Text(Texts.mONTANT_PAYE, style: GoogleFonts.roboto(fontSize: 8, fontWeight: FontWeight.w900))),
                                DataColumn(label: Text(Texts.SERVICE_TEXT, style: GoogleFonts.roboto(fontSize: 8, fontWeight: FontWeight.w900))),
                                DataColumn(label: Text(Texts.mODE_PAIEMENT, style: GoogleFonts.roboto(fontSize: 8, fontWeight: FontWeight.w900))),
                                DataColumn(label: Text(Texts.DETAILS, style: GoogleFonts.roboto(fontSize: 8, fontWeight: FontWeight.w900))),
                              ],
                              source: DTS(transactions, context, abonnementsById)
                          ),
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          )
        ],
      ),
    ),
    bottomNavigationBar: GestureDetector(
      onTap: () => showMaterialModalBottomSheet(
        context: context,
        useRootNavigator: true,
        bounce: true,
        //secondAnimation: AnimationController.unbounded(vsync: this, duration: Duration(seconds: 30)),
        enableDrag: true,
        backgroundColor: Colors.transparent,
        builder: (context, scrollController) => buildWrap(context),
      ),
      child: Container(
        color: MyColor.bottonNavColor,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            Text(
              Texts.NEW,
              style: GoogleFonts.roboto(
                  color: MyColor.hintColor,
                  fontSize: 20,
                  fontWeight: FontWeight.bold),
            ),
            SizedBox(
              height: 50,
              width: 50,
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: FloatingActionButton(
                  clipBehavior: Clip.hardEdge,
                  autofocus: true,
                  mini: true,
                  backgroundColor: MyColor.hintColor,
                  onPressed: () => showMaterialModalBottomSheet(
                    context: context,
                    useRootNavigator: true,
                    bounce: true,
                    //secondAnimation: AnimationController.unbounded(vsync: this, duration: Duration(seconds: 30)),
                    enableDrag: true,
                    backgroundColor: Colors.transparent,
                    builder: (context, scrollController) =>
                        buildWrap(context),
                  ),
                  child: AnimatedIcon(
                    icon: AnimatedIcons.event_add,
                    size: 30,
                    progress: _animateIcon,
                    ),
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    ),
    onWillPop: _onWillPop,
   );
  }
}

1 个答案:

答案 0 :(得分:1)

您可以在 PaginatedDataTable 的 onPageChanged 上添加检查器,以检查要在表格上显示的项目数是否小于默认行数。

PaginatedDataTable(
  rowsPerPage: _rowsPerPage,
  source: RowSource(),
  onPageChanged: (int? n) {
    /// value of n is the number of rows displayed so far
    setState(() {
      if (n != null) {
        debugPrint(
            'onRowsPerPageChanged $_rowsPerPage ${RowSource()._rowCount - n}');
        /// Update rowsPerPage if the remaining count is less than the default rowsPerPage
        if (RowSource()._rowCount - n < _rowsPerPage)
          _rowsPerPage = RowSource()._rowCount - n;
        /// else, restore default rowsPerPage value
        else _rowsPerPage = PaginatedDataTable.defaultRowsPerPage;
      } else
        _rowsPerPage = 0;
    });
  },
  columns: <DataColumn>[],
)

Demo

这是完整的示例。

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  /// Set default number of rows to be displayed per page
  var _rowsPerPage = PaginatedDataTable.defaultRowsPerPage;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: SafeArea(
        child: PaginatedDataTable(
          rowsPerPage: _rowsPerPage,
          source: RowSource(),
          onPageChanged: (int? n) {
            /// value of n is the number of rows displayed so far
            setState(() {
              if (n != null) {
                debugPrint(
                    'onRowsPerPageChanged $_rowsPerPage ${RowSource()._rowCount - n}');
                /// Update rowsPerPage if the remaining count is less than the default rowsPerPage
                if (RowSource()._rowCount - n < _rowsPerPage)
                  _rowsPerPage = RowSource()._rowCount - n;
                /// else, restore default rowsPerPage value
                else _rowsPerPage = PaginatedDataTable.defaultRowsPerPage;
              } else
                _rowsPerPage = 0;
            });
          },
          columns: [
            DataColumn(
              label: Text(
                'Foo',
                style: TextStyle(fontStyle: FontStyle.italic),
              ),
            ),
            DataColumn(
              label: Text(
                'Bar',
                style: TextStyle(fontStyle: FontStyle.italic),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class RowSource extends DataTableSource {
  final _rowCount = 26;

  @override
  DataRow? getRow(int index) {
    if (index < _rowCount) {
      return DataRow(cells: <DataCell>[
        DataCell(Text('Foo $index')),
        DataCell(Text('Bar $index'))
      ]);
    } else
      return null;
  }

  @override
  bool get isRowCountApproximate => true;

  @override
  int get rowCount => _rowCount;

  @override
  int get selectedRowCount => 0;
}