在这里插入图片描述

设置页面是应用的配置中心,提供了主题、语言、字体大小等各种设置选项。这个页面使用ListView来展示所有设置项,并使用GetX进行状态管理。设置页面的设计强调了用户体验,通过分组显示不同类型的设置,使用户能够快速找到所需的设置选项。

设置页面的整体架构

设置页面是一个StatefulWidget,它在initState中获取AppController的实例。使用StatefulWidget是因为我们需要在页面初始化时获取控制器。

class SettingsPage extends StatefulWidget {
  const SettingsPage({Key? key}) : super(key: key);

  
  State<SettingsPage> createState() => _SettingsPageState();
}

class _SettingsPageState extends State<SettingsPage> {
  late AppController appController;

  
  void initState() {
    super.initState();
    appController = Get.find<AppController>();
  }

Get.find() 从GetX的依赖注入系统中获取AppController的实例。这样,我们可以访问应用的各种设置状态。使用GetX的依赖注入系统的好处是,我们不需要通过构造函数传递控制器,代码更加简洁。

页面的整体布局

设置页面使用Scaffold作为基础容器。AppBar显示页面标题,body使用ListView来展示所有设置项。


Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: const Text('设置')),
    body: ListView(
      children: [
        // 显示设置
        // 功能设置
        // 关于应用
      ],
    ),
  );
}

使用ListView而不是Column的好处是,当设置项超过屏幕高度时,用户可以滚动查看。这提供了更好的用户体验。

显示设置部分

显示设置包括深色模式、语言和字体大小三个选项。这些设置直接影响应用的外观。

Padding(
  padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h),
  child: Text(
    '显示设置',
    style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold, color: Colors.blue),
  ),
),
SettingsItem(
  icon: Icons.dark_mode,
  title: '深色模式',
  subtitle: '切换应用主题',
  trailing: Obx(() => Switch(
    value: appController.isDarkMode.value,
    onChanged: (value) {
      appController.setDarkMode(value);
    },
  )),
),

这段代码展示了如何创建一个设置项。首先,我们使用Padding和Text来创建一个分组标题。然后,我们使用SettingsItem组件来创建一个设置项。

Obx 是GetX提供的响应式组件。当isDarkMode的值改变时,Switch会自动更新。这是GetX的强大功能,可以自动处理UI的更新,无需手动调用setState。

深色模式使用Switch组件,用户可以直接切换。当用户改变Switch的状态时,onChanged回调会被触发,调用appController.setDarkMode(value)来更新应用的主题。

语言和字体大小设置

语言和字体大小设置使用对话框来实现。

SettingsItem(
  icon: Icons.language,
  title: '语言',
  subtitle: '当前: 中文',
  trailing: const Icon(Icons.arrow_forward_ios, size: 16),
  onTap: () => _showLanguageDialog(),
),
SettingsItem(
  icon: Icons.text_fields,
  title: '字体大小',
  subtitle: '调整应用字体',
  trailing: const Icon(Icons.arrow_forward_ios, size: 16),
  onTap: () => _showFontSizeDialog(),
),

这两个设置项都使用了onTap回调来显示对话框。当用户点击这些项时,会显示一个对话框让用户选择相应的选项。

功能设置部分

功能设置包括通知、默认保存位置和清除历史记录三个选项。

Padding(
  padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h),
  child: Text(
    '功能设置',
    style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold, color: Colors.blue),
  ),
),
SettingsItem(
  icon: Icons.notifications,
  title: '通知',
  subtitle: '接收转换完成通知',
  trailing: Obx(() => Switch(
    value: appController.notificationEnabled.value,
    onChanged: (value) {
      appController.setNotification(value);
    },
  )),
),
SettingsItem(
  icon: Icons.folder,
  title: '默认保存位置',
  subtitle: '设置文件保存路径',
  trailing: const Icon(Icons.arrow_forward_ios, size: 16),
  onTap: () => _showSavePathDialog(),
),

通知设置也使用Switch组件,用户可以直接切换。默认保存位置使用对话框来设置,用户可以输入自定义的保存路径。

关于应用部分

关于应用部分包括应用版本、帮助与反馈和隐私政策三个选项。

Padding(
  padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h),
  child: Text(
    '关于应用',
    style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold, color: Colors.blue),
  ),
),
SettingsItem(
  icon: Icons.info,
  title: '应用版本',
  subtitle: 'v2.1.3',
  trailing: const Icon(Icons.arrow_forward_ios, size: 16),
),
SettingsItem(
  icon: Icons.help,
  title: '帮助与反馈',
  subtitle: '获取帮助或提交反馈',
  trailing: const Icon(Icons.arrow_forward_ios, size: 16),
  onTap: () => _showHelpDialog(),
),

这些项目提供了应用的基本信息和帮助功能。应用版本项没有onTap回调,因为它只是显示版本号。帮助与反馈项有onTap回调,点击时会显示帮助对话框。

SettingsItem组件

