Flutter控件之MaterialApp和Scaffold

Stella981
• 阅读 753

MaterialApp

见名思其意,材料设计类型的App,在安卓5.0正式加入一些材料设计类型的组件之后,App风格也越来越趋向于材料设计类型。MaterialApp就是符合材料设计理念的App框架级Widget。它其实也是一个Widget。它由主题,title,路由,主页等。以下是其构造方法:

  1. const MaterialApp({

  2. Key key,

  3. //导航键

  4. this.navigatorKey,

  5. //主页,应用默认所显示的界面 Widget

  6. this.home,

  7. //路由,应用的顶级导航表格,这个是多页面应用用来控制页面跳转的,类似于网页的网址

  8. this.routes = const <String, WidgetBuilder>{},

  9. //初始路由,第一个显示的路由名字,默认值为 Window.defaultRouteName

  10. this.initialRoute,

  11. //生成路由,生成路由的回调函数,当导航的命名路由的时候,会使用这个来生成界面

  12. this.onGenerateRoute,

  13. //未知路由

  14. this.onUnknownRoute,

  15. //导航观察器,应用 Navigator 的监听器

  16. this.navigatorObservers = const <NavigatorObserver>[],

  17. //构造者

  18. this.builder,

  19. //标题,在任务管理窗口中所显示的应用名字

  20. this.title = '',

  21. //生成标题

  22. this.onGenerateTitle,

  23. //颜色,应用的主要颜色值(primary color),也就是安卓任务管理窗口中所显示的应用颜色

  24. this.color,

  25. //主题,应用各种 UI 所使用的主题颜色

  26. this.theme,

  27. this.darkTheme,

  28. this.themeMode = ThemeMode.system,

  29. //地域,国际化

  30. this.locale,

  31. //本地化委托

  32. this.localizationsDelegates,

  33. //区域分辨率回调

  34. this.localeListResolutionCallback,

  35. this.localeResolutionCallback,

  36. //支持区域

  37. this.supportedLocales = const <Locale>[Locale('en', 'US')],

  38. //调试显示材质网格,是否显示 纸墨设计 基础布局网格,用来调试 UI 的工具

  39. this.debugShowMaterialGrid = false,

  40. //显示性能标签

  41. this.showPerformanceOverlay = false,

  42. this.checkerboardRasterCacheImages = false,

  43. this.checkerboardOffscreenLayers = false,

  44. this.showSemanticsDebugger = false,

  45. this.debugShowCheckedModeBanner = true,

  46. })

主页

一个用来定义打开应用时候显示的第一个Widget界面。如:

  1. class MaterialMyApp extends StatelessWidget {

  2. @override

  3. Widget build(BuildContext context) {

  4. return MaterialApp(

  5. title: "我是Flutter标题",

  6. theme: ThemeData(

  7. primaryColor: Colors.redAccent,

  8. ),

  9. home:Center(

  10. child: Text("Hello Flutter",style: TextStyle(fontSize: 20),),

  11. )

  12. //MyHomePage(),

  13. ,debugShowMaterialGrid: true,

  14. );

  15. }

  16. }

效果图

Flutter控件之MaterialApp和Scaffold

title

任务窗口中,APP显示的标题名字。如:

  1. class MaterialMyApp extends StatelessWidget {

  2. @override

  3. Widget build(BuildContext context) {

  4. return MaterialApp(

  5. title: "我是Flutter标题",

  6. theme: ThemeData(

  7. primaryColor: Colors.redAccent,

  8. ),

  9. home:MyHomePage(),

  10. );

  11. }

  12. }

路由

