书架形式的布局,可上下左右拖动(不是滚动,而是整体拖动)
1.根据数据调整后的(书架的数据源应该是:List<List<DataInfo>> expUserCellList )
class ExperienceStation extends StatefulWidget{
final int id;
ExperienceStation({this.id});
State<StatefulWidget> createState() {
// TODO: implement createState
return _ExperienceStation();
}
}
class _ExperienceStation extends State<ExperienceStation>{
String _latticeImage = PathConfig.imageLatticeCenter;
int _rowCount = 0; //行数
int _columnCount = 0; //列数
ExperienceStationDetailBean _experienceStationDetailBean;
void initState() {
// TODO: implement initState
super.initState();
_httpDetail();
}
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: CustomAppBar(
backgroundColor: Colors.white,
elevation: 0,
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back_ios),
),
iconTheme: IconThemeData(color: Color(0xff999999)),
title: Text(
'可拖动的',
style: TextStyle(color: Colors.black),
),
centerTitle: true,
),
body: _experienceStationDetailBean==null?Container():_body(),
);
}
_body(){
return Container(
color: Colors.white,
padding: EdgeInsets.only(left: 30.w,top: 35.w,right: 30.w),
margin: EdgeInsets.only(top: 15.w),
child: Column(
children: [
_goodsView(),
_addStationButton()
],
),
);
}
_goodsView(){
return Expanded(
child: Container(
margin: EdgeInsets.only(top: 40.w,bottom: 40.w),
child: InteractiveViewer(
constrained: false,
scaleEnabled: false,
child: Table(
columnWidths: <int, TableColumnWidth>{
for (int column = 0; column < _columnCount; column += 1)
column: const FixedColumnWidth(80),
},
children: buildRows(_rowCount, _columnCount),
),
),
)
);
}
List<TableRow> buildRows(int rowCount, int columnCount) {
return [
for (int row = 0; row < rowCount; row += 1)
TableRow(
children: [
for (int column = 0; column < columnCount; column ++)
InkWell(
child: Container(
height: 160.w,
decoration: BoxDecoration(
//color: _colorful(row,column),
image:DecorationImage(
image: AssetImage(_setLatticeImage(row,column)),
fit: BoxFit.fill, // 完全填充
),
),
child: Stack(
children: [
_experienceStationDetailBean.expUserCellList[row][column].expUserCellId == null
&& _experienceStationDetailBean.expUserCellList[row][column].cellPublishStatus == 1
?GestureDetector(
child: Center(
child: Container(
margin: EdgeInsets.only(top: row==0 ?30.w : row==_experienceStationDetailBean.expUserCellList.length-1?0: 20.w),
width: 80.w,
height: 80.w,
child: Image.asset(PathConfig.imageCircularAdd),
),
),
onTap: (){
NavigatorUtil.push(ExperienceStationCaption(id: widget.id));
},
):
Container(
alignment: Alignment.center,
child: Container(
margin: EdgeInsets.only(top: row==0 ?30.w : row==_experienceStationDetailBean.expUserCellList.length-1?0: 20.w),
width: 80.w,
height: 80.w,
child: Utils().roundedImage(_experienceStationDetailBean.expUserCellList[row][column].userCellPic??'', 4),
)
),
Container(
width: 35.w,
height: 35.w,
alignment: Alignment.center,
margin: EdgeInsets.only(top: 10.w,left: 10.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(2),
color: JadeColors.translucent
),
child: Text('${_experienceStationDetailBean.expUserCellList[row][column].num}',style: TextStyle(color: Colors.white,fontSize: setFontSize(18)),),
)
],
),
),
onTap: (){
if(_experienceStationDetailBean.expUserCellList[row][column].expUserCellId != null){
NavigatorUtil.push(ExperienceStationDetail(id: _experienceStationDetailBean.expUserCellList[row][column].expUserCellId,expId: widget.id,));
}
},
)
],
),
];
}
String _setLatticeImage(row,column){
if(row == 0 && column == 0){
//左上角
_latticeImage = PathConfig.imageLatticeTopLeft;
}else if(row == 0 && column == _columnCount-1){
//右上角
_latticeImage = PathConfig.imageLatticeTopRight;
}else if(row == _rowCount -1 && column == 0){
//左下角
_latticeImage = PathConfig.imageLatticeBottomLeft;
}else if(row == _rowCount -1 && column == _columnCount-1){
//右下角
_latticeImage = PathConfig.imageLatticeBottomRight;
}else if(column==0){
_latticeImage = PathConfig.imageLatticeSecondLeft;
}else if(column==_columnCount-1){
_latticeImage = PathConfig.imageLatticeSecondRight;
}else if(row == _rowCount -1){
_latticeImage = PathConfig.imageLatticeSecondBottom;
}else {
_latticeImage = PathConfig.imageLatticeCenter;
}
return _latticeImage;
}
final colors = [Colors.red,Colors.yellow,Colors.blue,Colors.green];
final colors2 = [Colors.yellow,Colors.blue,Colors.green,Colors.red];
_colorful(int row, int column ) => row % 2==0?colors[column]:colors2[column];
_addStationButton(){
return InkWell(
child: Container(
width: Utils().screenWidth(context)/2,
margin: EdgeInsets.only(bottom: 40.h),
alignment: Alignment.center,
height: 78.w,
decoration: BoxDecoration(
color: JadeColors.blue_2,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(color: JadeColors.grey_4,blurRadius: 5.0,offset: Offset(0, 4),)
]
),
child: Text('加入体验站',style: TextStyle(color: Colors.white,fontSize: setFontSize(34)),),
),
onTap: (){
NavigatorUtil.push(ExperienceStationCaption(id: widget.id));
},
);
}
_httpDetail(){
WidgetsBinding.instance.addPostFrameCallback((_){
Loading.showLoading(context);
});
HttpApplication.getInstance().experienceStationLattices(widget.id,
callBack: (result){
Loading.hideLoading(context);
if(result != null){
if(mounted){
_experienceStationDetailBean = ExperienceStationDetailBean.fromJson(result);
_rowCount = _experienceStationDetailBean.rowNum;
_columnCount = _experienceStationDetailBean.columnNum;
setState(() {});
}
}
},
errorCallBack: (error){
Loading.hideLoading(context);
});
}
}
实体类
class ExperienceStationDetailBean {
int rowNum;
int columnNum;
List<List<ExpUserCellList>> expUserCellList;
ExperienceStationDetailBean({
this.rowNum,
this.columnNum,
this.expUserCellList,
});
ExperienceStationDetailBean.fromJson(dynamic json) {
rowNum = json['rowNum'];
columnNum = json['columnNum'];
if (json['expUserCellList'] != null) {
expUserCellList = [];
json['expUserCellList'].forEach((v) {
List<ExpUserCellList> dataList = [];
v.forEach((k){
dataList.add(ExpUserCellList.fromJson(k));
});
expUserCellList.add(dataList);
});
}
}
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['rowNum'] = rowNum;
map['columnNum'] = columnNum;
if (expUserCellList != null) {
map['expUserCellList'] = expUserCellList.map((v) => v.map((e) => e.toJson())).toList();
}
return map;
}
}
2.无数据源时
import 'package:flutter/material.dart';
class InteractiveViewerDemo2 extends StatelessWidget {
Widget build(BuildContext context) {
const int _rowCount = 20;
const int _columnCount = 4;
return Scaffold(
body: Center(
child: Container(
width: 300,
height: 200,
child: InteractiveViewer(
constrained: false,
scaleEnabled: false,
child: Table(
columnWidths: <int, TableColumnWidth>{
for (int column = 0; column < _columnCount; column += 1)
column: const FixedColumnWidth(150.0),
},
children: buildRows(_rowCount, _columnCount),
),
),
),
),
);
}
List<TableRow> buildRows(int rowCount, int columnCount) {
return [
for (int row = 0; row < rowCount; row += 1)
TableRow(
children: [
for (int column = 0; column < columnCount; column += 1)
Container(
margin: EdgeInsets.all(2),
height: 50,
alignment: Alignment.center,
color: _colorful(row,column),
child: Text('($row,$column)',style: TextStyle(fontSize: 20,color: Colors.white),),
),
],
),
];
}
final colors = [Colors.red,Colors.yellow,Colors.blue,Colors.green];
final colors2 = [Colors.indigo,Colors.red,Colors.green,Colors.blueGrey];
_colorful(int row, int column ) => row % 2==0?colors[column]:colors2[column];
}