17 changed files with 511 additions and 181 deletions
@ -0,0 +1,9 @@ |
|||
import 'package:get/get.dart'; |
|||
import '../controllers/timbre_controller.dart'; |
|||
|
|||
class TimbreBinding extends Bindings { |
|||
@override |
|||
void dependencies() { |
|||
Get.put<TimbreController>(TimbreController()); |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
import 'package:get/get.dart'; |
|||
|
|||
class TimbreController extends GetxController { |
|||
RxList dataList = [ |
|||
{'type': '1', 'name': '默认音色', 'description': '微软云端音色服务'}, |
|||
{'type': '2', 'name': '声音复刻', 'description': '复刻本人音色服务'} |
|||
].obs; |
|||
RxString type = '1'.obs; |
|||
|
|||
@override |
|||
void onInit() { |
|||
super.onInit(); |
|||
} |
|||
} |
|||
@ -0,0 +1,168 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
|||
import 'package:get/get.dart'; |
|||
import '../../../core/theme/app_colors.dart'; |
|||
import '../controllers/timbre_controller.dart'; |
|||
|
|||
class TimbreView extends GetView<TimbreController> { |
|||
const TimbreView({Key? key}) : super(key: key); |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
final isDarkMode = Theme.of(context).brightness == Brightness.dark; |
|||
|
|||
return Scaffold( |
|||
backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], |
|||
appBar: _buildAppBar(isDarkMode), |
|||
body: _buildBody(isDarkMode), |
|||
); |
|||
} |
|||
|
|||
// 构建应用栏 |
|||
PreferredSizeWidget _buildAppBar(bool isDarkMode) { |
|||
return AppBar( |
|||
backgroundColor: isDarkMode ? Colors.black : Colors.white, |
|||
elevation: 0.5, |
|||
leading: IconButton( |
|||
icon: Icon( |
|||
Icons.arrow_back_ios, |
|||
color: isDarkMode ? Colors.white : Colors.black, |
|||
size: 20.sp, |
|||
), |
|||
onPressed: () => Get.back(), |
|||
), |
|||
title: Text( |
|||
'选择音色', |
|||
style: TextStyle( |
|||
fontSize: 17.sp, |
|||
fontWeight: FontWeight.w600, |
|||
color: isDarkMode ? Colors.white : Colors.black, |
|||
), |
|||
), |
|||
centerTitle: true, |
|||
); |
|||
} |
|||
|
|||
// 构建主体内容 |
|||
Widget _buildBody(bool isDarkMode) { |
|||
return Column( |
|||
children: [ |
|||
Expanded( |
|||
child: Obx( |
|||
() => ListView.builder( |
|||
itemCount: controller.dataList.length, |
|||
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 5.w), |
|||
itemBuilder: (BuildContext context, int index) { |
|||
Map data = controller.dataList[index]; |
|||
return _item(isDarkMode, data); |
|||
}, |
|||
), |
|||
), |
|||
), |
|||
GestureDetector( |
|||
onTap: () {}, |
|||
child: Container( |
|||
width: 130.w, |
|||
height: 48.w, |
|||
margin: EdgeInsets.symmetric(vertical: 20.w), |
|||
decoration: BoxDecoration( |
|||
color: isDarkMode ? AppColors.primary : Colors.blue, |
|||
borderRadius: BorderRadius.circular(12.w), |
|||
), |
|||
child: Row( |
|||
mainAxisAlignment: MainAxisAlignment.center, |
|||
children: [ |
|||
const Icon(Icons.keyboard_voice, color: Colors.white), |
|||
5.horizontalSpace, |
|||
Text( |
|||
'声音复刻', |
|||
style: TextStyle(color: Colors.white, fontSize: 16.sp), |
|||
), |
|||
], |
|||
), |
|||
), |
|||
), |
|||
], |
|||
); |
|||
} |
|||
|
|||
Widget _item(bool isDarkMode, Map data) { |
|||
return InkWell( |
|||
onTap: () { |
|||
controller.type.value = data['type']; |
|||
}, |
|||
child: Obx( |
|||
() => Container( |
|||
margin: EdgeInsets.symmetric(vertical: 6.h), |
|||
padding: EdgeInsets.all(12.w), |
|||
decoration: BoxDecoration( |
|||
color: controller.type.value == data['type'] |
|||
? (isDarkMode |
|||
? Colors.teal[900]!.withOpacity(0.3) |
|||
: Colors.teal[50]!) |
|||
: (isDarkMode |
|||
? Colors.white.withOpacity(0.05) |
|||
: Colors.grey[100]!), |
|||
borderRadius: BorderRadius.circular(12.r), |
|||
border: Border.all( |
|||
color: controller.type.value == data['type'] |
|||
? (isDarkMode ? Colors.teal[300]! : Colors.teal[600]!) |
|||
: Colors.transparent, |
|||
width: 1, |
|||
), |
|||
), |
|||
child: Row( |
|||
children: [ |
|||
Expanded( |
|||
child: Column( |
|||
crossAxisAlignment: CrossAxisAlignment.start, |
|||
children: [ |
|||
Text( |
|||
data['name'], |
|||
style: TextStyle( |
|||
fontSize: 16.sp, |
|||
fontWeight: FontWeight.w500, |
|||
color: isDarkMode ? Colors.white : Colors.black87, |
|||
), |
|||
overflow: TextOverflow.ellipsis, |
|||
), |
|||
SizedBox(height: 4.h), |
|||
Text( |
|||
data['description'], |
|||
style: TextStyle( |
|||
fontSize: 12.sp, |
|||
color: isDarkMode ? Colors.white70 : Colors.black54, |
|||
), |
|||
overflow: TextOverflow.ellipsis, |
|||
maxLines: 2, |
|||
), |
|||
], |
|||
), |
|||
), |
|||
Container( |
|||
width: 24.w, |
|||
height: 24.w, |
|||
margin: EdgeInsets.only(left: 12.w), |
|||
decoration: BoxDecoration( |
|||
color: controller.type.value == data['type'] |
|||
? (isDarkMode ? Colors.teal[300] : Colors.teal[600]) |
|||
: (isDarkMode |
|||
? Colors.white.withOpacity(0.1) |
|||
: Colors.grey[300]), |
|||
shape: BoxShape.circle, |
|||
), |
|||
child: controller.type.value == data['type'] |
|||
? Icon( |
|||
Icons.check, |
|||
size: 16.w, |
|||
color: Colors.white, |
|||
) |
|||
: null, |
|||
), |
|||
], |
|||
), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue