-
Notifications
You must be signed in to change notification settings - Fork 168
Open
Description
tdesign-flutter 版本
0.2.7
重现链接
SVID_20260203_093548_1.mp4
重现步骤/代码
screen页面
class BookFormScreen extends GetView<BookFormController> {
const BookFormScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: TDNavBar(
title: "添加数据",
onBack: () {
Get.back();
},
),
body: Obx(
() => Container(
padding: EdgeInsets.all(16),
child: Column(
spacing: 16,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildTitle(context),
_buildSourceSelection(context),
_buildForm(context),
_buildActionButton(context),
],
),
),
),
);
}
Widget _buildTitle(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TDText("选择导入源"),
TDText(
"请选择您想要导入书籍的来源方式",
textColor: TDTheme.of(context).fontGyColor3,
font: TDTheme.of(context).fontBodySmall,
),
],
);
}
Widget _buildSourceSelection(BuildContext context) {
return Expanded(
child: SingleChildScrollView(
child: Column(
children: [
_addDialogItem(
context: context,
icon: Icons.web,
title: "来自网页",
isSelected: controller.source.value == BookFormSources.web,
description: "从网页解析后,下载书籍到本地",
onTap: () {
controller.source.value = BookFormSources.web;
},
),
_addDialogItem(
context: context,
icon: Icons.archive,
title: "来自压缩包",
isSelected: controller.source.value == BookFormSources.archive,
description: "从压缩包中提取书籍到本地",
onTap: () {
controller.source.value = BookFormSources.archive;
},
),
_addDialogItem(
context: context,
icon: Icons.archive_sharp,
title: "来自批量压缩包",
isSelected:
controller.source.value == BookFormSources.batchArchive,
description: "选择文件夹,从文件夹里面多个压缩包中提取书籍到本地",
onTap: () {
controller.source.value = BookFormSources.batchArchive;
},
),
_addDialogItem(
context: context,
icon: Icons.picture_as_pdf,
title: "来自PDF文件",
isSelected: controller.source.value == BookFormSources.pdf,
description: "从PDF文件中提取书籍到本地",
onTap: () {
controller.source.value = BookFormSources.pdf;
},
),
],
),
),
);
}
Widget _buildForm(BuildContext context) {
switch (controller.source.value) {
case BookFormSources.web:
return TDInput(
controller: controller.webUrlController,
hintText: "请输入书籍网址",
);
case BookFormSources.archive:
return TDInput(
controller: controller.filePathController,
hintText: "请选择压缩包文件",
readOnly: true,
rightBtn: TDButton(
text: "选择文件",
theme: TDButtonTheme.primary,
onTap: () {
controller.pickArchiveFile();
},
),
);
case BookFormSources.batchArchive:
return TDInput(
controller: controller.folderPathController,
hintText: "请选择包含压缩包的文件夹",
readOnly: true,
rightBtn: TDButton(
text: "选择文件夹",
theme: TDButtonTheme.primary,
onTap: () {
controller.pickFolder();
},
),
);
case BookFormSources.pdf:
return TDInput(
controller: controller.pdfPathController,
hintText: "请选择PDF文件",
readOnly: true,
rightBtn: TDButton(
text: "选择文件",
theme: TDButtonTheme.primary,
onTap: () {
controller.pickPdf();
},
),
);
default:
return SizedBox.shrink();
}
}
Widget _buildActionButton(BuildContext context) {
return TDButton(
text: "添加书籍",
width: double.infinity,
theme: TDButtonTheme.primary,
onTap: () {
controller.submitForm();
},
);
}
Widget _addDialogItem({
required BuildContext context,
required IconData icon,
required String title,
required String description,
required bool isSelected,
required VoidCallback onTap,
}) {
return Material(
color: Colors.transparent,
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(8),
hoverColor: TDTheme.of(context).fontGyColor4.withValues(alpha: 0.05),
splashColor: TDTheme.of(
context,
).brandNormalColor.withValues(alpha: 0.1),
highlightColor: TDTheme.of(
context,
).brandNormalColor.withValues(alpha: 0.05),
child: Container(
decoration: BoxDecoration(
color: isSelected
? TDTheme.of(context).fontGyColor4.withValues(alpha: 0.1)
: Colors.transparent,
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: isSelected
? TDTheme.of(context).fontGyColor4
: Colors.transparent,
),
),
padding: EdgeInsets.all(16),
child: Row(
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: TDTheme.of(
context,
).fontGyColor4.withValues(alpha: 0.1),
),
padding: EdgeInsets.all(16),
child: Icon(icon),
),
SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TDText(title),
TDText(
description,
overflow: TextOverflow.clip,
textColor: TDTheme.of(context).fontGyColor3,
font: TDTheme.of(context).fontBodySmall,
),
],
),
),
],
),
),
),
);
}
}
controller控制器
class BookFormController extends GetxController {
final source = Rxn<BookFormSources>(null);
final submitFormState = Rx<RequestState<void>>(Idle());
final webUrlController = TextEditingController();
final filePathController = TextEditingController();
final folderPathController = TextEditingController();
final pdfPathController = TextEditingController();
Future<void> submitForm() async {
final sourceValue = source.value;
if (sourceValue?.value == null) {
ToastService.showError("请选择书籍来源");
return;
}
if (sourceValue == BookFormSources.web) {
final url = webUrlController.text;
if (url.toString().trim().isEmpty) {
ToastService.showError("请输入网页地址");
return;
}
// 然后打开解析页面
Get.offAndToNamed(AppRoute.parseWeb, arguments: url.toString());
}
if (sourceValue == BookFormSources.archive) {
final file = filePathController.text;
if (file.toString().trim().isEmpty) {
ToastService.showError("请选择压缩包文件");
return;
}
Get.offAndToNamed(
AppRoute.parseArchiveSingle,
arguments: file.toString(),
);
}
if (sourceValue == BookFormSources.batchArchive) {
final folder = folderPathController.text;
if (folder.toString().trim().isEmpty) {
ToastService.showError("请选择压缩包文件夹");
return;
}
Get.offAndToNamed(
AppRoute.parseArchiveBatch,
arguments: folder.toString(),
);
}
if (sourceValue == BookFormSources.pdf) {
final pdf = pdfPathController.text;
if (pdf.toString().trim().isEmpty) {
ToastService.showError("请选择PDF文件");
return;
}
Get.offAndToNamed(AppRoute.parsePdf, arguments: {'path': pdf.toString()});
}
}
Future<void> pickArchiveFile() async {
final result = await PickFileUtil.pickerFile(
type: FileType.custom,
allowedExtensions: ['zip', 'rar', '7z', 'cbz', 'cbr'],
);
if (result != null && result.files.isNotEmpty) {
final filePath = result.files.first.path;
if (filePath != null) {
filePathController.text = filePath;
}
}
}
Future<void> pickFolder() async {
final folderPath = await PickFileUtil.pickDirectory();
if (folderPath != null) {
folderPathController.text = folderPath;
}
}
Future<void> pickPdf() async {
final path = await PdfPicker.pickPdf();
if (path != null) {
pdfPathController.text = path;
}
}
}
enum BookFormSources {
web("web", "网页"),
archive("archive", "压缩包"),
batchArchive("batch_archive", "批量压缩包"),
pdf("pdf", "PDF");
final String value;
final String desc;
const BookFormSources(this.value, this.desc);
}
具体重现方法查看视频和代码,当我页面组件在消失并重现后,rightbuttom会消失,重复操作后又会出现,但设置了clearable为false时候不会出现
期望结果
页面重组后rightbutton属性里面的组件不会消失
实际结果
页面重组后rightbutton属性里面的组件会消失
Flutter版本
3.38.7
设备与机型信息
pixel6
系统版本
android 15
补充说明
No response
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels