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

如何实现目标Flutter UI?求Camera插件自定义完整代码

Flutter 自定义相机UI完整实现

以下是基于camera插件实现自定义相机UI的完整代码,包含相机预览、拍照按钮、切换摄像头等常用功能,你可以根据需求调整UI样式:

1. 添加依赖

在pubspec.yaml中添加相机插件及相关依赖:

dependencies:
  flutter:
    sdk: flutter
  camera: ^0.10.5+5 # 可替换为最新稳定版本
  path_provider: ^2.1.1
  path: ^1.8.3

2. 完整实现代码

import 'dart:async';
import 'dart:io';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:path/path.dart' show join;
import 'package:path_provider/path_provider.dart';

List<CameraDescription>? cameras;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  cameras = await availableCameras();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '自定义相机',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const CameraScreen(),
    );
  }
}

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

  @override
  State<CameraScreen> createState() => _CameraScreenState();
}

class _CameraScreenState extends State<CameraScreen> {
  CameraController? _controller;
  Future<void>? _initializeControllerFuture;
  bool _isRearCamera = true;

  @override
  void initState() {
    super.initState();
    _initCamera(cameras![0]);
  }

  void _initCamera(CameraDescription cameraDescription) {
    _controller = CameraController(
      cameraDescription,
      ResolutionPreset.medium,
      enableAudio: false,
    );

    _initializeControllerFuture = _controller?.initialize();
    setState(() {});
  }

  @override
  void dispose() {
    _controller?.dispose();
    super.dispose();
  }

  Future<void> _takePicture() async {
    try {
      await _initializeControllerFuture;

      final path = join(
        (await getTemporaryDirectory()).path,
        '${DateTime.now()}.png',
      );

      await _controller?.takePicture();

      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('照片已拍摄')),
      );
      // 可扩展:跳转照片预览页面或保存到系统相册
    } catch (e) {
      print(e);
    }
  }

  void _switchCamera() {
    setState(() {
      _isRearCamera = !_isRearCamera;
    });
    CameraDescription cameraDescription = _isRearCamera
        ? cameras![0]
        : cameras![1];
    _initCamera(cameraDescription);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder<void>(
        future: _initializeControllerFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            return Stack(
              children: [
                // 相机预览层
                CameraPreview(_controller!),
                // 顶部切换摄像头按钮
                Positioned(
                  top: 40,
                  right: 20,
                  child: IconButton(
                    icon: const Icon(Icons.flip_camera_ios, color: Colors.white, size: 30),
                    onPressed: _switchCamera,
                  ),
                ),
                // 底部拍照按钮栏
                Positioned(
                  bottom: 40,
                  left: 0,
                  right: 0,
                  child: Center(
                    child: GestureDetector(
                      onTap: _takePicture,
                      child: Container(
                        width: 75,
                        height: 75,
                        decoration: BoxDecoration(
                          color: Colors.white,
                          shape: BoxShape.circle,
                          border: Border.all(color: Colors.grey.shade300, width: 4),
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            );
          } else {
            return const Center(child: CircularProgressIndicator(color: Colors.white));
          }
        },
      ),
    );
  }
}

关键注意事项

  • 权限配置:必须在平台配置文件中添加相机权限声明
    • Android:在AndroidManifest.xml中添加 <uses-permission android:name="android.permission.CAMERA" />
    • iOS:在Info.plist中添加 NSCameraUsageDescription 字段并填写权限用途说明
  • UI自定义:可通过修改Stack中的控件位置、样式,添加滤镜选择、相册入口等功能
  • 照片处理:代码中照片默认保存到临时目录,可扩展逻辑将照片保存到系统相册

内容的提问来源于stack exchange,提问作者Shahbas Ahsan K K

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 15:01:25