网站建设属于什么经营范围,深圳企业登记注册,厦门网站建设公司首选乐振,wordpress生成的网页文章目录 前言官方Flutter案例侧边栏添加代码初始化展示效果 子组件私有数据空间导航栏转为有状态WidgetsetState手动转换页面实现效果 响应式动态切换宽度添加收藏夹#xff0c;跨Widget传数据实现效果 完整代码后续进阶效果总结 前言
接着继续上一章的内容
官方Flutter案例… 文章目录 前言官方Flutter案例侧边栏添加代码初始化展示效果 子组件私有数据空间导航栏转为有状态WidgetsetState手动转换页面实现效果 响应式动态切换宽度添加收藏夹跨Widget传数据实现效果 完整代码后续进阶效果总结 前言
接着继续上一章的内容
官方Flutter案例 编写第一个 Flutter 应用 侧边栏添加
代码初始化
为了保证main.dart代码能正常跑通我将完整的代码复制粘贴到这里
import package:english_words/english_words.dart;
import package:flutter/material.dart;
import package:provider/provider.dart;void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});overrideWidget build(BuildContext context) {return ChangeNotifierProvider(create: (context) MyAppState(),child: MaterialApp(title: Namer App,theme: ThemeData(useMaterial3: true,colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange),),home: MyHomePage(),),);}
}//可通知视图修改的类
class MyAppState extends ChangeNotifier {//这个就相当于成员变量var current WordPair.random();//手动声明回调函数理论上来说最好通过函数显性修改父节点属性void getNext(){current WordPair.random();// 手动通知刷新视图元素notifyListeners();}//手动通知void notify(){notifyListeners();}var favorites WordPair[];void toggleFavorite() {if (favorites.contains(current)) {favorites.remove(current);} else {favorites.add(current);}notifyListeners();}
}class MyHomePage extends StatelessWidget {overrideWidget build(BuildContext context) {return Scaffold(body: Row(children: [SafeArea(child: NavigationRail(extended: false,destinations: [NavigationRailDestination(icon: Icon(Icons.home),label: Text(Home),),NavigationRailDestination(icon: Icon(Icons.favorite),label: Text(Favorites),),],selectedIndex: 0,onDestinationSelected: (value) {print(selected: $value);},),),Expanded(child: Container(color: Theme.of(context).colorScheme.primaryContainer,child: GeneratorPage(),),),],),);}
}class GeneratorPage extends StatelessWidget {overrideWidget build(BuildContext context) {var appState context.watchMyAppState();var pair appState.current;IconData icon;if (appState.favorites.contains(pair)) {icon Icons.favorite;} else {icon Icons.favorite_border;}return Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [BigCard(pair: pair),SizedBox(height: 10),Row(mainAxisSize: MainAxisSize.min,children: [ElevatedButton.icon(onPressed: () {appState.toggleFavorite();},icon: Icon(icon),label: Text(Like),),SizedBox(width: 10),ElevatedButton(onPressed: () {appState.getNext();},child: Text(Next),),],),],),);}
}class BigCard extends StatelessWidget {const BigCard({super.key,required this.pair,});final WordPair pair;overrideWidget build(BuildContext context) {//获取父节点的主题final theme Theme.of(context);//手动设置style,这个就是类似于css的样式传递final style theme.textTheme.bodyMedium!.copyWith(color: theme.colorScheme.onPrimary,);return Card(color: theme.colorScheme.primary,child: Padding(padding: const EdgeInsets.all(8.0),child: Text(pair.asLowerCase,style: style),),);}
}展示效果
由于官方的案例是按照横向布局来设置的所以我们安卓实时效果不太一样。 子组件私有数据空间
我们目前的数据都是用MyApp的数据但是我们不可能将所有的数据都放在父节点子节点也应该有自己的私有数据空间。
在Flutter中这称之为无状态WidgetStatelessWidget和有状态widgetStatefulWidget
导航栏转为有状态Widget setState 在 Flutter 中使用 setState 时的 6 个简单技巧 手动转换页面 在return之前添加如下代码
Widget page;switch (selectedIndex) {case 0:page GeneratorPage();break;case 1:page Placeholder();break;default:throw UnimplementedError(no widget for $selectedIndex);}实现效果 响应式动态切换宽度
将【Scaffold】替换为【Builder】【Builder】替换为【LayoutBuilder】 添加收藏夹跨Widget传数据
添加一个新的Widget
class FavoritesPage extends StatelessWidget {overrideWidget build(BuildContext context) {var appState context.watchMyAppState();if (appState.favorites.isEmpty) {return Center(child: Text(No favorites yet.),);}return ListView(children: [Padding(padding: const EdgeInsets.all(20),child: Text(You have ${appState.favorites.length} favorites:),),for (var pair in appState.favorites)ListTile(leading: Icon(Icons.favorite),title: Text(pair.asLowerCase),),],);}
}实现效果 完整代码
import package:english_words/english_words.dart;
import package:flutter/material.dart;
import package:provider/provider.dart;void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});overrideWidget build(BuildContext context) {return ChangeNotifierProvider(create: (context) MyAppState(),child: MaterialApp(title: Namer App,theme: ThemeData(useMaterial3: true,colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange),),home: MyHomePage(),),);}
}//可通知视图修改的类
class MyAppState extends ChangeNotifier {//这个就相当于成员变量var current WordPair.random();//手动声明回调函数理论上来说最好通过函数显性修改父节点属性void getNext(){current WordPair.random();// 手动通知刷新视图元素notifyListeners();}//手动通知void notify(){notifyListeners();}var favorites WordPair[];void toggleFavorite() {if (favorites.contains(current)) {favorites.remove(current);} else {favorites.add(current);}notifyListeners();}
}class MyHomePage extends StatefulWidget {overrideStateMyHomePage createState() _MyHomePageState();
}class _MyHomePageState extends StateMyHomePage {var selectedIndex 0;overrideWidget build(BuildContext context) {Widget page;switch (selectedIndex) {case 0:page GeneratorPage();break;case 1:page FavoritesPage();break;default:throw UnimplementedError(no widget for $selectedIndex);}return LayoutBuilder(builder: (context,constraints) {return Scaffold(body: Row(children: [SafeArea(child: NavigationRail(extended: false,destinations: [NavigationRailDestination(icon: Icon(Icons.home),label: Text(Home),),NavigationRailDestination(icon: Icon(Icons.favorite),label: Text(Favorites),),],selectedIndex: selectedIndex,onDestinationSelected: (value) {setState(() {selectedIndex value;print(selected: $selectedIndex);});},),),Expanded(child: Container(color: Theme.of(context).colorScheme.primaryContainer,child: page,),),],),);});}
}class FavoritesPage extends StatelessWidget {overrideWidget build(BuildContext context) {var appState context.watchMyAppState();if (appState.favorites.isEmpty) {return Center(child: Text(No favorites yet.),);}return ListView(children: [Padding(padding: const EdgeInsets.all(20),child: Text(You have ${appState.favorites.length} favorites:),),for (var pair in appState.favorites)ListTile(leading: Icon(Icons.favorite),title: Text(pair.asLowerCase),),],);}
}class GeneratorPage extends StatelessWidget {overrideWidget build(BuildContext context) {var appState context.watchMyAppState();var pair appState.current;IconData icon;if (appState.favorites.contains(pair)) {icon Icons.favorite;} else {icon Icons.favorite_border;}return Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [BigCard(pair: pair),SizedBox(height: 10),Row(mainAxisSize: MainAxisSize.min,children: [ElevatedButton.icon(onPressed: () {appState.toggleFavorite();},icon: Icon(icon),label: Text(Like),),SizedBox(width: 10),ElevatedButton(onPressed: () {appState.getNext();},child: Text(Next),),],),],),);}
}class BigCard extends StatelessWidget {const BigCard({super.key,required this.pair,});final WordPair pair;overrideWidget build(BuildContext context) {//获取父节点的主题final theme Theme.of(context);//手动设置style,这个就是类似于css的样式传递final style theme.textTheme.bodyMedium!.copyWith(color: theme.colorScheme.onPrimary,);return Card(color: theme.colorScheme.primary,child: Padding(padding: const EdgeInsets.all(8.0),child: Text(pair.asLowerCase,style: style),),);}
}
后续进阶效果 进阶代码链接 总结
唉该怎么说呢但凡Avalonia或者MAUI对移动端的支持好一点我也不至于学一个Flutter。但是没办法。我记得有个数据有将近50%的移动端开发用的就是Flutter。Flutter和Avalonia用的都是自绘的方式而MAUI用的却是原生映射的方式。所以会出现很多很多的Bug。MAUIBlazor或许是个不错的解决方案但是我还是累了不想陪微软折腾了。过两年再看看好了。