You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter开发:是否有类似Bitmoji的可自定义头像(支持脸型选择)方案?

Flutter 实现自定义头像生成功能(类似Bitmoji)

一、资源准备

  • 将头像部件(脸型、发型、胡须、眼睛、嘴巴等)按图层导出为带透明通道的PNG图,命名规则统一(如face_oval.png、hair_short_black.png)。
  • 按部件类型分类存放,比如assets/avatar/face/、assets/avatar/hair/,方便后续调用。

二、状态管理

用StatefulWidget管理选中的部件状态,示例代码:

class AvatarCreator extends StatefulWidget {
  const AvatarCreator({super.key});

  @override
  State<AvatarCreator> createState() => _AvatarCreatorState();
}

class _AvatarCreatorState extends State<AvatarCreator> {
  // 默认选中的部件
  String selectedFace = 'face_oval';
  String selectedHair = 'hair_short_black';
  String selectedBeard = 'beard_none';

  // 切换部件的方法
  void _updateFace(String face) => setState(() => selectedFace = face);
  void _updateHair(String hair) => setState(() => selectedHair = hair);
  void _updateBeard(String beard) => setState(() => selectedBeard = beard);

  @override
  Widget build(BuildContext context) {
    // 后续UI实现
  }
}

三、核心头像预览组件

用Stack叠加图层,注意层级顺序(底层脸型,上层覆盖发型、胡须等):

final _avatarKey = GlobalKey(); // 用于后续保存头像

Widget _buildAvatarPreview() {
  return RepaintBoundary(
    key: _avatarKey,
    child: Stack(
      alignment: Alignment.center,
      children: [
        Image.asset('assets/avatar/face/$selectedFace.png'),
        Image.asset('assets/avatar/eyes/eyes_normal.png'), // 示例眼睛部件
        Image.asset('assets/avatar/mouth/mouth_smile.png'), // 示例嘴巴部件
        Image.asset('assets/avatar/hair/$selectedHair.png'),
        Image.asset('assets/avatar/beard/$selectedBeard.png'),
      ],
    ),
  );
}

四、部件选择UI

用横向ListView实现选择栏,以脸型选择为例:

Widget _buildFaceSelector() {
  final faceOptions = ['face_oval', 'face_round', 'face_square', 'face_long'];
  return SizedBox(
    height: 80,
    child: ListView.builder(
      scrollDirection: Axis.horizontal,
      itemCount: faceOptions.length,
      padding: const EdgeInsets.symmetric(horizontal: 16),
      itemBuilder: (context, index) {
        final face = faceOptions[index];
        return GestureDetector(
          onTap: () => _updateFace(face),
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 8),
            child: Opacity(
              opacity: selectedFace == face ? 1 : 0.5,
              child: Image.asset('assets/avatar/face/$face.png', width: 60),
            ),
          ),
        );
      },
    ),
  );
}

发型、胡须选择器可复用此结构,只需修改数据源和更新方法。

五、头像保存功能

通过RepaintBoundary将头像转为图片并保存:

Future<void> _saveAvatar() async {
  final boundary = _avatarKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
  final image = await boundary.toImage(pixelRatio: 3.0);
  final byteData = await image.toByteData(format: ImageByteFormat.png);
  final pngBytes = byteData!.buffer.asUint8List();

  // 调用第三方插件保存到相册(如image_gallery_saver)
  // await ImageGallerySaver.saveImage(pngBytes);
  if (mounted) {
    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('头像已保存')));
  }
}

六、优化建议

  • 用enum管理部件类型,避免字符串硬编码(如enum FaceType { oval, round, square, long })。
  • 批量加载资源:用AssetBundle遍历文件夹获取部件列表,无需手动写路径。
  • 支持颜色自定义:通过ColorFilter给部件换色,示例:
    Image.asset(
      'assets/avatar/hair/$selectedHair.png',
      colorFilter: ColorFilter.mode(Colors.red, BlendMode.srcIn),
    )
    

内容的提问来源于stack exchange,提问作者ahmed emam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 21:06:17