flutter_list_ui 1.3.4
flutter_list_ui: ^1.3.4 copied to clipboard
A Flutter package for creating beautiful and customizable list UIs with various styles and layouts.
Flutter List UI #
A Flutter package that provides a collection of list-related widgets with consistent styling and behavior.
Features #
InfoList
: A flexible list widget that supports:- Generic type support for any data model
- Empty state handling with customizable UI
- Skeleton loading UI with shimmer effect
- AsyncValue integration with Riverpod
- Custom item builders
- Custom separators
- Custom styling options
- Horizontal scrolling support for long text
InfoCard
: A card widget that wraps content with consistent stylingInfoHeader
: A header widget for cards with title and optional actionsInfoItemBase
: A base model for list items with common properties
Getting Started #
Add the package to your pubspec.yaml
:
dependencies:
flutter_list_ui: ^1.3.2
shimmer: ^3.0.0 # Optional: for skeleton loading effect
Usage #
Basic List #
InfoList.info(
items: items,
buildItem: (item) => ListTile(
title: Text(item.title),
subtitle: Text(item.subtitle),
),
);
With Empty State #
InfoList.info(
items: items,
buildEmptyItem: (context, items) => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.inbox_outlined,
size: 48,
color: Colors.grey[400],
),
const SizedBox(height: 16),
Text(
'데이터가 없습니다',
style: TextStyle(
color: Colors.grey[600],
fontSize: 16,
),
),
],
),
),
buildItem: (item) => ListTile(
title: Text(item.title),
subtitle: Text(item.subtitle),
),
);
With Skeleton Loading #
InfoList.info(
items: items,
isLoading: true,
skeletonCount: 3,
skeletonBuilder: (context, index) => Container(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: Colors.grey[300],
shape: BoxShape.circle,
),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
height: 20,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(4),
),
),
const SizedBox(height: 8),
Container(
width: 150,
height: 16,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(4),
),
),
],
),
),
],
),
),
);
With Riverpod AsyncValue #
InfoList.when(
value: itemsAsyncValue,
buildItem: (item) => ListTile(
title: Text(item.title),
subtitle: Text(item.subtitle),
),
buildEmptyItem: (context, items) => Container(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.search_off,
size: 48,
color: Colors.grey[400],
),
const SizedBox(height: 16),
Text(
'검색 결과가 없습니다',
style: TextStyle(
color: Colors.grey[600],
fontSize: 16,
),
),
const SizedBox(height: 8),
Text(
'다른 검색어를 시도해보세요',
style: TextStyle(
color: Colors.grey[500],
fontSize: 14,
),
),
],
),
),
);
With Shimmer Effect #
import 'package:shimmer/shimmer.dart';
InfoList.info(
items: items,
isLoading: true,
skeletonBuilder: (context, index) => Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Container(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
height: 20,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
const SizedBox(height: 8),
Container(
width: 150,
height: 16,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
],
),
),
],
),
),
),
);
With InfoCard #
Info(
card: InfoCard(
header: InfoHeader(
title: 'List Title',
titleStyle: Theme.of(context).textTheme.titleLarge,
),
body: InfoList.info(
items: items,
buildItem: (item) => ListTile(
title: Text(item.title),
subtitle: Text(item.subtitle),
),
),
backgroundColor: Colors.white,
isRound: true,
showBorder: false,
),
);
With Horizontal Scrolling #
CustomInfoList(
items: items,
useSliver: true,
buildItem: (item) => SizedBox(
width: 300,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Row(
children: [
Icon(
item.isActive ? Icons.check_circle : Icons.circle_outlined,
color: item.isActive ? Colors.blue : null,
),
const SizedBox(width: 16),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
item.name,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: item.isActive ? Colors.blue : null,
),
overflow: TextOverflow.clip,
softWrap: false,
),
const SizedBox(height: 4),
Text(
item.description,
style: Theme.of(context).textTheme.bodyMedium,
overflow: TextOverflow.clip,
softWrap: false,
),
],
),
const SizedBox(width: 16),
const Icon(Icons.chevron_right),
],
),
),
),
),
);
Additional Information #
InfoList Properties #
Property | Type | Description |
---|---|---|
items | List | The list of items to display |
buildItem | Widget Function(T) | Function to build each item widget |
backgroundColor | Color? | Background color of the list |
contentPadding | EdgeInsetsGeometry? | Padding around the list content |
shrinkWrap | bool | Whether the list should shrink-wrap its content |
separatorBuilder | Widget Function(BuildContext, int)? | Function to build separator widgets |
physics | ScrollPhysics? | Scroll physics for the list |
itemPadding | EdgeInsetsGeometry? | Padding for each item |
itemDecoration | BoxDecoration? | Decoration for each item container |
removeTopPadding | bool | Whether to remove top padding |
emptyWidget | Widget? | Widget to show when items is empty |
isLoading | bool | Whether to show skeleton loading UI |
skeletonCount | int | Number of skeleton items to show |
skeletonBuilder | Widget Function(BuildContext, int)? | Function to build skeleton items |
buildEmptyItem | Widget Function(BuildContext, List | Function to build empty state UI |
InfoCard Properties #
Property | Type | Description |
---|---|---|
header | InfoHeader? | Header widget for the card |
body | Widget | Main content of the card |
backgroundColor | Color? | Background color of the card |
isRound | bool | Whether to show rounded corners |
showBorder | bool | Whether to show border |
padding | EdgeInsetsGeometry? | Padding around the card content |
margin | EdgeInsetsGeometry? | Margin around the card |
InfoHeader Properties #
Property | Type | Description |
---|---|---|
title | String | Title text |
titleStyle | TextStyle? | Style for the title text |
actions | List | Action widgets to show in the header |
Dependencies #
- flutter_riverpod: ^2.5.1 (Required for AsyncValue support)
- flutter_screenutil: ^5.9.0
- google_fonts: ^6.1.0
- cached_network_image: ^3.3.1
- shimmer: ^3.0.0 (Optional: for skeleton loading effect)
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
License #
This project is licensed under the MIT License - see the LICENSE file for details.
About #
A reusable Flutter UI components package