SettingsItem是一个自定义组件,用来展示设置项。它提供了统一的设置项UI。

class SettingsItem extends StatelessWidget {
  final IconData icon;
  final String title;
  final String subtitle;
  final Widget? trailing;
  final VoidCallback? onTap;

  const SettingsItem({
    Key? key,
    required this.icon,
    required this.title,
    required this.subtitle,
    this.trailing,
    this.onTap,
  }) : super(key: key);

  
  Widget build(BuildContext context) {
    return Card(
      margin: EdgeInsets.symmetric(horizontal: 16.w, vertical: 4.h),
      child: ListTile(
        leading: Icon(icon, color: Colors.blue),
        title: Text(title, style: TextStyle(fontWeight: FontWeight.bold)),
        subtitle: Text(subtitle, style: TextStyle(fontSize: 12.sp)),
        trailing: trailing,
        onTap: onTap,
      ),
    );
  }
}

SettingsItem使用ListTile来显示内容。leading 属性显示左边的图标。title 显示设置项的名称。subtitle 显示设置项的描述。trailing 属性可以是任何Widget,例如Switch或Icon。onTap 是点击回调。

Card组件为ListTile提供了卡片样式,包括圆角和阴影。这样的设计使得每个设置项看起来更加独立和清晰。

语言选择对话框

语言选择对话框提供了多种语言选项供用户选择。

void _showLanguageDialog() {
  showDialog(
    context: context,
    builder: (context) => AlertDialog(
      title: const Text('选择语言'),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          ListTile(
            title: const Text('中文'),
            onTap: () => Navigator.pop(context),
          ),
          ListTile(
            title: const Text('English'),
            onTap: () => Navigator.pop(context),
          ),
          ListTile(
            title: const Text('日本語'),
            onTap: () => Navigator.pop(context),
          ),
        ],
      ),
    ),
  );
}

这个对话框使用AlertDialog来显示。content 属性包含了一个Column,其中包含了多个ListTile,每个ListTile代表一种语言选项。当用户点击一个语言选项时,onTap回调会被触发,调用 Navigator.pop(context) 关闭对话框。

字体大小对话框

字体大小对话框提供了三种字体大小选项。

void _showFontSizeDialog() {
  showDialog(
    context: context,
    builder: (context) => AlertDialog(
      title: const Text('字体大小'),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          ListTile(
            title: const Text('小'),
            onTap: () => Navigator.pop(context),
          ),
          ListTile(
            title: const Text('正常'),
            selected: true,
            onTap: () => Navigator.pop(context),
          ),
          ListTile(
            title: const Text('大'),
            onTap: () => Navigator.pop(context),
          ),
        ],
      ),
    ),
  );
}

这个对话框的结构与语言选择对话框类似。selected: true 表示"正常"选项是当前选中的选项,ListTile会以不同的样式显示选中的项。

保存路径对话框

保存路径对话框允许用户输入自定义的文件保存路径。

void _showSavePathDialog() {
  showDialog(
    context: context,
    builder: (context) => AlertDialog(
      title: const Text('默认保存位置'),
      content: TextField(
        decoration: InputDecoration(
          hintText: '/storage/emulated/0/Download',
          border: OutlineInputBorder(borderRadius: BorderRadius.circular(8.r)),
        ),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(context),
          child: const Text('取消'),
        ),
        TextButton(
          onPressed: () => Navigator.pop(context),
          child: const Text('确定'),
        ),
      ],
    ),
  );
}

这个对话框包含了一个TextField,用户可以在其中输入保存路径。对话框的底部有两个按钮:取消和确定。

AppController的状态管理

AppController使用GetX进行状态管理。

class AppController extends GetxController {
  final isDarkMode = false.obs;
  final language = 'zh'.obs;
  final fontSize = 'normal'.obs;
  final notificationEnabled = true.obs;
  final savePath = '/storage/emulated/0/Download'.obs;

  void setDarkMode(bool value) {
    isDarkMode.value = value;
  }

  void setLanguage(String lang) {
    language.value = lang;
  }

  void setFontSize(String size) {
    fontSize.value = size;
  }

  void setNotification(bool value) {
    notificationEnabled.value = value;
  }

  void setSavePath(String path) {
    savePath.value = path;
  }
}

.obs 表示这个变量是可观察的。当这个变量的值改变时,所有使用Obx包装的Widget都会自动更新。这是GetX的核心功能,可以自动处理UI的更新,无需手动调用setState。

每个设置都有一个对应的setter方法,用来更新设置的值。这样的设计使得设置的更新逻辑集中在一个地方,便于维护和扩展。

总结

设置页面通过使用ListView和SettingsItem组件,提供了一个功能完整的设置界面。页面使用分组显示不同类型的设置,使用户能够快速找到所需的设置选项。通过使用GetX进行状态管理,我们实现了响应式的UI更新。这样的设计提供了良好的用户体验,并且具有很好的可维护性和可扩展性。


欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