Map 类型,是应用的顶级路由表。当我们再使用Navigator.pushNamed进行命名路由的跳转时,会在此路表中进行查找并跳转。如果你的应用程序只有一个页面,则无需使用routes,直接指定home对应的Widget即可。如:

  1. class MaterialMyApp extends StatelessWidget {

  2. @override

  3. Widget build(BuildContext context) {

  4. return MaterialApp(

  5. title: "我是Flutter标题",

  6. routes: <String,WidgetBuilder>{

  7. "/first":(BuildContext context)=>FirstPage(),

  8. "/second":(BuildContext context)=>SecondPage()

  9. },

  10. theme: ThemeData(

  11. primaryColor: Colors.redAccent,

  12. ),

  13. home:/*Center(

  14. child: Text("Hello Flutter",style: TextStyle(fontSize: 20),),

  15. )*/FirstPage()

  16. ,

  17. debugShowMaterialGrid: false,

  18. );

  19. }

  20. }

  21. class FirstPage extends StatelessWidget {

  22. @override

  23. Widget build(BuildContext context) {

  24. return Scaffold(

  25. appBar: AppBar(

  26. title: Text("第一页"),

  27. ),

  28. body: Center(

  29. child: RaisedButton(onPressed:(){

  30. Navigator.pushNamed(context, '/second');

  31. },child: Text("跳转到第二页"),),

  32. ),

  33. );

  34. }

  35. }

  36. class SecondPage extends StatelessWidget {

  37. @override

  38. Widget build(BuildContext context) {

  39. return Scaffold(

  40. appBar: AppBar(

  41. title: Text("第二页"),

  42. ),

  43. body: Center(

  44. child: RaisedButton(onPressed:(){

  45. Navigator.of(context).pop(context);

  46. },child: Text("返回到第一页"),),

  47. ),

  48. );

  49. }

  50. }

效果图

Flutter控件之MaterialApp和Scaffold

Flutter控件之MaterialApp和Scaffold

国际化

详见Flutter国际化实现记录

Scaffold

Scaffold是一个路由页的骨架,同样也是Material组件,主要有底部导航,顶部导航,侧面抽屉布局导航。

构造方法

  1. const Scaffold({

  2. Key key,

  3. this.appBar,//设置应用栏,显示在脚手架顶部

  4. this.body,//展示页面的内容

  5. this.floatingActionButton,//设置悬浮于上层区域的按钮

  6. this.floatingActionButtonLocation,//设置floatingActionButton的位置

  7. this.floatingActionButtonAnimator,

  8. this.persistentFooterButtons,

  9. this.drawer,//设置左边侧边栏

  10. this.endDrawer,//设置右边侧边栏

  11. this.bottomNavigationBar,//底部导航栏

  12. this.bottomSheet,//底部抽屉栏

  13. this.backgroundColor,//背景颜色

  14. this.resizeToAvoidBottomPadding,//自动适应底部padding

  15. this.resizeToAvoidBottomInset,

  16. this.primary = true,

  17. this.drawerDragStartBehavior = DragStartBehavior.start,

  18. this.extendBody = false,

  19. this.drawerScrimColor,

  20. })

下面是一个常用的页面导航,包括appBar,drawer,还有bottomNavigationBar。

效果图

Flutter控件之MaterialApp和Scaffold

Flutter控件之MaterialApp和Scaffold

appBar

AppBar是一个Material风格的导航栏,通过它可以设置导航栏标题、导航栏菜单、导航栏底部的Tab标题。

其常用属性
  1. AppBar({

  2. Key key,

  3. this.leading, //导航栏最左侧Widget,常见为抽屉菜单按钮或返回按钮。

  4. this.automaticallyImplyLeading = true, //如果leading为null,是否自动实现默认的leading按钮

  5. this.title,// 页面标题

  6. this.actions, // 导航栏右侧菜单

  7. this.bottom, // 导航栏底部菜单,通常为Tab按钮组

  8. this.elevation = 4.0, // 导航栏阴影

  9. this.centerTitle, //标题是否居中

  10. this.backgroundColor,//背景颜色

  11. ...

  12. })

以上示意图AppBar代码。

  1. appBar: new AppBar(

  2. title:new Text("FlutterStudy"),

  3. centerTitle: true,

  4. actions: <Widget>[

  5. IconButton(icon: Icon(Icons.share), onPressed: (){

  6. _scaffoldKey.currentState.showSnackBar(SnackBar(content:Text("点击了分享!")));

  7. })

  8. ],

  9. ),

Flutter控件之MaterialApp和Scaffold

drawer

Scaffold的drawer和endDrawer属性可以分别接受一个Widget来作为页面的左、右抽屉菜单。如果开发者提供了抽屉菜单,那么当用户手指从屏幕左(或右)侧向里滑动时便可打开抽屉菜单。如果给Scaffold添加了抽屉菜单,默认情况下Scaffold会自动将AppBar的leading设置为菜单按钮。

  1. drawer: new Drawer(

  2. child: new DrawerPage(),//提供一个Widget

  3. ),

Flutter控件之MaterialApp和Scaffold

