[Flutter学徒]7路由&导航导航,或用户如何在不同的屏幕之间切换,是一个需要掌握的重要概念。好的导航可以使

导航,或用户如何在不同的屏幕之间切换,是一个需要掌握的重要概念。好的导航可以使你的应用程序有条不紊,并帮助用户在你的应用程序中找到自己的方向,而不会感到沮丧。

在上一章中,当你为用户创建一个杂货店清单来管理要买的东西时,你对导航有了小小的体会。当用户点击一个物品时,会显示物品的详细信息。

你将学习以下内容。

在本章结束时,你将知道导航到不同屏幕所需的一切!

注意。如果你想直接跳到代码,请跳到开始部分。如果你想先学习理论知识,请继续阅读!

如果你有iOS背景,你可能对UINavigationController很熟悉。这个控制器定义了一个基于堆栈的方案来管理和导航视图控制器。

在Android中,你使用JetpackNavigation来管理各种片段。

在Flutter中,你使用Navigator小部件来管理你的屏幕或页面。你可以把屏幕或页面看作是路线。

注意。本章交替使用这些术语,因为它们的意思都是一样的。

一个栈是一个管理页面的数据结构。你插入的元素是后进先出(LIFO),只有堆栈顶部的元素对用户是可见的。

例如,当用户查看一个杂货店项目的列表时,点击一个项目将GroceryItemScreen推到堆栈的顶部。一旦用户完成了修改,你就把它从堆栈中抛出来。

下面是导航栈的顶层和侧层视图。

现在,是时候快速浏览一下Navigator1.0了。

在Flutter1.22发布之前,你只能通过发出直接的命令,如"现在显示这个"或"移除当前屏幕并返回到前一个",来实现屏幕之间的转换。Navigator1.0为你提供了一套简单的API,用于在屏幕之间进行导航。最常见的包括。

那么你如何在你的应用程序中添加一个导航器呢?

大多数Flutter应用程序以WidgetsApp作为根部件开始。

注意。到目前为止,你已经使用了MaterialApp,它扩展了WidgetsApp。

WidgetsApp包装了许多其他你的应用程序需要的普通widget。在这些包装好的部件中,有一个顶层的Navigator来管理你推送和弹出的页面。

为了向用户显示另一个屏幕,你需要在Navigator栈上推送一个Route。下面是该代码的一个例子。

下面是如何从堆栈中弹出一个路线的方法。

Navigator.pop(context);这似乎很容易。那么为什么不直接使用Navigator1.0呢?嗯,它有一些缺点。

必要性的API可能看起来很自然,很容易使用,但实际上,它很难管理和扩展。

首先是没有好的方法来管理你的页面,而不保留你推拉屏幕的心理地图。

想象一下,一个新的开发人员刚刚加入你的团队。他们会从哪里开始呢?他们肯定会感到困惑。

此外,Navigator1.0并没有向开发者公开路由栈。这使得它很难处理复杂的情况,比如在页面之间添加和删除一个屏幕。

例如,在Fooderlich中,你想只在用户还没有完成入职时显示入职界面。用Navigator1.0处理这个问题很复杂。

最后,在安卓设备上,当你有嵌套的导航器或将Flutter添加到你的主机安卓应用时,后退按钮可能无法在导航器1.0中工作。

它包括以下关键组件。

势在必行的API是非常基本的,迫使你把push()和pop()函数放在你的widget层次结构中--它耦合了你所有的widget!为了呈现另一个屏幕,你还必须在widget的层次结构上放置回调。

下面是它是如何工作的。

这就是了!而不是要建立一个每个屏幕如何呈现和解散的心理思维图,状态驱动哪些页面出现。

如果你有一个现有的项目,你不需要迁移或转换你现有的代码来使用新的API。

这里有一些提示,可以帮助你决定哪个对你更有用。

接下来,你将获得一些关于Navigator2.0的实践经验。

注意。本章将重点介绍Navigator2.0的实现。要了解更多关于Navigator1.0的信息,请查看。

