opti: responsive UI

This commit is contained in:
louis 2024-03-29 17:16:09 +08:00
parent f471cf085b
commit 89e7a575a8
12 changed files with 417 additions and 391 deletions

View File

@ -28,10 +28,10 @@ if (flutterVersionName == null) {
} }
android { android {
namespace "com.sdmm.manage" namespace "com.sdkj.skt"
compileSdkVersion flutter.compileSdkVersion compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion ndkVersion flutter.ndkVersion
// compileSdkVersion 34
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
@ -47,7 +47,7 @@ android {
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.sdmm.manage" applicationId "com.sdkj.skt"
// You can update the following values to match your application needs. // You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion flutter.minSdkVersion minSdkVersion flutter.minSdkVersion

View File

@ -1,4 +1,4 @@
package com.sdmm.manage package com.sdkj.skt
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterActivity

View File

@ -4,6 +4,6 @@
<bitmap android:gravity="fill" android:src="@drawable/background"/> <bitmap android:gravity="fill" android:src="@drawable/background"/>
</item> </item>
<item> <item>
<bitmap android:gravity="scaleAspectFill" android:src="@drawable/splash"/> <bitmap android:gravity="center" android:src="@drawable/splash"/>
</item> </item>
</layer-list> </layer-list>

View File

@ -4,6 +4,6 @@
<bitmap android:gravity="fill" android:src="@drawable/background"/> <bitmap android:gravity="fill" android:src="@drawable/background"/>
</item> </item>
<item> <item>
<bitmap android:gravity="scaleAspectFill" android:src="@drawable/splash"/> <bitmap android:gravity="center" android:src="@drawable/splash"/>
</item> </item>
</layer-list> </layer-list>

View File

@ -4,6 +4,6 @@
<bitmap android:gravity="fill" android:src="@drawable/background"/> <bitmap android:gravity="fill" android:src="@drawable/background"/>
</item> </item>
<item> <item>
<bitmap android:gravity="scaleAspectFill" android:src="@drawable/splash"/> <bitmap android:gravity="center" android:src="@drawable/splash"/>
</item> </item>
</layer-list> </layer-list>

View File

@ -4,6 +4,6 @@
<bitmap android:gravity="fill" android:src="@drawable/background"/> <bitmap android:gravity="fill" android:src="@drawable/background"/>
</item> </item>
<item> <item>
<bitmap android:gravity="scaleAspectFill" android:src="@drawable/splash"/> <bitmap android:gravity="center" android:src="@drawable/splash"/>
</item> </item>
</layer-list> </layer-list>

View File

@ -21,40 +21,49 @@ class InventoryInoutCard extends StatelessWidget {
controller controller
.showInventoryInoutInfoDialog(controller.list[ind][index].id!); .showInventoryInoutInfoDialog(controller.list[ind][index].id!);
}, },
child: Container( child: Stack(
margin: EdgeInsets.symmetric( children: [
vertical: ScreenAdaper.height(10), Container(
horizontal: ScreenAdaper.width(10)), margin: EdgeInsets.symmetric(
padding: EdgeInsets.symmetric( vertical: ScreenAdaper.height(10),
horizontal: ScreenAdaper.width(defaultPadding), horizontal: ScreenAdaper.width(10)),
vertical: ScreenAdaper.height(defaultPadding)), padding: EdgeInsets.symmetric(
decoration: BoxDecoration( horizontal: ScreenAdaper.width(defaultPadding),
boxShadow: [ vertical: ScreenAdaper.height(defaultPadding)),
BoxShadow( decoration: BoxDecoration(
color: AppTheme.barrierColor.withOpacity(0.2), boxShadow: [
offset: Offset(0, ScreenAdaper.height(5)), BoxShadow(
blurRadius: ScreenAdaper.sp(10)), color: AppTheme.barrierColor.withOpacity(0.2),
], offset: Offset(0, ScreenAdaper.height(5)),
color: AppTheme.nearlyWhite, blurRadius: ScreenAdaper.sp(10)),
borderRadius: BorderRadius.circular(ScreenAdaper.sp(30))), ],
child: Row( color: AppTheme.nearlyWhite,
crossAxisAlignment: CrossAxisAlignment.center, borderRadius: BorderRadius.circular(ScreenAdaper.sp(30))),
children: [ child: Row(
buildImage(), crossAxisAlignment: CrossAxisAlignment.start,
Expanded(child: buildContent()), children: [
], buildImage(),
), Expanded(child: buildContent()),
],
),
),
Positioned(
child: buildInOrOut(),
right: ScreenAdaper.width(5),
top: ScreenAdaper.height(5),
)
],
), ),
); );
} }
Widget buildContent() { Widget buildContent() {
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
@ -65,16 +74,12 @@ class InventoryInoutCard extends StatelessWidget {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: ScreenAdaper.height(25)), fontSize: ScreenAdaper.height(25)),
)), )),
buildInOrOut()
], ],
), ),
// Spacer(),
Text( Text(
controller.list[ind][index].product?.company?.name ?? '-', controller.list[ind][index].product?.company?.name ?? '-',
style: TextStyle( style: TextStyle(
color: AppTheme.grey, color: AppTheme.grey, fontSize: ScreenAdaper.height(20)),
fontWeight: FontWeight.bold,
fontSize: ScreenAdaper.height(20)),
), ),
SizedBox( SizedBox(
height: ScreenAdaper.height(5), height: ScreenAdaper.height(5),
@ -85,14 +90,13 @@ class InventoryInoutCard extends StatelessWidget {
child: Text( child: Text(
'${controller.list[ind][index].project?.name}', '${controller.list[ind][index].project?.name}',
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w600, color: AppTheme.grey, fontSize: ScreenAdaper.height(20)),
fontSize: ScreenAdaper.height(20)),
), ),
), ),
], ],
), ),
SizedBox( SizedBox(
height: ScreenAdaper.height(5), height: ScreenAdaper.height(20),
), ),
Row( Row(
children: [ children: [
@ -100,15 +104,15 @@ class InventoryInoutCard extends StatelessWidget {
child: Text( child: Text(
'${controller.list[ind][index].quantity} ${controller.list[ind][index].product?.unit?.label ?? '-'}', '${controller.list[ind][index].quantity} ${controller.list[ind][index].product?.unit?.label ?? '-'}',
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w600, fontSize: ScreenAdaper.height(20),
fontSize: ScreenAdaper.height(20)), fontWeight: FontWeight.w600),
), ),
), ),
Text( Text(
controller.list[ind][index].agent ?? '-', controller.list[ind][index].agent ?? '-',
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w600, fontSize: ScreenAdaper.height(20),
fontSize: ScreenAdaper.height(20)), fontWeight: FontWeight.w600),
), ),
], ],
) )
@ -118,12 +122,12 @@ class InventoryInoutCard extends StatelessWidget {
Widget buildImage() { Widget buildImage() {
return Container( return Container(
margin: EdgeInsets.only(right: ScreenAdaper.width(defaultPadding) / 2), margin: EdgeInsets.only(right: ScreenAdaper.width(defaultPadding)),
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(ScreenAdaper.sp(15)), borderRadius: BorderRadius.circular(ScreenAdaper.sp(15)),
child: FadeInCacheImage( child: FadeInCacheImage(
width: ScreenAdaper.height(100), width: ScreenAdaper.height(150),
height: ScreenAdaper.height(100), height: ScreenAdaper.height(150),
url: controller.list[ind][index].files.isNotEmpty url: controller.list[ind][index].files.isNotEmpty
? '${GloablConfig.OSS_URL}${controller.list[ind][index].files[0].path}' ? '${GloablConfig.OSS_URL}${controller.list[ind][index].files[0].path}'
: ''), : ''),

View File

@ -11,9 +11,6 @@ class InventoryInoutView extends StatelessWidget {
return PageView( return PageView(
physics: const BouncingScrollPhysics(), physics: const BouncingScrollPhysics(),
reverse: true, reverse: true,
onPageChanged: (index) {
controller.setIndex(index);
},
controller: controller.pageController, controller: controller.pageController,
children: List.generate( children: List.generate(
controller.daysNum, controller.daysNum,

View File

@ -174,7 +174,7 @@ class LoginScreen extends StatelessWidget {
Widget buildUserNameInput() { Widget buildUserNameInput() {
return TextFormField( return TextFormField(
// //
// keyboardType: TextInputType.url, obscureText: true,
decoration: InputDecoration( decoration: InputDecoration(
prefixIcon: Icon( prefixIcon: Icon(
Icons.person_2_outlined, Icons.person_2_outlined,
@ -187,7 +187,6 @@ class LoginScreen extends StatelessWidget {
onFieldSubmitted: (value) { onFieldSubmitted: (value) {
_controller.passwordFocusNode.requestFocus(); _controller.passwordFocusNode.requestFocus();
}, },
autovalidateMode: AutovalidateMode.onUserInteraction,
style: TextStyle(fontSize: ScreenAdaper.height(25)), style: TextStyle(fontSize: ScreenAdaper.height(25)),
onChanged: (value) { onChanged: (value) {
_controller.username = value; _controller.username = value;
@ -203,9 +202,6 @@ class LoginScreen extends StatelessWidget {
size: ScreenAdaper.height(40), size: ScreenAdaper.height(40),
), ),
errorStyle: TextStyle(fontSize: ScreenAdaper.height(20)), errorStyle: TextStyle(fontSize: ScreenAdaper.height(20)),
contentPadding: EdgeInsets.symmetric(
horizontal: ScreenAdaper.width(30),
vertical: ScreenAdaper.height(10)),
hintText: '密码', hintText: '密码',
border: InputBorder.none, border: InputBorder.none,
focusedBorder: InputBorder.none), focusedBorder: InputBorder.none),
@ -218,7 +214,6 @@ class LoginScreen extends StatelessWidget {
onChanged: (value) { onChanged: (value) {
_controller.password = value; _controller.password = value;
}, },
autovalidateMode: AutovalidateMode.onUserInteraction,
); );
} }

View File

@ -53,7 +53,7 @@ class InventorySearch extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
flex: 5, flex: 5,
child: TextField( child: Obx(() => TextField(
controller: controller.searchBarTextConroller, controller: controller.searchBarTextConroller,
onChanged: (value) => doSearch(value), onChanged: (value) => doSearch(value),
decoration: InputDecoration( decoration: InputDecoration(
@ -64,8 +64,8 @@ class InventorySearch extends StatelessWidget {
floatingLabelBehavior: FloatingLabelBehavior.always, floatingLabelBehavior: FloatingLabelBehavior.always,
prefixIcon: const Icon(Icons.search), prefixIcon: const Icon(Icons.search),
// searchBarController有值时不显示 // searchBarController有值时不显示
suffixIcon: Obx(() => controller.searchKey.value.isEmpty suffixIcon: controller.searchKey.value.isEmpty
? const SizedBox() ? null
: IconButton( : IconButton(
icon: const Icon(Icons.clear), icon: const Icon(Icons.clear),
onPressed: () { onPressed: () {
@ -73,11 +73,11 @@ class InventorySearch extends StatelessWidget {
controller.searchBarTextConroller.clear(); controller.searchBarTextConroller.clear();
doSearch(''); doSearch('');
}, },
)), ),
border: OutlineInputBorder( border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
), ),
))), )))),
SizedBox( SizedBox(
width: ScreenAdaper.width(5), width: ScreenAdaper.width(5),
), ),
@ -185,6 +185,7 @@ class InventorySearch extends StatelessWidget {
)); ));
} }
//
Widget buildInventoryList() { Widget buildInventoryList() {
final textStyle = TextStyle(fontSize: ScreenAdaper.height(25)); final textStyle = TextStyle(fontSize: ScreenAdaper.height(25));
return Obx(() => SmartRefresher( return Obx(() => SmartRefresher(
@ -199,157 +200,166 @@ class InventorySearch extends StatelessWidget {
? Center( ? Center(
child: Empty(text: '暂无库存'), child: Empty(text: '暂无库存'),
) )
: Table(columnWidths: { : !ScreenAdaper.isLandspace()
0: MinColumnWidth( ? buildPortraitList()
FixedColumnWidth(80), FixedColumnWidth(80)), : Table(columnWidths: {
1: MinColumnWidth( 0: MinColumnWidth(
FixedColumnWidth( FixedColumnWidth(80), FixedColumnWidth(80)),
ScreenAdaper.screenShortDistance() / 5), 1: MinColumnWidth(
FixedColumnWidth( FixedColumnWidth(
ScreenAdaper.screenShortDistance() / 5)), ScreenAdaper.screenShortDistance() / 5),
2: FlexColumnWidth(ScreenAdaper.screenShortDistance() / 4), FixedColumnWidth(
3: FlexColumnWidth(ScreenAdaper.screenShortDistance() / 4), ScreenAdaper.screenShortDistance() / 5)),
4: MinColumnWidth( 2: FlexColumnWidth(
FixedColumnWidth( ScreenAdaper.screenShortDistance() / 4),
ScreenAdaper.screenShortDistance() / 5), 3: FlexColumnWidth(
FixedColumnWidth( ScreenAdaper.screenShortDistance() / 4),
ScreenAdaper.screenShortDistance() / 5)), 4: MinColumnWidth(
5: MinColumnWidth( FixedColumnWidth(
FixedColumnWidth( ScreenAdaper.screenShortDistance() / 5),
ScreenAdaper.screenShortDistance() / 6), FixedColumnWidth(
FixedColumnWidth( ScreenAdaper.screenShortDistance() / 5)),
ScreenAdaper.screenShortDistance() / 6)), 5: MinColumnWidth(
}, children: [ FixedColumnWidth(
// table header ScreenAdaper.screenShortDistance() / 6),
TableRow( FixedColumnWidth(
decoration: BoxDecoration( ScreenAdaper.screenShortDistance() / 6)),
border: Border( }, children: [
bottom: // table header
BorderSide(color: AppTheme.dividerColor))), TableRow(
children: [ decoration: BoxDecoration(
TableCell( border: Border(
verticalAlignment: bottom: BorderSide(
TableCellVerticalAlignment.middle, color: AppTheme.dividerColor))),
child: Container( children: [
alignment: Alignment.centerLeft, TableCell(
height: ScreenAdaper.height(60), verticalAlignment:
TableCellVerticalAlignment.middle,
child: Container(
alignment: Alignment.centerLeft,
height: ScreenAdaper.height(60),
child: Text(
'库存编号',
style: listTitleTextStyle,
),
)),
TableCell(
verticalAlignment:
TableCellVerticalAlignment.middle,
child: Text(
'所属项目',
style: listTitleTextStyle,
)),
TableCell(
verticalAlignment:
TableCellVerticalAlignment.middle,
child: Text(
'产品名称',
style: listTitleTextStyle,
)),
TableCell(
verticalAlignment:
TableCellVerticalAlignment.middle,
child: Text( child: Text(
'库存编号', '规格',
style: listTitleTextStyle, style: listTitleTextStyle,
), ),
)), ),
TableCell( TableCell(
verticalAlignment: verticalAlignment:
TableCellVerticalAlignment.middle, TableCellVerticalAlignment.middle,
child: Text( child: Text(
'所属项目', '单价',
style: listTitleTextStyle, style: listTitleTextStyle,
)),
TableCell(
verticalAlignment:
TableCellVerticalAlignment.middle,
child: Text(
'产品名称',
style: listTitleTextStyle,
)),
TableCell(
verticalAlignment:
TableCellVerticalAlignment.middle,
child: Text(
'规格',
style: listTitleTextStyle,
),
),
TableCell(
verticalAlignment:
TableCellVerticalAlignment.middle,
child: Text(
'单价',
style: listTitleTextStyle,
),
),
TableCell(
verticalAlignment:
TableCellVerticalAlignment.middle,
child: Text(
'数量',
textAlign: TextAlign.right,
style: listTitleTextStyle,
),
),
]),
...controller.inventories.map((itemData) {
return TableRow(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: AppTheme.dividerColor))),
children: [
buildTableCell(
Text(
itemData.inventoryNumber!,
style: textStyle,
), ),
itemData: itemData), ),
TableCell(
// verticalAlignment:
buildTableCell( TableCellVerticalAlignment.middle,
Column( child: Text(
mainAxisAlignment: MainAxisAlignment.center, '数量',
crossAxisAlignment: CrossAxisAlignment.start, textAlign: TextAlign.right,
children: [ style: listTitleTextStyle,
),
),
]),
...controller.inventories.map((itemData) {
return TableRow(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: AppTheme.dividerColor))),
children: [
buildTableCell(
Text( Text(
'${itemData.project?.name}', itemData.inventoryNumber!,
style: textStyle, style: textStyle,
), ),
], itemData: itemData),
),
itemData: itemData), //
// buildTableCell(
buildTableCell( Column(
Column( mainAxisAlignment:
mainAxisAlignment: MainAxisAlignment.center, MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment:
children: [ CrossAxisAlignment.start,
children: [
Text(
'${itemData.project?.name}',
style: textStyle,
),
],
),
itemData: itemData),
//
buildTableCell(
Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'${itemData.product?.name}',
style: textStyle,
),
Text(
'${itemData.product?.company?.name}',
style: TextStyle(
fontSize: ScreenAdaper.height(15),
color: AppTheme.grey),
)
],
),
itemData: itemData),
//
buildTableCell(
Text( Text(
'${itemData.product?.name}', itemData.product
?.productSpecification ??
'',
style: textStyle),
itemData: itemData),
//
buildTableCell(
Text(
'${double.parse('${itemData.unitPrice}')}',
style: textStyle, style: textStyle,
), ),
Text( itemData: itemData),
'${itemData.product?.company?.name}',
style: TextStyle(
fontSize: ScreenAdaper.height(15),
color: AppTheme.grey),
)
],
),
itemData: itemData),
//
buildTableCell(
Text(
itemData.product?.productSpecification ??
'',
style: textStyle),
itemData: itemData),
//
buildTableCell(
Text(
'${double.parse('${itemData.unitPrice}')}',
style: textStyle,
),
itemData: itemData),
// //
buildTableCell( buildTableCell(
Text( Text(
'${itemData.quantity}${itemData.product?.unit?.label ?? ''}', '${itemData.quantity}${itemData.product?.unit?.label ?? ''}',
textAlign: TextAlign.right, textAlign: TextAlign.right,
style: textStyle), style: textStyle),
itemData: itemData, itemData: itemData,
alignment: Alignment.centerRight), alignment: Alignment.centerRight),
]); ]);
}).toList() }).toList()
]))); ])));
} }
Widget buildTableCell(Widget child, Widget buildTableCell(Widget child,
@ -373,6 +383,60 @@ class InventorySearch extends StatelessWidget {
), ),
); );
} }
Widget buildPortraitList() {
return ListView.separated(
itemBuilder: (_, index) {
final itemData = controller.inventories[index];
return InkWell(
onTap: () {
if (beforeSelectedCheck != null) {
if (!beforeSelectedCheck!(itemData)) {
return;
}
}
if (onInventorySelected != null) onInventorySelected!(itemData);
},
child: Container(
child: Row(children: [
Text(
'${itemData.inventoryNumber}',
style: TextStyle(fontSize: ScreenAdaper.sp(40)),
),
SizedBox(
width: ScreenAdaper.width(10),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${itemData.product?.name}${itemData.product?.productSpecification != '' ? '(${itemData.product?.productSpecification})' : ''}',
style: TextStyle(fontSize: ScreenAdaper.sp(40)),
),
Text(
'${itemData.product?.company?.name}',
style: TextStyle(
fontSize: ScreenAdaper.sp(30),
color: AppTheme.grey),
),
Text('${double.parse('${itemData.unitPrice}')}',
style: TextStyle(
fontSize: ScreenAdaper.sp(30),
color: AppTheme.grey))
],
),
Spacer(),
Text(
'${itemData.quantity}${itemData.product?.unit?.label ?? ''}',
style: TextStyle(fontSize: ScreenAdaper.sp(40))),
]),
));
},
separatorBuilder: (_, index) => Divider(
color: AppTheme.dividerColor,
),
itemCount: controller.inventories.length);
}
} }
class InventorySearchController extends GetxController { class InventorySearchController extends GetxController {

File diff suppressed because it is too large Load Diff

View File

@ -84,11 +84,9 @@ flutter_native_splash:
android: true android: true
ios: true ios: true
web: false web: false
android_gravity: scaleAspectFill
android_12: android_12:
image: assets/images/launch_image.jpg image: assets/images/launch_image.jpg
icon_background_color: '#ffffff' icon_background_color: '#ffffff'
android_gravity: scaleAspectFill
ios_content_mode: scaleAspectFill ios_content_mode: scaleAspectFill
flutter_launcher_icons: flutter_launcher_icons: