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 {
namespace "com.sdmm.manage"
namespace "com.sdkj.skt"
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
// compileSdkVersion 34
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
@ -47,7 +47,7 @@ android {
defaultConfig {
// 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.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion flutter.minSdkVersion

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -53,7 +53,7 @@ class InventorySearch extends StatelessWidget {
children: [
Expanded(
flex: 5,
child: TextField(
child: Obx(() => TextField(
controller: controller.searchBarTextConroller,
onChanged: (value) => doSearch(value),
decoration: InputDecoration(
@ -64,8 +64,8 @@ class InventorySearch extends StatelessWidget {
floatingLabelBehavior: FloatingLabelBehavior.always,
prefixIcon: const Icon(Icons.search),
// searchBarController有值时不显示
suffixIcon: Obx(() => controller.searchKey.value.isEmpty
? const SizedBox()
suffixIcon: controller.searchKey.value.isEmpty
? null
: IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
@ -73,11 +73,11 @@ class InventorySearch extends StatelessWidget {
controller.searchBarTextConroller.clear();
doSearch('');
},
)),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
))),
)))),
SizedBox(
width: ScreenAdaper.width(5),
),
@ -185,6 +185,7 @@ class InventorySearch extends StatelessWidget {
));
}
//
Widget buildInventoryList() {
final textStyle = TextStyle(fontSize: ScreenAdaper.height(25));
return Obx(() => SmartRefresher(
@ -199,157 +200,166 @@ class InventorySearch extends StatelessWidget {
? Center(
child: Empty(text: '暂无库存'),
)
: Table(columnWidths: {
0: MinColumnWidth(
FixedColumnWidth(80), FixedColumnWidth(80)),
1: MinColumnWidth(
FixedColumnWidth(
ScreenAdaper.screenShortDistance() / 5),
FixedColumnWidth(
ScreenAdaper.screenShortDistance() / 5)),
2: FlexColumnWidth(ScreenAdaper.screenShortDistance() / 4),
3: FlexColumnWidth(ScreenAdaper.screenShortDistance() / 4),
4: MinColumnWidth(
FixedColumnWidth(
ScreenAdaper.screenShortDistance() / 5),
FixedColumnWidth(
ScreenAdaper.screenShortDistance() / 5)),
5: MinColumnWidth(
FixedColumnWidth(
ScreenAdaper.screenShortDistance() / 6),
FixedColumnWidth(
ScreenAdaper.screenShortDistance() / 6)),
}, children: [
// table header
TableRow(
decoration: BoxDecoration(
border: Border(
bottom:
BorderSide(color: AppTheme.dividerColor))),
children: [
TableCell(
verticalAlignment:
TableCellVerticalAlignment.middle,
child: Container(
alignment: Alignment.centerLeft,
height: ScreenAdaper.height(60),
: !ScreenAdaper.isLandspace()
? buildPortraitList()
: Table(columnWidths: {
0: MinColumnWidth(
FixedColumnWidth(80), FixedColumnWidth(80)),
1: MinColumnWidth(
FixedColumnWidth(
ScreenAdaper.screenShortDistance() / 5),
FixedColumnWidth(
ScreenAdaper.screenShortDistance() / 5)),
2: FlexColumnWidth(
ScreenAdaper.screenShortDistance() / 4),
3: FlexColumnWidth(
ScreenAdaper.screenShortDistance() / 4),
4: MinColumnWidth(
FixedColumnWidth(
ScreenAdaper.screenShortDistance() / 5),
FixedColumnWidth(
ScreenAdaper.screenShortDistance() / 5)),
5: MinColumnWidth(
FixedColumnWidth(
ScreenAdaper.screenShortDistance() / 6),
FixedColumnWidth(
ScreenAdaper.screenShortDistance() / 6)),
}, children: [
// table header
TableRow(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: AppTheme.dividerColor))),
children: [
TableCell(
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(
'库存编号',
'规格',
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(
'单价',
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,
),
TableCell(
verticalAlignment:
TableCellVerticalAlignment.middle,
child: Text(
'单价',
style: listTitleTextStyle,
),
itemData: itemData),
//
buildTableCell(
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
),
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.project?.name}',
itemData.inventoryNumber!,
style: textStyle,
),
],
),
itemData: itemData),
//
buildTableCell(
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
itemData: itemData),
//
buildTableCell(
Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
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(
'${itemData.product?.name}',
itemData.product
?.productSpecification ??
'',
style: textStyle),
itemData: itemData),
//
buildTableCell(
Text(
'${double.parse('${itemData.unitPrice}')}',
style: textStyle,
),
Text(
'${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),
itemData: itemData),
//
buildTableCell(
Text(
'${itemData.quantity}${itemData.product?.unit?.label ?? ''}',
textAlign: TextAlign.right,
style: textStyle),
itemData: itemData,
alignment: Alignment.centerRight),
]);
}).toList()
])));
//
buildTableCell(
Text(
'${itemData.quantity}${itemData.product?.unit?.label ?? ''}',
textAlign: TextAlign.right,
style: textStyle),
itemData: itemData,
alignment: Alignment.centerRight),
]);
}).toList()
])));
}
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 {

File diff suppressed because it is too large Load Diff

View File

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