bottomNavigationBar

  • BottomNavigationBar 常用的底部导航控件,还有一种BottomAppBar控件,它和FloatingActionButton配合实现底部不规则导航。
  1. new BottomNavigationBar(

  2. items: [

  3. new BottomNavigationBarItem(

  4. icon: new Icon(Icons.home),

  5. title: new Text("Home")

  6. ),

  7. new BottomNavigationBarItem(

  8. icon: new Icon(Icons.phone_android),

  9. title: new Text("Android")

  10. ),

  11. new BottomNavigationBarItem(

  12. icon: new Icon(Icons.phone_iphone),

  13. title: new Text("iOS")

  14. ),

  15. new BottomNavigationBarItem(

  16. icon: new Icon(Icons.settings),

  17. title: new Text("Setting")

  18. ),

  19. ],

  20. type: BottomNavigationBarType.fixed,

  21. currentIndex: _curIndex,

  22. onTap: (index){

  23. setState(() {

  24. _curIndex=index;

  25. });

  26. },

  27. )

Flutter控件之MaterialApp和Scaffold

  • BottomAppBar
  1. BottomAppBar(

  2. color: Colors.white,

  3. shape: CircularNotchedRectangle(), // 底部导航栏打一个圆形的洞

  4. child: Row(

  5. children: [

  6. IconButton(icon: Icon(Icons.home),onPressed: (){

  7. setState(() {

  8. _curIndex=0;

  9. });

  10. },),

  11. IconButton(icon: Icon(Icons.phone_iphone),onPressed: (){

  12. setState(() {

  13. _curIndex=1;

  14. });

  15. },),

  16. SizedBox(), //中间位置空出

  17. IconButton(icon: Icon(Icons.phone_iphone),onPressed: (){

  18. setState(() {

  19. _curIndex=2;

  20. });

  21. },),

  22. IconButton(icon: Icon(Icons.settings),onPressed: (){

  23. setState(() {

  24. _curIndex=3;

  25. });

  26. },),

  27. ],

  28. mainAxisAlignment: MainAxisAlignment.spaceAround, //均分底部导航栏横向空间

  29. ),

  30. ),

  31. floatingActionButton:isNormalShow?null: FloatingActionButton(onPressed: (){

  32. },backgroundColor: Colors.redAccent,

  33. child: Icon(Icons.add),),

  34. floatingActionButtonLocation:isNormalShow?null: FloatingActionButtonLocation.centerDocked,//设置floatingActionButton的位置

控制isNormalShow属性控制显示不同的底部导航。

Flutter控件之MaterialApp和Scaffold

Flutter控件之MaterialApp和Scaffold

