Skip to content

Instantly share code, notes, and snippets.

@manelfera
Last active October 22, 2023 12:34
Show Gist options
  • Save manelfera/a9bc181f090689f603244a76f83f0f39 to your computer and use it in GitHub Desktop.
Save manelfera/a9bc181f090689f603244a76f83f0f39 to your computer and use it in GitHub Desktop.
Flutter circle container for lists (vertical & horizontal)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(20),
child: Column(children: [
Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
const Text(
'Sample horizontal bullets',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w800,
fontFamily: 'Roboto',
letterSpacing: 0.5,
fontSize: 20,
),
)
]),
const SizedBox(height: 20),
Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
const CircleBottomText(
innerText: 'Hello',
bottomText: 'World',
size: 60,
borderColor: Colors.orange,
fillColor: Colors.orange,
),
const CircleBottomText(
innerText: 'Hello',
bottomText: 'World',
size: 60,
borderColor: Colors.orange,
fillColor: Colors.orange,
),
const CircleBottomText(
innerText: 'Hello',
bottomText: 'World',
size: 60,
borderColor: Colors.orange,
fillColor: Colors.orange,
),
]),
const SizedBox(height: 20),
Separator(thickness: 2),
const SizedBox(height: 20),
Row(mainAxisAlignment: MainAxisAlignment.start, children: [
const Text(
'Sample vertical bulleted list',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w800,
fontFamily: 'Roboto',
letterSpacing: 0.5,
fontSize: 20,
),
)
]),
const SizedBox(height: 20),
const NumberedListItem(
number: '1', color: Colors.orange, child: text1),
const SizedBox(height: 20),
const NumberedListItem(
number: '2', color: Colors.orange, child: text2),
const SizedBox(height: 20),
const NumberedListItem(
number: '3', color: Colors.orange, child: text3),
]));
}
}
const text1 = Text.rich(
TextSpan(text: 'Lorem ipsum dolor sit amet, ', children: <TextSpan>[
TextSpan(
text: 'consectetur adipiscing elit.',
style: TextStyle(fontWeight: FontWeight.bold))
]),
overflow: TextOverflow.ellipsis,
maxLines: 5,
);
const text2 = Text.rich(
TextSpan(text: 'Curabitur vehicula dictum cursus.'),
overflow: TextOverflow.ellipsis,
maxLines: 5,
);
const text3 = Text.rich(
TextSpan(
// with no TextStyle it will have default text style
text: 'Lorem ipsum dolor sit amet, ',
children: <TextSpan>[
TextSpan(
text: 'consectetur adipiscing elit. ',
style: TextStyle(fontWeight: FontWeight.bold)),
TextSpan(
text:
'Curabitur vehicula dictum cursus. Aliquam posuere tortor quam, sed laoreet enim ultrices at.'),
],
),
overflow: TextOverflow.ellipsis,
maxLines: 5,
);
class CircleBottomText extends StatelessWidget {
final String innerText;
final String? bottomText;
final Color borderColor;
final Color? fillColor;
final double size;
final TextStyle? innerTextStyle;
const CircleBottomText({
Key? key,
required this.innerText,
required this.borderColor,
required this.size,
this.bottomText,
this.fillColor,
this.innerTextStyle,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Container(
width: size,
height: size,
decoration: BoxDecoration(
color: borderColor, // border color
shape: BoxShape.circle,
),
child: Padding(
padding: const EdgeInsets.all(5), // border width
child: Container(
// or ClipRRect if you need to clip the content
decoration: BoxDecoration(
shape: BoxShape.circle,
color: fillColor ?? borderColor, // inner circle color
),
child: Center(
child: Text(
innerText,
style: innerTextStyle ??
Theme.of(context).textTheme.bodyLarge, // inner content
),
),
),
),
),
if (bottomText != null) ...[
const SizedBox(height: 8),
Text(bottomText!),
]
],
);
}
}
class NumberedListItem extends StatelessWidget {
final String number;
final Color color;
// final String text;
final Widget child;
const NumberedListItem({
Key? key,
required this.number,
required this.color,
required this.child,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Row(children: [
CircleBottomText(
innerText: number,
size: 60,
borderColor: color,
fillColor: Colors.white,
innerTextStyle: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.w800,
fontFamily: 'Roboto',
letterSpacing: 0.5,
fontSize: 20,
),
),
const SizedBox(width: 20),
Expanded(child: child
)
]);
}
}
class Separator extends StatelessWidget {
final Color? color;
final double thickness;
const Separator({this.color, this.thickness = 1, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: thickness, color: color ?? Theme.of(context).dividerColor);
}
}
@manelfera
Copy link
Author

manelfera commented Jun 3, 2022

Beautify your flutter bulleted lists

image

See it live at dartpad

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