annotation_for_all 0.1.0
annotation_for_all: ^0.1.0 copied to clipboard
A standalone Flutter toolkit for annotating PDFs and images: freehand drawing, highlight, underline, grading marks (tick, cross, circle, question mark, number stamps), image insertion, and undo/redo. [...]
import 'dart:io';
import 'package:annotation_for_all/annotation_for_all.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() => runApp(const ExampleApp());
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'annotation_for_all example',
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String? _status;
Future<void> _pickAndOpen() async {
// No extension filter — try a PDF, a photo, or a .docx to see all three
// branches of FileAnnotator.open.
final result = await FilePicker.platform.pickFiles(
withData: kIsWeb, // web needs bytes; mobile/desktop can use the path
);
if (result == null || result.files.isEmpty) return;
final picked = result.files.single;
if (!mounted) return;
final outcome = await FileAnnotator.open(
context,
// On web, PlatformFile.path isn't just null — merely accessing the
// getter throws. Only touch .path off the web.
file: kIsWeb ? null : File(picked.path!),
bytes: picked.bytes,
fileName: picked.name,
enableMarksDialog: true, // off by default; flip on to demo it
totalMarks: 100,
// Only show Tick and Cross in the marks toolbar — no number/circle/
// question mark. Pass the full set (or omit this) to show all of them.
enabledMarks: const {MarkType.rightTick, MarkType.incorrectCross},
);
setState(() {
switch (outcome.handledAs) {
case FileHandledAs.annotated:
_status = 'Saved ${outcome.annotatedBytes!.lengthInBytes} bytes';
break;
case FileHandledAs.viewed:
_status = 'Opened "${picked.name}" externally';
break;
case FileHandledAs.downloaded:
_status = 'Downloaded "${picked.name}"';
break;
case FileHandledAs.cancelled:
_status = 'Cancelled';
break;
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('annotation_for_all example')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: _pickAndOpen,
child: const Text('Pick a file'),
),
const SizedBox(height: 16),
if (_status != null) Text(_status!),
],
),
),
);
}
}