完整代码

  1. import 'package:flutter/material.dart';

  2. class MyScaffold1 extends StatelessWidget {

  3. @override

  4. Widget build(BuildContext context) {

  5. return MaterialApp(

  6. title: "我是标题",

  7. theme: ThemeData(

  8. primaryColor: Colors.redAccent

  9. ),

  10. home: HomePage(),

  11. );

  12. }

  13. }

  14. class HomePage extends StatefulWidget {

  15. @override

  16. _HomePage createState() => _HomePage();

  17. }

  18. class _HomePage extends State<HomePage>{

  19. final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  20. int _curIndex=0;

  21. List<ContentPage> contents=new List();

  22. bool isNormalShow=true;

  23. @override

  24. void initState() {

  25. // TODO: implement initState

  26. super.initState();

  27. contents.add(new ContentPage(content:"Home"));

  28. contents.add(new ContentPage(content:"Android"));

  29. contents.add(new ContentPage(content:"iOS"));

  30. contents.add(new ContentPage(content:"Setting"));

  31. }

  32. @override

  33. void dispose() {

  34. // TODO: implement dispose

  35. super.dispose();

  36. }

  37. @override

  38. Widget build(BuildContext context) {

  39. // TODO: implement build

  40. return new Scaffold(

  41. key: _scaffoldKey,

  42. appBar: new AppBar(

  43. title:new Text("FlutterStudy"),

  44. centerTitle: true,

  45. actions: <Widget>[

  46. IconButton(icon: Icon(Icons.share), onPressed: (){

  47. _scaffoldKey.currentState.showSnackBar(SnackBar(content:Text("点击了分享!")));

  48. })

  49. ],

  50. ),

  51. drawer: new Drawer(

  52. child: new DrawerPage(),

  53. ),

  54. body: contents[_curIndex],

  55. bottomNavigationBar:isNormalShow? new BottomNavigationBar(

  56. items: [

  57. new BottomNavigationBarItem(

  58. icon: new Icon(Icons.home),

  59. title: new Text("Home")

  60. ),

  61. new BottomNavigationBarItem(

  62. icon: new Icon(Icons.phone_android),

  63. title: new Text("Android")

  64. ),

  65. new BottomNavigationBarItem(

  66. icon: new Icon(Icons.phone_iphone),

  67. title: new Text("iOS")

  68. ),

  69. new BottomNavigationBarItem(

  70. icon: new Icon(Icons.settings),

  71. title: new Text("Setting")

  72. ),

  73. ],

  74. type: BottomNavigationBarType.fixed,

  75. currentIndex: _curIndex,

  76. onTap: (index){

  77. setState(() {

  78. _curIndex=index;

  79. });

  80. },

  81. ):BottomAppBar(

  82. color: Colors.white,

  83. shape: CircularNotchedRectangle(), // 底部导航栏打一个圆形的洞

  84. child: Row(

  85. children: [

  86. IconButton(icon: Icon(Icons.home),onPressed: (){

  87. setState(() {

  88. _curIndex=0;

  89. });

  90. },),

  91. IconButton(icon: Icon(Icons.phone_iphone),onPressed: (){

  92. setState(() {

  93. _curIndex=1;

  94. });

  95. },),

  96. SizedBox(), //中间位置空出

  97. IconButton(icon: Icon(Icons.phone_iphone),onPressed: (){

  98. setState(() {

  99. _curIndex=2;

  100. });

  101. },),

  102. IconButton(icon: Icon(Icons.settings),onPressed: (){

  103. setState(() {

  104. _curIndex=3;

  105. });

  106. },),

  107. ],

  108. mainAxisAlignment: MainAxisAlignment.spaceAround, //均分底部导航栏横向空间

  109. ),

  110. ),

  111. floatingActionButton:isNormalShow?null: FloatingActionButton(onPressed: (){

  112. },backgroundColor: Colors.redAccent,

  113. child: Icon(Icons.add),),

  114. floatingActionButtonLocation:isNormalShow?null: FloatingActionButtonLocation.centerDocked,

  115. );

  116. }

  117. }

  118. class DrawerWidget extends StatefulWidget {

  119. @override

  120. State<StatefulWidget> createState() {

  121. // TODO: implement createState

  122. return new _DrawerWidgetStage();

  123. }

  124. }

  125. class _DrawerWidgetStage extends State<DrawerWidget> {

  126. @override

  127. Widget build(BuildContext context) {

  128. // TODO: implement build

  129. return new ListView(

  130. padding: const EdgeInsets.only(),

  131. children: <Widget>[

  132. new UserAccountsDrawerHeader(

  133. accountName: new Text("HuangSir"),

  134. accountEmail: new Text("1244914544@qq.com"),

  135. currentAccountPicture: new CircleAvatar(

  136. backgroundImage: new NetworkImage(

  137. "http://img.52z.com/upload/news/image/20181108/20181108204521_83402.jpg"),

  138. ),

  139. ),

  140. _getListTitle("lifecycle 学习", "/LifecyclePage"),

  141. new Divider(),

  142. _getListTitle("Route 学习0", "/RoutePage0"),

  143. new Divider(),

  144. _getListTitle("Route 学习1", "/RoutePage1"),

  145. ],

  146. );

  147. }

  148. ListTile _getListTitle(String title, String route) {

  149. return new ListTile(

  150. title: new Text(title),

  151. trailing: new Icon(Icons.arrow_right),

  152. onTap: () {

  153. Navigator.of(context).pop();

  154. Navigator.pushNamed(context, route);

  155. },

  156. );

  157. }

  158. }

  159. class DrawerPage extends StatelessWidget {

  160. @override

  161. Widget build(BuildContext context) {

  162. // TODO: implement build

  163. return new Scaffold(

  164. body: new DrawerWidget(),

  165. );

  166. }

  167. }

  168. //内容页

  169. class ContentPage extends StatelessWidget {

  170. final String content;

  171. const ContentPage({Key key, this.content}) : super(key: key);

  172. @override

  173. Widget build(BuildContext context) {

  174. return Center(

  175. child: Text(this.content),

  176. );

  177. }

  178. }

还有一种底部导航配合PageView实现的常用的App框架。但是每次点击页面都会调用页面的initState方法,其解决方法是使其内容页 with AutomaticKeepAliveClientMixin,实现

  1. @override

  2. // TODO: implement wantKeepAlive

  3. bool get wantKeepAlive => true;

即可。

效果图

