device_wrapper 1.2.1
device_wrapper: ^1.2.1 copied to clipboard
Wrap Flutter pages with realistic device frames (iPhone, Galaxy, iPad, MacBook, Surface, Apple Watch) for web/desktop preview with themes and screenshots.
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:device_wrapper/device_wrapper.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Device Wrapper Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: DeviceWrapper(
initialMode: DeviceMode.iphone,
showModeToggle: true,
initialTheme: WrapperTheme.light,
initialOrientation: DeviceOrientation.portrait,
onModeChanged: (mode) {
debugPrint('Device mode changed to: ${mode.displayName}');
},
onScreenshot: (ui.Image image) {
debugPrint('Screenshot taken: ${image.width}x${image.height}');
},
child: const DemoHomePage(),
),
);
}
}
/// Demo home page to showcase the device wrapper
class DemoHomePage extends StatelessWidget {
const DemoHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[100],
appBar: AppBar(
backgroundColor: Colors.deepPurple,
foregroundColor: Colors.white,
title: const Text('Demo App'),
elevation: 0,
),
body: SingleChildScrollView(
child: Column(
children: [
// Hero Section
Container(
width: double.infinity,
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.deepPurple,
Colors.deepPurple.shade300,
],
),
),
child: Column(
children: [
const CircleAvatar(
radius: 50,
backgroundColor: Colors.white24,
child: Icon(
Icons.person,
size: 50,
color: Colors.white,
),
),
const SizedBox(height: 16),
const Text(
'Welcome, User!',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
const SizedBox(height: 8),
Text(
'Devices: iPhone, Galaxy, iPad, Tab,\nMacBook, Surface, Apple Watch',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
color: Colors.white.withValues(alpha: 0.8),
),
),
],
),
),
// Features Grid
Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Features',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
GridView.count(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
crossAxisCount: 2,
mainAxisSpacing: 12,
crossAxisSpacing: 12,
childAspectRatio: 1.2,
children: [
_buildFeatureCard(
icon: Icons.dashboard,
title: 'Dashboard',
color: Colors.blue,
),
_buildFeatureCard(
icon: Icons.message,
title: 'Messages',
color: Colors.green,
),
_buildFeatureCard(
icon: Icons.settings,
title: 'Settings',
color: Colors.orange,
),
_buildFeatureCard(
icon: Icons.analytics,
title: 'Analytics',
color: Colors.purple,
),
],
),
],
),
),
// Recent Activity
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Recent Activity',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 12),
_buildActivityItem(
icon: Icons.check_circle,
title: 'Task Completed',
subtitle: '2 minutes ago',
color: Colors.green,
),
_buildActivityItem(
icon: Icons.notifications,
title: 'New Notification',
subtitle: '15 minutes ago',
color: Colors.blue,
),
_buildActivityItem(
icon: Icons.update,
title: 'System Update',
subtitle: '1 hour ago',
color: Colors.orange,
),
],
),
),
const SizedBox(height: 100),
],
),
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
selectedItemColor: Colors.deepPurple,
unselectedItemColor: Colors.grey,
currentIndex: 0,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Search',
),
BottomNavigationBarItem(
icon: Icon(Icons.favorite),
label: 'Favorites',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
backgroundColor: Colors.deepPurple,
child: const Icon(Icons.add, color: Colors.white),
),
);
}
Widget _buildFeatureCard({
required IconData icon,
required String title,
required Color color,
}) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: color.withValues(alpha: 0.1),
shape: BoxShape.circle,
),
child: Icon(icon, color: color, size: 28),
),
const SizedBox(height: 12),
Text(
title,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
],
),
);
}
Widget _buildActivityItem({
required IconData icon,
required String title,
required String subtitle,
required Color color,
}) {
return Container(
margin: const EdgeInsets.only(bottom: 12),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.03),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: color.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(8),
),
child: Icon(icon, color: color, size: 20),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
Text(
subtitle,
style: TextStyle(
fontSize: 12,
color: Colors.grey[600],
),
),
],
),
),
Icon(Icons.chevron_right, color: Colors.grey[400]),
],
),
);
}
}