在AndroidStudio中打开启动项目,运行flutterpubget,然后运行该应用程序。

注意。最好从启动项目开始,而不是继续上一章的项目,因为启动项目包含一些本章特有的变化。

你会看到,Fooderlich的应用程序只显示一个Splash屏幕。

在你深入研究导航之前,这个启动项目中有一些新文件可以帮助你。

在in.dart中,Fooderlich现在是一个StatefulWidget。它可以监听状态变化并相应地重建相应的部件。

Fooderlich现在支持用户对黑暗模式的设置。

在lib/screens/中有八个新变化。

稍后,你将使用这些来构建你的认证UI流程。

对lib/models/中的文件有一些改变。

tab_manager.dart已被删除。取而代之的是,你将在app_state_manager.dart中管理用户的标签选择,你很快就会构建它。

此外,有三个新的模型对象。

assets/sample_data/包含以下模拟数据。

assets/包含新的图片,你将用它们来建立新的入职指南。

在pubspec.yaml中,有两个新包。

smooth_page_indicator:^0.2.3webview_flutter:^2.0.7下面是它们的作用。

smooth_page_indicator:当你滚动页面时显示一个页面指示器。webview_flutter:提供一个WebView小部件,在iOS或Android平台上显示网页内容。

如果你打开android/app/build.gradle,你会发现minSdkVersion现在是19,如下所示。

android{defaultConfig{ ...minSdkVersion19...}}这是因为webview_flutter依赖于AndroidSDK19或更高版本,以实现混合组成。

现在你知道有什么变化了,你可以快速浏览一下本章中你要构建的UI流程。

下面是你向用户展示的前三个屏幕。

从入职界面,用户进入应用程序的首页。他们现在可以开始使用该应用程序了。

该应用程序向用户展示了三个标签,有这些选项。

接下来,用户可以点击添加按钮,或者,如果食品杂货清单不是空的,他们可以点击一个现有的项目。这将呈现出食品杂货项目屏幕,如下所示。

现在,用户如何查看他们的个人资料或注销?他们首先点选个人资料的头像,如下图所示。

在档案屏幕上,他们可以做以下事情。

下面是一个用户切换到黑暗模式,然后打开raywenderlich.com的例子。

这里是整个导航层次的鸟瞰图。

注意。在本章资料的assets文件夹中,有一个大型的图片版本。

你的应用程序完成后将会非常棒。现在,是时候添加一些代码了!

第一步是定义你的应用程序的状态,它如何变化以及当变化发生时通知哪些组件。

在models目录下,创建一个名为app_state_manager.dart的新文件并添加以下内容。

在同一个文件中,找到//TODO:AddinitializeApp并将其替换为以下内容。