Flutter控件之MaterialApp和Scaffold

完整代码

  1. import 'package:flutter/material.dart';

  2. class MaterialMyApp extends StatelessWidget {

  3. @override

  4. Widget build(BuildContext context) {

  5. return MaterialApp(

  6. title: "我是Flutter标题",

  7. routes: <String, WidgetBuilder>{

  8. "/first": (BuildContext context) => FirstPage(),

  9. "/second": (BuildContext context) => SecondPage()

  10. },

  11. theme: ThemeData(

  12. primaryColor: Colors.redAccent,

  13. ),

  14. home: MyHomePage(),

  15. debugShowMaterialGrid: false,

  16. );

  17. }

  18. }

  19. class FirstPage extends StatelessWidget {

  20. @override

  21. Widget build(BuildContext context) {

  22. return Scaffold(

  23. appBar: AppBar(

  24. title: Text("第一页"),

  25. ),

  26. body: Center(

  27. child: RaisedButton(

  28. onPressed: () {

  29. Navigator.pushNamed(context, '/second');

  30. },

  31. child: Text("跳转到第二页"),

  32. ),

  33. ),

  34. );

  35. }

  36. }

  37. class SecondPage extends StatelessWidget {

  38. @override

  39. Widget build(BuildContext context) {

  40. return Scaffold(

  41. appBar: AppBar(

  42. title: Text("第二页"),

  43. ),

  44. body: Center(

  45. child: RaisedButton(

  46. onPressed: () {

  47. Navigator.of(context).pop(context);

  48. },

  49. child: Text("返回到第一页"),

  50. ),

  51. ),

  52. );

  53. }

  54. }

  55. ///

  56. /// 主页

  57. ///

  58. class MyHomePage extends StatefulWidget {

  59. @override

  60. _MyHomePageState createState() => _MyHomePageState();

  61. }

  62. class _MyHomePageState extends State<MyHomePage> {

  63. var _curIndex = 0;

  64. var _pagerController = new PageController(initialPage: 0);

  65. List<String> _tabs = ["Gank", "Widgets", "Example", "Setting"];

  66. @override

  67. void initState() {

  68. super.initState();

  69. }

  70. @override

  71. void dispose() {

  72. super.dispose();

  73. }

  74. @override

  75. Widget build(BuildContext context) {

  76. return Scaffold(

  77. body: new PageView.builder(

  78. itemBuilder: (BuildContext context, int index) {

  79. return _buildPageItem(context, index);

  80. },

  81. itemCount: _tabs.length,

  82. controller: _pagerController,

  83. onPageChanged: (index) {

  84. _onChangePageView(index);

  85. },

  86. ),

  87. bottomNavigationBar: BottomNavigationBar(

  88. items: [

  89. _buildBottomItem(Icons.home, _tabs[0]),

  90. _buildBottomItem(Icons.widgets, _tabs[1]),

  91. _buildBottomItem(Icons.ac_unit, _tabs[2]),

  92. _buildBottomItem(Icons.settings, _tabs[3]),

  93. ],

  94. currentIndex: _curIndex,

  95. type: BottomNavigationBarType.fixed,

  96. onTap: (index) {

  97. _pagerController.animateToPage(index,

  98. duration: const Duration(milliseconds: 300), curve: Curves.ease);

  99. },

  100. ),

  101. );

  102. }

  103. void _onChangePageView(int index) {

  104. setState(() {

  105. _curIndex = index;

  106. });

  107. }

  108. Widget _buildPageItem(BuildContext context, int index) {

  109. return ContentWidget(content: _tabs[index]);

  110. }

  111. BottomNavigationBarItem _buildBottomItem(IconData iconData, String tab) {

  112. return new BottomNavigationBarItem(icon: Icon(iconData), title: Text(tab));

  113. }

  114. }

  115. ///

  116. /// 内容页面

  117. ///

  118. class ContentWidget extends StatefulWidget {

  119. final String content;

  120. const ContentWidget({Key key, this.content}) : super(key: key);

  121. @override

  122. State<StatefulWidget> createState() {

  123. // TODO: implement createState

  124. return new __ContentWidgetStage();

  125. }

  126. }

  127. class __ContentWidgetStage extends State<ContentWidget>

  128. with AutomaticKeepAliveClientMixin {

  129. @override

  130. void initState() {

  131. // TODO: implement initState

  132. super.initState();

  133. print("initState===>" + this.widget.content);

  134. }

  135. @override

  136. Widget build(BuildContext context) {

  137. // TODO: implement build

  138. return Scaffold(

  139. appBar: AppBar(

  140. title: Text(this.widget.content),

  141. ),

  142. body: Center(

  143. child: Text(

  144. this.widget.content,

  145. style: TextStyle(color: Colors.redAccent),

  146. ),

  147. ),

  148. );

  149. }

  150. @override

  151. // TODO: implement wantKeepAlive

  152. bool get wantKeepAlive => true;

  153. }

