Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save softmarshmallow/60dac1c6fea7f9809f9bc48127523bf4 to your computer and use it in GitHub Desktop.

Select an option

Save softmarshmallow/60dac1c6fea7f9809f9bc48127523bf4 to your computer and use it in GitHub Desktop.
demo for demonstrating flutter's image fit & repeat, scaling capability and modeling.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(const MyApp());
/// Data model for managing the image display settings.
class ImageDisplaySettings extends ChangeNotifier {
static const String _imageUrl =
'https://www.gstatic.com/flutter-onestack-prototype/genui/example_1.jpg';
BoxFit _boxFit;
ImageRepeat _imageRepeat;
double _imageScale;
ImageDisplaySettings()
: _boxFit = BoxFit.cover,
_imageRepeat = ImageRepeat.noRepeat,
_imageScale = 1.0;
String get imageUrl => _imageUrl;
BoxFit get boxFit => _boxFit;
ImageRepeat get imageRepeat => _imageRepeat;
double get imageScale => _imageScale;
void setBoxFit(BoxFit newBoxFit) {
if (_boxFit != newBoxFit) {
_boxFit = newBoxFit;
notifyListeners();
}
}
void setImageRepeat(ImageRepeat newImageRepeat) {
if (_imageRepeat != newImageRepeat) {
_imageRepeat = newImageRepeat;
notifyListeners();
}
}
void setImageScale(double newImageScale) {
if (_imageScale != newImageScale) {
_imageScale = newImageScale;
notifyListeners();
}
}
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<ImageDisplaySettings>(
create: (BuildContext context) => ImageDisplaySettings(),
builder: (BuildContext context, Widget? child) {
return MaterialApp(
title: 'Decoration Image Showcase',
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.blue),
home: const DecorationImageDemoPage(),
);
},
);
}
}
class DecorationImageDemoPage extends StatelessWidget {
const DecorationImageDemoPage({super.key});
@override
Widget build(BuildContext context) {
final ImageDisplaySettings settings =
Provider.of<ImageDisplaySettings>(context);
return Scaffold(
appBar: AppBar(
title: const Text('Decoration Image Showcase'),
),
body: ListView(
padding: const EdgeInsets.all(16.0),
children: <Widget>[
const Text(
'Interactive Image Display',
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
Center(
child: Container(
width: 300,
height: 200,
decoration: BoxDecoration(
color: Colors.grey[200], // Background color in case image is loading or fails
borderRadius: BorderRadius.circular(16.0),
boxShadow: const <BoxShadow>[
BoxShadow(
color: Colors.black26,
blurRadius: 8.0,
offset: Offset(0, 4),
),
],
image: DecorationImage(
image: NetworkImage(settings.imageUrl),
fit: settings.boxFit,
alignment: Alignment.center,
repeat: settings.imageRepeat,
scale: settings.imageScale,
),
),
child: const Center(
child: Text(
'Featured Image',
style: TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold,
shadows: <Shadow>[
Shadow(
offset: Offset(1.0, 1.0),
blurRadius: 3.0,
color: Color.fromARGB(150, 0, 0, 0),
),
],
),
),
),
),
),
const SizedBox(height: 24),
const Text(
'Image Properties:',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
ListTile(
title: const Text('BoxFit Mode'),
trailing: DropdownButton<BoxFit>(
value: settings.boxFit,
onChanged: (BoxFit? newValue) {
if (newValue != null) {
settings.setBoxFit(newValue);
}
},
items: BoxFit.values.map<DropdownMenuItem<BoxFit>>(
(BoxFit value) {
return DropdownMenuItem<BoxFit>(
value: value,
child: Text(value.toString().split('.').last),
);
},
).toList(),
),
),
ListTile(
title: const Text('ImageRepeat Mode'),
trailing: DropdownButton<ImageRepeat>(
value: settings.imageRepeat,
onChanged: (ImageRepeat? newValue) {
if (newValue != null) {
settings.setImageRepeat(newValue);
}
},
items: ImageRepeat.values.map<DropdownMenuItem<ImageRepeat>>(
(ImageRepeat value) {
return DropdownMenuItem<ImageRepeat>(
value: value,
child: Text(value.toString().split('.').last),
);
},
).toList(),
),
),
ListTile(
title: Text('Image Scale: ${settings.imageScale.toStringAsFixed(1)}x'),
trailing: SizedBox(
width: 200, // Constrain slider width
child: Slider(
value: settings.imageScale,
min: 0.1,
max: 5.0,
divisions: 49, // 0.1 increments
label: settings.imageScale.toStringAsFixed(1),
onChanged: (double newValue) {
settings.setImageScale(newValue);
},
),
),
),
],
),
);
}
}
@softmarshmallow
Copy link
Author

softmarshmallow commented Sep 25, 2025

https://dartpad.dev/?id=60dac1c6fea7f9809f9bc48127523bf4

This demo show cases, how each property of DecorationImage actually produces lots of no-op, that this is not the best model how we would design Image model

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment