Flutter Rive 代码 如何在子菜单图标下添加文本?
如何在菜单图标下添加文本,如图所示?
我不知道,因为我之前没有尝试过 flutter rive,请帮忙。
我在子菜单图标下添加了文本,我解决了这个问题。 如何在页面之间切换?如何创建一个新页面并在点击时切换到该页面?
import 'package:flutter/material.dart';
import 'package:rive/rive.dart';
class TabItem {
TabItem({
this.stateMachine = "",
this.artboard = "",
this.status,
});
UniqueKey? id = UniqueKey();
String stateMachine;
String artboard;
late SMIBool? status;
static List<TabItem> tabItemsList = [
TabItem(
stateMachine: "CHAT_Interactivity",
artboard: "CHAT",
),
TabItem(
stateMachine: "SEARCH_Interactivity",
artboard: "SEARCH",
),
TabItem(stateMachine: "TIMER_Interactivity", artboard: "TIMER"),
TabItem(stateMachine: "BELL_Interactivity", artboard: "BELL"),
TabItem(stateMachine: "USER_Interactivity", artboard: "USER"),
];
}
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:rive/rive.dart' hide LinearGradient;
import 'package:flutter_samples/samples/ui/rive_app/models/tab_item.dart';
import 'package:flutter_samples/samples/ui/rive_app/theme.dart';
import 'package:flutter_samples/samples/ui/rive_app/assets.dart' as app_assets;
class CustomTabBar extends StatefulWidget {
const CustomTabBar({Key? key, required this.onTabChange}) : super(key: key);
final Function(int tabIndex) onTabChange;
@override
State<CustomTabBar> createState() => _CustomTabBarState();
}
class _CustomTabBarState extends State<CustomTabBar> {
final List<TabItem> _icons = TabItem.tabItemsList;
int _selectedTab = 0;
void _onRiveIconInit(Artboard artboard, index) {
final controller = StateMachineController.fromArtboard(
artboard, _icons[index].stateMachine);
artboard.addController(controller!);
_icons[index].status = controller.findInput<bool>("active") as SMIBool;
}
void onTabPress(int index) {
if (_selectedTab != index) {
setState(() {
_selectedTab = index;
});
widget.onTabChange(index);
_icons[index].status!.change(true);
Future.delayed(const Duration(seconds: 1), () {
_icons[index].status!.change(false);
});
}
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Container(
margin: const EdgeInsets.fromLTRB(24, 0, 24, 8),
padding: const EdgeInsets.all(1),
constraints: const BoxConstraints(maxWidth: 768),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
gradient: LinearGradient(colors: [
Colors.white.withOpacity(0.5),
Colors.white.withOpacity(0)
]),
),
child: Container(
// Clip to avoid the tab touch outside the border radius area
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
color: RiveAppTheme.background2.withOpacity(0.8),
borderRadius: BorderRadius.circular(24),
boxShadow: [
BoxShadow(
color: RiveAppTheme.background2.withOpacity(0.3),
blurRadius: 20,
offset: const Offset(0, 20),
)
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: List.generate(_icons.length, (index) {
TabItem icon = _icons[index];
return Expanded(
key: icon.id,
child: CupertinoButton(
padding: const EdgeInsets.all(12),
child: AnimatedOpacity(
opacity: _selectedTab == index ? 1 : 0.5,
duration: const Duration(milliseconds: 200),
child: Stack(
clipBehavior: Clip.none,
alignment: Alignment.center,
children: [
Positioned(
top: -4,
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
height: 4,
width: _selectedTab == index ? 20 : 0,
decoration: BoxDecoration(
color: RiveAppTheme.accentColor,
borderRadius: BorderRadius.circular(2),
),
),
),
SizedBox(
height: 36,
width: 36,
child: RiveAnimation.asset(
app_assets.iconsRiv,
stateMachines: [icon.stateMachine],
artboard: icon.artboard,
onInit: (artboard) {
_onRiveIconInit(artboard, index);
},
),
)
]),
),
onPressed: () {
onTabPress(index);
},
),
);
}),
),
),
),
);
}
}
Flutter Rive 代码 如何在子菜单图标下添加文本?
如何在菜单图标下添加文本,如图所示?
我不知道,因为我之前没有尝试过 flutter rive,请帮忙。
我在子菜单图标下添加了文本,我解决了这个问题。 如何在页面之间切换?如何创建一个新页面并在点击时切换到该页面?
为每个选项卡创建单独的页面小部件:
// chat_page.dart
class ChatPage extends StatelessWidget {
const ChatPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const Center(
child: Text('Chat Page'),
);
}
}
// Similar for other pages
class SearchPage extends StatelessWidget {...}
class TimerPage extends StatelessWidget {...}
class NotificationsPage extends StatelessWidget {...}
class ProfilePage extends StatelessWidget {...}
将标题和页面小部件添加到 TabItem 类中:
class TabItem {
TabItem({
required this.stateMachine,
required this.artboard,
required this.title,
required this.page,
this.status,
});
UniqueKey? id = UniqueKey();
String stateMachine;
String artboard;
String title;
Widget page;
late SMIBool? status;
static List<TabItem> tabItemsList = [
TabItem(
stateMachine: "CHAT_Interactivity",
artboard: "CHAT",
title: "Chat",
page: const ChatPage(),
),
TabItem(
stateMachine: "SEARCH_Interactivity",
artboard: "SEARCH",
title: "Search",
page: const SearchPage(),
),
TabItem(
stateMachine: "TIMER_Interactivity",
artboard: "TIMER",
title: "Timer",
page: const TimerPage(),
),
TabItem(
stateMachine: "BELL_Interactivity",
artboard: "BELL",
title: "Notifications",
page: const NotificationsPage(),
),
TabItem(
stateMachine: "USER_Interactivity",
artboard: "USER",
title: "Profile",
page: const ProfilePage(),
),
];
}
class MainScreen extends StatefulWidget {
const MainScreen({Key? key}) : super(key: key);
@override
State<MainScreen> createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
final PageController _pageController = PageController();
int _selectedIndex = 0;
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
void _onTabChange(int index) {
setState(() {
_selectedIndex = index;
});
_pageController.animateToPage(
index,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
// Pages
PageView(
controller: _pageController,
physics: const NeverScrollableScrollPhysics(), // Disable swipe
children: TabItem.tabItemsList.map((tab) => tab.page).toList(),
),
// Custom Tab Bar
Positioned(
bottom: 0,
left: 0,
right: 0,
child: CustomTabBar(
onTabChange: _onTabChange,
),
),
],
),
);
}
}
修改您的 CustomTabBar 小部件以包含文本标签:
class _CustomTabBarState extends State<CustomTabBar> {
// ... existing code ...
@override
Widget build(BuildContext context) {
return SafeArea(
child: Container(
margin: const EdgeInsets.fromLTRB(24, 0, 24, 8),
padding: const EdgeInsets.all(1),
constraints: const BoxConstraints(maxWidth: 768),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
gradient: LinearGradient(colors: [
Colors.white.withOpacity(0.5),
Colors.white.withOpacity(0)
]),
),
child: Container(
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
color: RiveAppTheme.background2.withOpacity(0.8),
borderRadius: BorderRadius.circular(24),
boxShadow: [
BoxShadow(
color: RiveAppTheme.background2.withOpacity(0.3),
blurRadius: 20,
offset: const Offset(0, 20),
)
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: List.generate(_icons.length, (index) {
TabItem icon = _icons[index];
return Expanded(
key: icon.id,
child: CupertinoButton(
padding: const EdgeInsets.all(12),
child: AnimatedOpacity(
opacity: _selectedTab == index ? 1 : 0.5,
duration: const Duration(milliseconds: 200),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Stack(
clipBehavior: Clip.none,
alignment: Alignment.center,
children: [
Positioned(
top: -4,
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
height: 4,
width: _selectedTab == index ? 20 : 0,
decoration: BoxDecoration(
color: RiveAppTheme.accentColor,
borderRadius: BorderRadius.circular(2),
),
),
),
SizedBox(
height: 36,
width: 36,
child: RiveAnimation.asset(
app_assets.iconsRiv,
stateMachines: [icon.stateMachine],
artboard: icon.artboard,
onInit: (artboard) {
_onRiveIconInit(artboard, index);
},
),
),
],
),
const SizedBox(height: 4),
Text(
icon.title,
style: TextStyle(
fontSize: 12,
color: _selectedTab == index
? RiveAppTheme.accentColor
: Colors.grey,
),
),
],
),
),
onPressed: () {
onTabPress(index);
},
),
);
}),
),
),
),
);
}
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Rive Navigation Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MainScreen(),
);
}
}
平滑页面转换
状态管理
UI定制
PageView(
controller: _pageController,
physics: const NeverScrollableScrollPhysics(),
children: TabItem.tabItemsList.map((tab) {
return KeyedSubtree(
key: ValueKey(tab.title),
child: tab.page,
);
}).toList(),
)
SafeArea(
bottom: true,
child: CustomTabBar(...),
)
void navigateToTab(String tabName) {
final index = TabItem.tabItemsList.indexWhere((tab) => tab.title == tabName);
if (index != -1) {
_onTabChange(index);
}
}
页面未更新
动画问题
内存泄漏
记住:
您希望我更详细地解释任何部分或展示如何实现特定功能吗?