本文分享自微信公众号 - Flutter学习簿(gh_d739155d3b2c)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
浩浩 浩浩
3年前
【Flutter实战】Widget简介
3.1Widget简介3.1.1概念在前面的介绍中,我们知道在Flutter中几乎所有的对象都是一个Widget。与原生开发中“控件”不同的是,Flutter中的Widget的概念更广泛,它不仅可以表示UI元素,也可以表示一些功能性的组件如:用于手势检测的GestureDetectorwidget、用于APP主题数据传递的Theme
浩浩 浩浩
3年前
【Flutter实战】布局类组件简介
4.1布局类组件简介布局类组件都会包含一个或多个子组件,不同的布局类组件对子组件排版(layout)方式不同。我们在前面说过Element树才是最终的绘制树,Element树是通过Widget树来创建的(通过Widget.createElement()),Widget其实就是Element的配置数据。在Flutter中,根据Widget是否
Stella981 Stella981
3年前
React PC端框架
1\.AntDesignAntDesign是阿里巴巴团队出品的ReactUI组件库。有自己独特的设计风格和理念。非常符合国人的审美需求。并且在支付宝、蚂蚁金服等多个阿里项目中投入使用。组件化质量非常高,开箱即用。支持浏览器、服务端渲染以及Electron环境。包括刚刚推出支付宝小程序也是这一套设计风格。可谓国人开发Re
Stella981 Stella981
3年前
Flutter RefreshIndicator 下拉刷新组件 Material 风格的刷新效果
题记——优美的应用体验来自于细节的处理,更源自于码农的自我要求与努力,当然也需要码农年轻灵活的思维。<p盘点Flutter跨平台APP开发中使用到的进度条</p</div<p/<pFlutter是谷歌推出的最新的移动开发框架。RefreshIndicator是Material风格的滑动刷新Widget
Stella981 Stella981
3年前
Flutter在IOS环境下文本选择弹窗崩溃问题
中文IOS环境下,如果App里配置了中文Locale,长按文本会崩溃,这个问题是由于‘复制、粘贴’弹窗使用了cupertino控件,即使是在MaterialApp里。而现在cupertino不支持多语言(13452(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.co
APP开发流程注意事项有哪些
APP开发的定义固然简单,但对于精益求精的开发者们来说,在制作完成一件完美的APP之前,总是要历经无穷无尽的反复思考,从APP的首轮设计规划阶段、再到APP的填充修缮环节,再到最终的生成发布。   一、纸上阶段  每个APP在在正式上架之前都要经历“纸上”(或屏幕上)的阶段。这一设计阶段决定了APP的整体框架结构,后续的所有工作都是围绕着它来展开的。因此,这
流浪剑客 流浪剑客
1年前
Macos多视图文件管理工具:QSpace Pro for Mac中文版
是一款高度专业化的软件,它主要用于进行量子化学和材料科学计算。以下是它的主要特点:高效能计算:QSpacePro使用了最先进的算法和计算技术,可以快速准确地执行大规模的量子化学和材料科学计算。广泛的用途:QSpacePro可以用于多种类型的计算,包括从头算
绣鸾 绣鸾
1年前
ArchiCAD 26 for Mac(三维建筑设计软件)
是一款专业的建筑设计和BIM(建筑信息模型)软件,由Graphisoft公司开发。以下是该软件的一些主要特色:强大的建模和设计工具:ArchiCAD26提供了全面的设计和建模工具,包括自动屋顶、柱、梁等的生成,以及灵活的参数化设计工具,可以快速创建各种类型
流浪剑客 流浪剑客
1年前
三维建筑设计软件:ArchiCAD 26 最新版 支持M1
是一款专业的建筑设计和BIM(建筑信息模型)软件,由Graphisoft公司开发。以下是该软件的一些主要特色:强大的建模和设计工具:ArchiCAD26提供了全面的设计和建模工具,包括自动屋顶、柱、梁等的生成,以及灵活的参数化设计工具,可以快速创建各种类型