问题描述
我正在使用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,content: new Text(SnackBarText.SERVER_ERROR,));
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'),)),],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,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,DataColumn(label: Text(Texts.SERVICE_TEXT,DataColumn(label: Text(Texts.mODE_PAIEMENT,DataColumn(label: Text(Texts.DETAILS,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,scrollController) =>
buildWrap(context),child: AnimatedIcon(
icon: AnimatedIcons.event_add,size: 30,progress: _animateIcon,)
],onWillPop: _onWillPop,);
}
}
解决方法
您可以在 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>[],)
这是完整的示例。
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,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',],);
}
}
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;
}