Introduction
The clay_containers
package allows you to create clay-style containers, which are UI elements with a soft, realistic appearance. This guide will show you how to integrate and use this package to create clay containers in your Flutter app.
Content
1.Add the clay_containers
dependency: Open your pubspec.yaml
file and add the clay_containers
dependency.
dependencies:
clay_containers: ^latest_version
Run flutter pub get
to install the package.
2.Import the package:
Import the clay_containers
package in your Dart file.
import 'package:clay_containers/clay_containers.dart';
3.Create a Clay Container:
Use the ClayContainer
widget to create a clay container with a soft, realistic appearance.
ClayContainer(
color: Colors.white,
height: 100,
width: 100,
depth: 10,
borderRadius: 20,
child: Center(
child: Text('Clay Container', style: TextStyle(color: Colors.black)),
),
)
Customize the color
, height
, width
, depth
, borderRadius
, and child
parameters to achieve the desired appearance for your clay container. The color
parameter sets the background color of the container, height
and width
set the size, depth
sets the depth of the container’s shadow, borderRadius
sets the border radius, and child
is the widget that will be displayed inside the container.
4.Run the app:
Run your Flutter app to see the clay container. It should have a soft, realistic appearance with a shadow effect.
Sample Code
import 'package:clay_containers/clay_containers.dart';
import 'package:flutter/material.dart';
// import 'package:clay_containers/theme/clay_text_theme.dart';
import 'package:flutter/material.dart';
// import 'package:clay_containers/theme/clay_theme_data.dart';
import 'package:flutter/material.dart';
void main() => runApp(const MaterialApp(debugShowCheckedModeBanner: false, home: MyApp()));
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
Color baseColor = const Color(0xFFf2f2f2);
double firstDepth = 50;
double secondDepth = 50;
double thirdDepth = 50;
double fourthDepth = 50;
late AnimationController _animationController;
@override
void initState() {
_animationController = AnimationController(
vsync: this, // the SingleTickerProviderStateMixin
duration: const Duration(seconds: 5),
)..addListener(() {
setState(() {});
});
_animationController.forward();
super.initState();
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
double? stagger(double value, double progress, double delay) {
var newProgress = progress - (1 - delay);
if (newProgress < 0) newProgress = 0;
return value * (newProgress / delay);
}
final calculatedFirstDepth = stagger(firstDepth, _animationController.value, 0.25)!;
final calculatedSecondDepth = stagger(secondDepth, _animationController.value, 0.5)!;
final calculatedThirdDepth = stagger(thirdDepth, _animationController.value, 0.75)!;
final calculatedFourthDepth = stagger(fourthDepth, _animationController.value, 1)!;
return ClayTheme(
themeData: const ClayThemeData(
height: 10,
width: 20,
borderRadius: 360,
textTheme: ClayTextTheme(style: TextStyle()),
depth: 12,
),
child: ColoredBox(
color: baseColor,
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
ClayContainer(
color: Colors.amber,
height: 240,
width: 240,
curveType: CurveType.concave,
spread: 30,
depth: calculatedFirstDepth.toInt(),
child: Center(
child: ClayContainer(
height: 200,
width: 200,
depth: calculatedSecondDepth.toInt(),
curveType: CurveType.convex,
color: Colors.lightBlue,
child: Center(
child: ClayContainer(
height: 160,
width: 160,
color: Colors.deepPurple,
depth: calculatedThirdDepth.toInt(),
curveType: CurveType.concave,
child: Center(
child: ClayContainer(
height: 120,
width: 120,
color: Colors.yellow,
depth: calculatedFourthDepth.toInt(),
curveType: CurveType.convex,
),
),
),
),
),
),
),
SizedBox(
height: 115,
),
ClayContainer(
color: baseColor,
height: 240,
width: 240,
curveType: CurveType.concave,
spread: 30,
depth: calculatedFirstDepth.toInt(),
child: Center(
child: ClayContainer(
height: 200,
width: 200,
depth: calculatedSecondDepth.toInt(),
curveType: CurveType.convex,
color: baseColor,
child: Center(
child: ClayContainer(
height: 160,
width: 160,
color: baseColor,
depth: calculatedThirdDepth.toInt(),
curveType: CurveType.concave,
child: Center(
child: ClayContainer(
height: 120,
width: 120,
color: baseColor,
depth: calculatedFourthDepth.toInt(),
curveType: CurveType.convex,
),
),
),
),
),
),
),
],
),
),
),
);
}
}
class ClayThemeData {
const ClayThemeData({
this.height,
this.width,
this.color = const Color(0xFFf0f0f0),
this.parentColor,
this.surfaceColor,
this.borderRadius,
this.customBorderRadius,
this.textTheme,
this.depth,
this.emboss = false,
this.spread,
});
final double? height;
final double? width;
final Color color;
final Color? parentColor;
final Color? surfaceColor;
final double? borderRadius;
final BorderRadius? customBorderRadius;
final int? depth;
final double? spread;
final bool emboss;
final ClayTextTheme? textTheme;
ClayThemeData copyWith({
double? height,
double? width,
Color? color,
Color? parentColor,
Color? surfaceColor,
double? borderRadius,
BorderRadius? customBorderRadius,
int? depth,
double? spread,
bool? emboss,
ClayTextTheme? textTheme,
}) {
return ClayThemeData(
height: height ?? this.height,
width: width ?? this.width,
color: color ?? this.color,
parentColor: parentColor ?? this.parentColor,
surfaceColor: surfaceColor ?? this.surfaceColor,
borderRadius: borderRadius ?? this.borderRadius,
customBorderRadius: customBorderRadius ?? this.customBorderRadius,
depth: depth ?? this.depth,
spread: spread ?? this.spread,
emboss: emboss ?? this.emboss,
textTheme: textTheme ?? this.textTheme,
);
}
}
class ClayTheme extends InheritedWidget {
const ClayTheme({required this.themeData, required super.child, super.key});
final ClayThemeData themeData;
static ClayThemeData? of(BuildContext context) {
return context.findAncestorWidgetOfExactType<ClayTheme>()?.themeData;
}
@override
bool updateShouldNotify(covariant ClayTheme oldWidget) => true;
}
// import 'package:flutter/material.dart';
class ClayTextTheme {
const ClayTextTheme({
required this.style,
this.color = const Color(0xFFf0f0f0),
this.depth = 40,
this.size = 14,
this.parentColor,
this.textColor,
this.spread,
this.emboss = false,
});
final Color color;
final Color? parentColor;
final Color? textColor;
final TextStyle style;
final double? spread;
final int depth;
final double size;
final bool emboss;
ClayTextTheme copyWith({
Color? color,
Color? parentColor,
Color? textColor,
TextStyle? style,
double? spread,
int? depth,
double? size,
bool? emboss,
}) {
return ClayTextTheme(
color: color ?? this.color,
parentColor: parentColor ?? this.parentColor,
textColor: textColor ?? this.textColor,
style: style ?? this.style,
spread: spread ?? this.spread,
depth: depth ?? this.depth,
size: size ?? this.size,
emboss: emboss ?? this.emboss,
);
}
}
Output
Conclusion
By following these steps, you can easily integrate the clay_containers
package into your Flutter app and create clay-style containers. This can be useful for adding a unique and visually appealing design to your app’s UI.