Flutter Sticker Editor
一个功能强大的 Flutter 贴图编辑器组件。
Features
-
🖼️ Image Editing
- Crop, rotate, and scale images
- Apply filters and adjustments
-
🎨 Drawing Tools
- Free-hand drawing
- Customizable brush settings
-
📝 Sticker Management
- Add and manage stickers
- Drag, resize, and rotate stickers
- Layer management
Getting Started
Add this to your package's pubspec.yaml
file:
dependencies:
flutter_sticker_editor: ^0.0.1
1、初始化设置
在使用组件之前,需要先初始化 DrawerInfo Provider:
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => DrawerInfo()),
],
child: MyApp(),
),
);
}
2、使用组件
全部默认
@override
Widget build(BuildContext context) {
return StickerEditor();
}
自定义界面
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_sticker_editor/flutter_sticker_editor.dart';
import 'package:provider/provider.dart';
class DrawerPage extends StatefulWidget {
const DrawerPage({super.key});
@override
State<DrawerPage> createState() => _DrawerPageState();
}
class _DrawerPageState extends State<DrawerPage> {
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
StickerEditorConfig config = StickerEditorConfig(
// customPickerPanel: _buildPickerWidget(),
customDrawerPanel: _buildDrawerWidgetCustom() // 方式1
// customDrawerPanel: _buildDrawerWidget() // 方式二
);
return StickerEditor(
onComplete: (Uint8List uint8List, { bool isSaveChihiros = false, bool isPublishList = false }) {
},
config: config,
);
}
Widget _buildPickerWidget() {
return SizedBox(
child: GestureDetector(
onTap: () {
context.read<DrawerInfo>().gotoStep(EditorStep.ready);
},
child: Image.asset(
'assets/images/stickers/niumao1.png',
width: 50,
height: 50,
fit: BoxFit.cover,
),
),
);
}
StickerDrawer _buildDrawerWidget() {
final List<StickerItem> defaultStickers = [
StickerItem(
id: 'niumao1',
path: 'assets/images/stickers/niumao1.png',
category: '最近',
),
StickerItem(
id: 'niumao2',
path: 'assets/images/stickers/niumao2.png',
category: '前景',
),
StickerItem(
id: 'niumao3',
path: 'assets/images/stickers/niumao3.png',
category: '中景',
),
StickerItem(
id: 'padi1',
path: 'assets/images/stickers/padi1.png',
category: '背景',
),
];
return StickerDrawer(
stickerSelectPanel: StickerSelectPanel(
stickers: defaultStickers,
),
);
}
StickerDrawer _buildDrawerWidgetCustom() {
final List<StickerItem> defaultStickers = [
StickerItem(
id: 'niumao1',
path: 'assets/images/stickers/niumao1.png',
category: '最近',
),
StickerItem(
id: 'niumao2',
path: 'assets/images/stickers/niumao2.png',
category: '前景',
),
StickerItem(
id: 'niumao3',
path: 'assets/images/stickers/niumao3.png',
category: '中景',
),
StickerItem(
id: 'padi1',
path: 'assets/images/stickers/padi1.png',
category: '背景',
),
];
return StickerDrawer(
stickerSelectPanel: StickerSelectPanel(
customContent: (context, scrollCtrl, selectedIndex) {
print('selected: ${selectedIndex}');
return ListView.builder(
controller: scrollCtrl,
itemCount: defaultStickers.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(
defaultStickers[index].id,
style: const TextStyle(
color: Colors.black12,
fontSize: 16,
),
),
onTap: () {
// 添加贴纸
context.read<DrawerInfo>().quickAddSticker(
defaultStickers[index].path,
);
},
);
},
);
},
),
);
}
}
使用单独功能(API)
1、添加背景贴纸(必须)
final drawerInfo = Provider.of<DrawerInfo>(context, listen: false);
drawerInfo.bgImageFile = _imageFile;
2、添加贴纸
快捷添加:
await context.read<DrawerInfo>().quickAddSticker(path);
自定义添加:
// 加载图片
if (path.startsWith('http')) {
// 网络图片加载
final response = await NetworkAssetBundle(Uri.parse(path)).load(path);
final Uint8List bytes = response.buffer.asUint8List();
img = await decodeImageFromList(bytes);
} else {
// 本地图片加载
final ByteData data = await rootBundle.load(path);
final Uint8List bytes = data.buffer.asUint8List();
img = await decodeImageFromList(bytes);
}
// 初始化贴纸
final sticker = Sticker(
stickerId: "sticker_id_123", // 贴纸ID,不可重复
stickerName: "图层${_stickers.length + 1}",
width: 100,
height: 100,
offset: const Offset(50, 50),
brushPaths: [],
rotation: 0,
image: img,
);
// 添加贴纸
context.read<DrawerInfo>().addSticker(sticker);
3、删除贴纸
// 删除贴纸[stickerId]
context.read<DrawerInfo>().deleteStickerById(stickerId);
获取指定贴纸
// 获取指定贴纸
context.read<DrawerInfo>().getStickerById(stickerId);
获取当前选中的贴纸
// 获取当前选中的贴纸
String? selectedStickerId = context.read<DrawerInfo>().selectedStickerId;
if (selectedStickerId != null) {
print('Selected Sticker ID: $selectedStickerId');
Sticker? currentSticker = context.read<DrawerInfo>().getStickerById(stickerId);
} else {
print('No sticker selected.');
}