Flutter Instagram风格故事板插件flutter_instagram_storyboard的使用
Flutter Instagram风格故事板插件 flutter_instagram_storyboard
的使用
简介
flutter_instagram_storyboard
是一个用于创建类似于 Instagram 故事板的 Flutter 插件。尽管目前它仍处于早期发布阶段,缺少一些有用的功能,但已经可以使用,并且只需进行一些小调整即可。
主要功能
- 一个可以自动标记为“已观看”的故事按钮列表
- 类似于 Instagram 的 3D 页面视图列表
- 自定义导航
- 默认的故事板结构
尚未实现的功能
- 允许从后端请求故事的按钮预加载器
- 在后台预加载可见故事的懒加载器
开始使用
最简单的开始方式是使用内置的 StoryListView
来创建故事按钮。它接受一个 StoryButtonData
对象列表,这些对象包含每个故事的所有设置,包括页面列表、每个页面的时间以及许多其他设置。页面可以完全自定义,它们只是小部件。
使用方法
以下是一个完整的示例代码:
import 'package:flutter/material.dart';
import 'package:flutter_instagram_storyboard/flutter_instagram_storyboard.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.red,
),
home: const StoryExamplePage(),
);
}
}
class StoryExamplePage extends StatefulWidget {
const StoryExamplePage({Key? key}) : super(key: key);
@override
State<StoryExamplePage> createState() => _StoryExamplePageState();
}
class _StoryExamplePageState extends State<StoryExamplePage> {
static const double _borderRadius = 100.0;
final StoryTimelineController storyController = StoryTimelineController();
Widget _createDummyPage({
required String text,
required String imageName,
bool addBottomBar = true,
}) {
return StoryPageScaffold(
bottomNavigationBar: addBottomBar
? SizedBox(
width: double.infinity,
height: kBottomNavigationBarHeight,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 20.0),
child: Row(
children: [
Expanded(
child: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
border: Border.all(color: Colors.white, width: 2.0),
borderRadius: BorderRadius.circular(_borderRadius),
),
),
),
const Padding(
padding: EdgeInsets.all(8.0),
child: Icon(Icons.send, color: Colors.white),
),
],
),
),
)
: const SizedBox.shrink(),
body: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/$imageName.png'),
fit: BoxFit.cover,
),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
text,
style: const TextStyle(color: Colors.white, fontSize: 30.0, fontWeight: FontWeight.bold),
),
],
),
),
),
);
}
Widget _buildButtonChild(String text) {
return Padding(
padding: const EdgeInsets.all(5.0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(height: 100.0),
Text(
text,
style: const TextStyle(color: Colors.black, fontWeight: FontWeight.normal, fontSize: 11.0),
textAlign: TextAlign.center,
),
],
),
);
}
BoxDecoration _buildButtonDecoration(String imageName) {
return BoxDecoration(
borderRadius: BorderRadius.circular(_borderRadius),
image: DecorationImage(
image: AssetImage('assets/images/$imageName.png'),
fit: BoxFit.cover,
),
);
}
BoxDecoration _buildBorderDecoration(Color color) {
return BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(_borderRadius)),
border: Border.fromBorderSide(BorderSide(color: color, width: 1.5)),
);
}
@override
void initState() {
super.initState();
storyController.addListener(_onStoryEvent);
}
void _onStoryEvent(event, storyId) {
print('event=> $event storyId $storyId');
}
@override
void dispose() {
storyController.removeListener(_onStoryEvent);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0.0,
title: const Text('Story Example'),
),
body: Column(
children: [
StoryListView(
listHeight: 180.0,
pageTransform: const StoryPage3DTransform(),
buttonDatas: [
StoryButtonData(
storyId: "1",
showAddButton: true,
storyController: storyController,
timelineBackgroundColor: Colors.red,
buttonDecoration: _buildButtonDecoration('car'),
child: _buildButtonChild('Want a new car?'),
onAddStoryPressed: () {
print('onAddStoryPressed');
},
borderDecoration: _buildBorderDecoration(Colors.red),
storyPages: [
_createDummyPage(
text: 'Want to buy a new car? Get our loan for the rest of your life!',
imageName: 'car',
),
_createDummyPage(
text: 'Can\'t return the loan? Don\'t worry, we\'ll take your soul as a collateral ;-)',
imageName: 'car',
),
],
segmentDuration: [const Duration(seconds: 15), const Duration(seconds: 3)],
),
StoryButtonData(
storyId: "2",
storyController: storyController,
timelineBackgroundColor: Colors.blue,
buttonDecoration: _buildButtonDecoration('travel_1'),
borderDecoration: _buildBorderDecoration(const Color.fromARGB(255, 134, 119, 95)),
child: _buildButtonChild('Travel whereever'),
storyPages: [
_createDummyPage(text: 'Get a loan', imageName: 'travel_1', addBottomBar: false),
_createDummyPage(text: 'Select a place where you want to go', imageName: 'travel_2', addBottomBar: false),
_createDummyPage(text: 'Dream about the place and pay our interest', imageName: 'travel_3', addBottomBar: false),
],
segmentDuration: [
const Duration(seconds: 3),
const Duration(seconds: 3),
const Duration(seconds: 3),
],
),
// Add more StoryButtonData here...
],
),
],
),
);
}
}
额外信息
该插件仍在开发中,主要用于我正在参与的一些项目中。如果你有兴趣参与开发,请随时提交拉取请求,但请确保你的代码符合主要的 Dart 语言指南。
更多关于Flutter Instagram风格故事板插件flutter_instagram_storyboard的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter Instagram风格故事板插件flutter_instagram_storyboard的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用 flutter_instagram_storyboard
插件来创建一个 Instagram 风格故事板的示例代码。这个插件允许你在 Flutter 应用中实现类似 Instagram 的故事板界面,包括滑动切换故事、添加导航栏等功能。
首先,你需要在你的 pubspec.yaml
文件中添加 flutter_instagram_storyboard
依赖:
dependencies:
flutter:
sdk: flutter
flutter_instagram_storyboard: ^最新版本号 # 请替换为实际的最新版本号
然后运行 flutter pub get
来获取依赖。
接下来,在你的 Dart 文件中编写代码。以下是一个简单的示例,展示如何使用 flutter_instagram_storyboard
插件:
import 'package:flutter/material.dart';
import 'package:flutter_instagram_storyboard/flutter_instagram_storyboard.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: StoryBoardScreen(),
);
}
}
class StoryBoardScreen extends StatefulWidget {
@override
_StoryBoardScreenState createState() => _StoryBoardScreenState();
}
class _StoryBoardScreenState extends State<StoryBoardScreen> {
List<String> stories = [
'https://example.com/story1.jpg', // 替换为你的图片URL
'https://example.com/story2.jpg', // 替换为你的图片URL
'https://example.com/story3.jpg', // 替换为你的图片URL
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: InstagramStoryBoard(
stories: stories,
indicatorColor: Colors.white,
indicatorActiveColor: Colors.black,
onStoryClick: (index) {
// 点击故事时的回调
print('Story clicked at index: $index');
},
onPageChanged: (index) {
// 页面切换时的回调
print('Page changed to index: $index');
},
navigationBar: NavigationBar(
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.pop(context);
},
),
trailing: IconButton(
icon: Icon(Icons.more_vert),
onPressed: () {
// 显示更多选项的菜单
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('More options')),
);
},
),
title: Text('Stories'),
center: Icon(Icons.add),
onCenterIconPressed: () {
// 添加新故事的按钮点击事件
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Add New Story')),
);
},
),
),
);
}
}
在这个示例中:
- 我们定义了一个
MyApp
类作为应用的入口。 StoryBoardScreen
是我们的主屏幕,它包含了一个状态类_StoryBoardScreenState
。- 在
_StoryBoardScreenState
中,我们定义了一个stories
列表,包含了故事图片的 URL。 - 我们使用
InstagramStoryBoard
组件来展示故事板,并传递了故事列表、指示器颜色、点击和页面切换的回调。 NavigationBar
组件用于显示导航栏,包括返回按钮、更多选项按钮和添加新故事的按钮。
你可以根据需要进一步自定义这个示例,比如调整布局、添加更多功能等。希望这个示例能帮助你快速上手 flutter_instagram_storyboard
插件的使用。