voidinitializeApp(){//7Timer(constDuration(milliseconds:2000),(){//8_initialized=true;//9notifyListeners();});}下面是代码的工作原理。

接下来,找到//TODO:添加login并将其替换为以下内容。

voidlogin(Stringusername,Stringpassword){//10_loggedIn=true;//11notifyListeners();}这个函数接收了一个用户名和密码。下面是它的作用。

接下来,找到//TODO:AddcompleteOnboarding并将其替换为以下内容。

voidcompleteOnboarding(){_onboardingComplete=true;notifyListeners();}调用completeOnboarding()将通知所有听众,用户已经完成了入职指导。

找到//TODO:添加goToTab并替换为以下内容:

voidgoToTab(index){_selectedTab=index;notifyListeners();}goToTab设置_selectedTab的索引并通知所有听众.

找到//TODO:添加goToRecipes并将其替换为以下内容:

voidgoToRecipes(){_selectedTab=FooderlichTab.recipes;notifyListeners();}这是一个帮助函数,可以直接进入食谱标签。

找到//TODO:Addlogout并将其替换为以下内容。

voidlogout(){//12_loggedIn=false;_onboardingComplete=false;_initialized=false;_selectedTab=0;//13initializeApp()。//14notifyListeners()。}当用户注销时,上面的代码。

请注意,所有这些函数都遵循相同的模式:它们设置一些不公开的值,然后通知监听器。这就是你要实现的单向数据流架构的本质。

最后,打开lib/models/models.dart,添加以下内容。

export'app_state_manager.dart';这样,你就把新创建的AppStateManager添加到桶文件中。你现在有了一个定义明确的应用程序状态模型和一个通知监听器状态变化的机制。这是很大的进步。现在,你将在应用程序中使用它!

打开lib/main.dart,找到//TODO:CreateAppStateManager并将其替换为以下内容。

final_appStateManager=AppStateManager();这里,你初始化了AppStateManager。

接下来,找到//TODO:AddAppStateManagerChangeNotifierProvider并将其替换为以下内容。

ChangeNotifierProvider(create:(context)=>_appStateManager,)。这为AppStateManager创建了一个变化提供者,所以widget的后代可以访问或监听应用程序的状态。

这就是全部!注意到你是如何首先定义你的应用程序的状态的吗?任何开发者看了这个文件都可以知道用户是如何与Fooderlich应用互动的。

不要关闭in.dart,你很快会再次更新它。接下来,你要添加一个路由器。

路由器配置导航器显示的页面列表。它监听状态管理器,并根据状态变化,配置页面路由列表。

在lib/下,创建一个名为navigation的新目录。在该文件夹中,创建一个名为app_router.dart的新文件。添加以下代码。

现在你已经定义了你的路由器,你将让它处理路由请求。

找到//TOOD:添加_handlePopPage并将其替换为以下内容。

下面是它的工作原理。

现在,要使用这个回调助手,找到//TODO:AddonPopPage并替换为以下内容。

onPopPage:_handlePopPage,这样,每次有页面从堆栈中弹出时,都会调用它。

现在,你需要连接状态管理器。当状态改变时,路由器将用一组新的页面重新配置导航器。

找到//TODO:AddListeners并将其替换为以下内容。

appStateManager.addListener(notifyListeners);groceryManager.addListener(notifyListeners);profileManager.addListener(notifyListeners);下面是状态管理器的作用。

当你处置路由器时,你必须删除所有监听器。如果忘记这样做将会抛出一个异常。

找到//TODO:Disposelisteners并将其替换为以下内容。

@overridevoiddispose(){ appStateManager.removeListener(notifyListeners);groceryManager.removeListener(notifyListeners); profileManager.removeListener(notifyListeners);super.dispose();}恭喜你,你刚刚设置了你的路由器小部件。现在,是时候使用它了!保持app_router.dart开放,你很快就会用到它。

新创建的路由器需要知道谁是管理者,所以你现在要把它连接到状态、杂货店和档案管理器。

打开in.dart,找到//TODO:Importapp_router。用下面的内容代替它。

import'navigation/app_router.dart';接下来,找到//TODO:定义AppRouter,用以下内容代替。

@overridevoidinitState(){_appRouter=AppRouter(appStateManager:_appStateManager,groceryManager:_groceryManager,profileManager:_profileManager,);super.initState();}现在你已经在initState()中初始化了你的应用路由器,然后再使用它。保持in.dart打开。

下一步,找到//TODO:用Routerwidget替换。用以下代码替换现有的home:constSplashScreen(),一行。

home:Router( routerDelegate:_appRouter,//TODO:AddbackButtonDispatcher),你不需要再导入Splash屏幕了。继续并删除以下代码。

import'screen/splash_screen.dart';你的路由器现在都设置好了!现在是时候让它玩玩屏幕了。

所有的基础设施都到位了,现在是时候根据路由定义要显示的屏幕了。但首先,看看目前的情况。在iOS上构建并运行。你会注意到在运行标签中的一个异常。

更糟糕的是,模拟器可能会显示红色的死亡屏幕。

这是因为Navigator页面不能是空的。应用程序抛出了一个异常,因为它不能生成一个路线。接下来你会通过添加屏幕来解决这个问题。

你将从头开始,显示Splash屏幕。

打开lib/screens/splash_screen.dart,添加以下导入。

import'package:provider/provider.dart';import'.../models/models.dart';接下来,找到//TODO:SplashScreenMaterialPageHelper并将其替换为以下内容。

staticMaterialPagepage(){returnMaterialPage(name:FooderlichPages.splashPath,key:ValueKey(FooderlichPages.splashPath),child:constSplashScreen(),);}在这里,你定义了一个静态方法来创建一个MaterialPage,设置适当的唯一标识符并创建SplashScreen。

接下来找到//TODO:InitializeApp并将其替换为以下内容。

现在,你要添加应用程序启动时显示的Splash屏幕。

回到app_router.dart,找到//TODO:AddSplashScreen并替换为以下内容。

if(!appStateManager.isInitialized)SplashScreen.page(),这里,你检查应用程序是否被初始化。如果没有,你将显示Splash屏幕。

执行一次热重启,你会看到下面的屏幕闪过。

你仍然会看到一个错误,但不要担心,它很快就会消失。

恭喜你,你刚刚设置了你的第一条路线现在,准备其他路由就容易多了。让app_router.dart打开。

下一组代码的更新将遵循一个类似的模式。

打开lib/screens/login_screen.dart,添加以下导入。

import'package:provider/provider.dart'。import'.../models/models.dart';接下来,找到//TODO:LoginScreenMaterialPageHelper并将其替换为以下内容。

staticMaterialPagepage(){returnMaterialPage(name:FooderlichPages.loginPath,key:ValueKey(FooderlichPages.loginPath),child:constLoginScreen());}在这里,你定义了一个静态方法,创建一个MaterialPage,设置一个唯一的键,并创建LoginScreen。保持login_screen.dart打开。

切换回app_router.dart,找到//TODO:添加LoginScreen并替换为以下内容。

回到login_screen.dart,找到//TODO:Login->Navigatetohome,并将其替换为以下内容。

打开lib/screens/onboarding_screen.dart,添加以下导入。

import'package:provider/provider.dart';import'.../models/models.dart';接下来,找到//TODO:AddOnboardingScreenMaterialPageHelper并替换为以下内容。

staticMaterialPagepage(){returnMaterialPage(name:FooderlichPages.onboardingPath,key:ValueKey(FooderlichPages.onboardingPath),child:constOnboardingScreen(),);}在这里,你配置了一个MaterialPage,设置了onboarding页面的唯一键,并创建了Onboarding屏幕部件。

返回到app_router.dart,找到//TODO:添加OnboardingScreen并替换为以下内容。

恭喜你,这是一个很好的进展。现在,你要添加逻辑来处理入职界面中触发的变化。

当用户点击跳过按钮而不是通过入职指南时,你要显示通常的主屏幕。

在onboarding_screen.dart中,找到//TODO:Onboarding->Navigatetohome并将其替换为以下内容。

接下来,你要处理当用户在入职界面上点击***返回时发生的事情。

回到app_router.dart,找到TODO:HandleOnboardingandSplash,用下面的内容替换它。

应用程序将返回Splash屏幕以重新初始化,如下图所示。

当用户点击Skip时,应用程序将显示主屏幕。打开lib/screens/home.dart,添加以下导入。

import'package:provider/provider.dart';import'.../models/models.dart';接下来,找到//TODO:HomeMaterialPageHelper并将其替换为以下内容。

staticMaterialPagepage(intcurrentTab){returnMaterialPage(name:FooderlichPages.home,key:ValueKey(FooderlichPages.home),child:Home(currentTab:currentTab,),);}在这里,你已经创建了一个静态的MaterialPage帮助器,并在主屏幕上显示当前标签。保持home.dart打开。

回到app_router.dart,找到//TODO:AddHome并将其替换为以下内容。

if(appStateManager.isOnboardingComplete)Home.page(appStateManager.getSelectedTab),这告诉你的应用程序只有在用户完成入职时才显示主页。

最后,你可以看到onboarding的实际效果了!

你会注意到,你不能切换到不同的标签。那是因为你还没有设置好状态处理。接下来你会做这个。

打开home.dart,找到//TODO:WrapConsumerforAppStateManager并将其替换为以下内容。

接下来,向下滚动到小组件的结尾,在结尾的}之前,添加以下内容。

},);确保你打开了自动格式化,并保存文件重新格式化。

你刚刚把你的整个widget包裹在一个Consumer里面。Consumer将监听应用程序的状态变化,并相应地重建其内部部件。

接下来,找到//TODO:Updateuser'sselectedtab并将其替换为以下内容。

现在,你想增加的是,点选浏览食谱按钮会将用户带到食谱标签。

打开empty_grocery_screen.dart,添加以下导入。

import'package:provider/provider.dart';import'.../models/models.dart';接下来,找到//TODO:Updateuser'sselectedtab并替换为以下内容。

为了测试它,点击底部导航栏中的要买标签,然后点击浏览食谱按钮。注意,应用程序会转到食谱标签,如下所示。

接下来,你将连接杂货店项目屏幕。打开lib/screens/grocery_item_screen.dart。找到//TODO:GroceryItemScreenMaterialPageHelper并将其替换为以下内容。

staticMaterialPagepage({GroceryItemitem,intindex,Function(GroceryItem)onCreate,Function(GroceryItem,int)onUpdate}){returnMaterialPage(name:FooderlichPages.groceryItemDetails,key:ValueKey(FooderlichPages.groceryItemDetails),child:GroceryItemScreen(originalItem:item,index:index,onCreate:onCreate,onUpdate:onUpdate,),);}在这里,你创建了一个静态页面助手,将GroceryItemScreen包裹在一个MaterialPage中。GroceryItem屏幕需要。

接下来,你将实现杂货店项目的屏幕。有两种方法来显示它。

接下来你将启用这些功能。

打开lib/screens/grocery_screen.dart,找到//TODO:CreateNewItem。用下面的内容来代替它。

接下来,回到app_router.dart,找到//TODO:Createnewitem并替换为以下内容。

//1如果(groceryManager.isCreatingNewItem)//2GroceryItemScreen.page(onCreate:(item){//3groceryManager.addItem(item);},),下面是如何让你导航到一个新的杂货店项目。

在你的应用程序运行时,执行热重启。你现在就可以创建一个新的杂货项目,如下图所示。

打开grocery_list_screen.dart,找到//TODO:Tapongroceryitem并将其替换为以下内容。

manager.groceryItemTapped(index);这就触发了groceryItemTapped(),让监听器知道用户选择了一个杂货店项目。

现在,回到app_router.dart,找到//TODO:SelectGroceryItemScreen并替换为以下内容。

//1if(groceryManager.selectedIndex!=null)//2GroceryItemScreen.page(item:groceryManager.selectedGroceryItem,index:groceryManager.selectedIndex,onUpdate:(item,index){//3groceryManager.updateItem(item,index);},),下面是代码的工作原理。

现在,你能够点击一个食品杂货项目,编辑它,并保存它!

有时,用户开始添加一个食品杂货项目,然后改变主意。为了应对这种情况,打开app_router.dart,找到//TODO:Handlestatewhenuserclosesgroceryitemscreen,用下面的内容代替。

if(route.settings.name==FooderlichPages.groceryItemDetails){ groceryManager.groceryItemTapped(null);}这确保了当用户从杂货店项目屏幕上点击后退按钮时,适当的状态被重置。

热重新启动,然后再次测试该序列。

请注意,该应用程序现在可以按预期工作。

用户还不能导航到个人资料屏幕。在你解决这个问题之前,你需要处理状态变化。

打开home.dart,找到//TODO:home->profile并将其替换为以下内容。

现在用户可以进入"简介"屏幕了,他们需要能够再次关闭它。

打开lib/screens/profile_screen.dart,找到//TODO:CloseProfileScreen并替换为以下内容。

现在,找到//TODO:ProfileScreenMaterialPageHelper并将其替换为以下内容。

staticMaterialPagepage(Useruser){returnMaterialPage(name:FooderlichPages.profilePath,key:ValueKey(FooderlichPages.profilePath),child:ProfileScreen(user:user),);}在这里,你为Profile屏幕创建一个助手MaterialPage。它需要一个用户对象。

接下来,打开app_router.dart,找到//TODO:AddProfileScreen,用下面的内容替换它。

if(profileManager.didSelectUser)ProfileScreen.page(profileManager.getUser),这将检查配置文件管理器,看用户是否选择了他们的配置文件。如果是,它就会显示Profile屏幕。

执行热重载并点击用户的头像。现在它将显示个人资料屏幕。

打开app_router.dart,找到//TODO:Handlestatewhenuserclosesprofilescreen并将其改为以下内容。

if(route.settings.name==FooderlichPages.profilePath){profileManager.tapOnProfile(false);}这将检查你弹出的路由是否确实是"profilePath",然后告诉"profileManager"个人资料屏幕不再可见。

现在点击X按钮,简介屏幕就会消失。

在"简介"屏幕内,你可以做三件事。

接下来,你将处理WebView屏幕。

回到profile_screen.dart,找到//TODO:Openraywenderlich.comWebView并将其替换为以下内容。

现在,打开webview_screen.dart,导入以下内容。

import'../models/models.dart';接下来,找到//TODO:WebViewScreenMaterialPageHelper并将其替换为以下内容。

staticMaterialPagepage(){returnMaterialPage(name:FooderlichPages.raywenderlich,key:ValueKey(FooderlichPages.raywenderlich),child:constWebViewScreen(),);}在这里,你创建了一个静态的MaterialPage,包裹了一个WebView屏幕部件。

接下来,回到app_router.dart。找到//TODO:AddWebViewScreen并将其替换为以下内容。

if(profileManager.didTapOnRaywenderlich)WebViewScreen.page(),这将检查用户是否点击了进入raywenderlich.com网站的选项。如果是,它就会呈现WebView屏幕。

热重载并转到个人资料屏幕。现在,点击查看raywenderlich.com,你会看到它出现在网络视图中,如下所示。

关闭该视图呢?

还是在app_router.dart中,找到//TODO:HandlestatewhenuserclosesWebViewscreen,用下面的内容替换。

if(route.settings.name==FooderlichPages.raywenderlich){profileManager.tapOnRaywenderlich(false);}在这里,你检查路由设置的名称是否是raywenderlich,然后在profileManager上调用适当的方法。

接下来,你将进行注销功能的工作。

为了处理注销用户,到profile_screen.dart,找到//TODO:Logoutuser。用下面的内容替换它。

保存你的改变。现在,从个人资料屏幕上点击注销,你会发现它回到了Splash屏幕,如下图所示。

接下来,你将处理安卓系统的返回按钮。

如果你一直在iOS上运行该项目,在你现有的设备或模拟器中停止该应用。现在,在一个安卓设备或模拟器上构建并运行你的应用程序。做好以下工作。

你期望它回到前一页。相反,它退出了整个应用程序!

要解决这个问题,打开in.dart,找到//TODO:AddbackButtonDispatcher,用下面的内容代替。

backButtonDispatcher:RootBackButtonDispatcher(),在这里,你设置了路由器部件的BackButtonDispatcher,它监听平台弹出的路由通知。当用户点击Android系统的返回按钮时,会触发路由器委托的onPopPage回调。

热重新启动你的应用程序,并再次尝试同样的步骤。

呜呼,它的行为符合预期!恭喜你,你现在已经完成了整个UI导航流程。

你还学会了创建一个路由器部件,它封装并配置了导航器的所有页面路线。现在,你可以在一个单一的路由器对象中轻松地管理你的导航流

为了学习这个主题,这里有一些高层次的理论和演练的建议。

Navigator2.0可能有点难以理解和单独管理。下面的软件包围绕着Navigator2.0的API,使路由和导航更容易。

还有很多事情你可以用Navigator2.0来做。在下一章中,你会看到支持网络URL和深层链接的内容!

THE END
1.可以定制食谱的app推荐定制食谱的减肥app大全定制食谱软件有哪些?对于需要减肥的用户和注重饮食健康营养均衡的用户来说,日常的吃的东西都是需要严格注意的,今天小编给大家推荐几款好用的定制食谱APP,根据大家的健康需求测试,制定专业科学的饮食计划,让大家都能吃的健康,用户可以根据自己的需求选择适合自己的食http://www.downcc.com/k/dzsp/
2.美食菜谱app手机界面图片免费下载美食菜谱app手机界面素材千图网为您找到163张美食菜谱app手机界面相关素材,千图网还提供美食菜谱app手机界面图片,美食菜谱app手机界面素材, 美食菜谱app手机界面模板等免费下载服务,千图网是国内专业创意营销服务交易平台,一站式解决企业营销数字化、协同化,实现营销转化效果增长!https://www.58pic.com/tupian/meishicaipuappshoujijiemian.html
3.菜谱APP源码和设计报告食谱类app用户界面设计论文菜谱APP源码和设计报告 《移动互联开发》 课程作业 学院: 班级: 学号: 姓名: 日期: 设计要求(提交文档时需删除): 1.本课程设计作为《Android 程序设计》的期末考查内容。 2.任务安排: (1)确定内容:11月3日前将确定内容,雷同内容进行微调(功能,实习,界面)。https://blog.csdn.net/m0_66999594/article/details/135196504
4.多功能美食菜谱APP方案设计毕业设计论文.pdf多功能美食菜谱APP方案设计毕业设计论文.pdf,摘要 本设计主要针对Android移动平台多功能美食彩票系统进行分 析和设计。设计一款基于Android的一款多功能菜谱软件,客户通过 手机能够获取美食菜谱、食材信息、健康资讯、在线社区以及线上、 线下互动服务。本次APP设计以内容https://max.book118.com/html/2021/0107/8062106036003035.shtm
5.爱厨房app官方下载安装爱厨房菜谱软件下载v1.0.1安卓版爱厨房菜谱软件操作简单,拥有精致的界面设计和丰富的菜谱分享,用户可以随时随地查看感兴趣的菜肴,并跟随详细的图文、视频掌握其步骤,并亲自尝试,完成各种美味佳肴,分享给亲朋好友们吧。 爱厨房app介绍: 人世间,唯有爱与美食不可辜负,爱已经辜负的太多了,美食就不能再辜负了。 爱厨房提供丰富的菜谱、食谱和详细的图文https://m.itmop.com/downinfo/241691.html
6.大众性菜谱软件,汇集了来自全国各地的数十万道家常菜–APP喵APP喵前言:一款实用性强、内容丰富的Android菜谱应用,提供全国各地的家常菜食谱,界面简洁,易于上手,适合各类烹饪爱好者。 软件简介 家常菜做法V3.3.69是一款专为安卓用户设计的实用菜谱应用,提供丰富多样的家常菜食谱,特色在于所有内容完全免费,界面简洁易用,并具备首页推荐和强大的搜索功能,帮助用户轻松找到并学习制作美https://www.appmiu.com/26091.html
7.食谱类APP竞品分析(下厨房,美食杰)4.在菜谱具体内容方面,下厨房的优点在于其可以上传视频而不仅是图片作为参考,而美食杰多了标签功能,作者可根据情况设置菜谱的工艺难度 ,口味和耗时,在其他用户查找菜谱时筛选更加便捷,也符合其自身宣传的优秀搜索功能,同时通过加大对内容提供者的鼓励而让他们愿意多忍耐一些上传操作,提高了食谱的质量和精度;而下厨房的标签https://www.jianshu.com/p/3a2e0c8aa597