From 0874ee5f767f910682498aeefe3a26a0a92de140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=A5=E8=BF=9C=E6=98=9F?= <1050431815@qq.com> Date: Thu, 28 Apr 2022 03:41:42 +0800 Subject: [PATCH 01/29] no commit message --- web/py_lib/flutter.py | 90 ++++++++++++++++++++++++++++++++++++ web/py_lib/flutter_test_2.py | 25 ++++++++-- 2 files changed, 111 insertions(+), 4 deletions(-) diff --git a/web/py_lib/flutter.py b/web/py_lib/flutter.py index 46d0d85..ae58b54 100755 --- a/web/py_lib/flutter.py +++ b/web/py_lib/flutter.py @@ -554,6 +554,95 @@ class Icon: e.appendChild(javascript.document.createTextNode(self.icon)) return e +class ListTile: + def __init__(self, leading=None, title=None): + if leading is not None: + assert hasattr(leading, 'render') and callable(leading.render) + if title is not None: + assert hasattr(title, 'render') and callable(title.render) + self.leading = leading + self.title = title + + def render(self): + e = maketag('li', {'class':'mdc-list-item'}) + e1 = maketag('span',{'class':'mdc-list-item__ripple'}) + e.appendChild(e1) + if self.leading is not None: + leading = self.leading.render() + #add_class(leading, 'mdc-list-item__graphic') + e.appendChild(leading) + if self.title is not None: + title = self.title.render() + add_class(title, 'mdc-list-item__text') + e.appendChild(title) + return e + +class ListView: + def __init__(self, children=None): + if children is not None: + for tmp in children: + assert hasattr(tmp, 'render') and callable(tmp.render) + self.children = children + + def render(self): + e = maketag('ul', {'class':'mdc-list'}) + if self.children is not None: + for tmp in self.children: + e.appendChild(tmp.render()) + return e + +class Tab: + def __init__(self, text=None, icon=None): + if text is not None: + assert hasattr(text, 'render') and callable(text.render) + if icon is not None: + assert hasattr(icon, 'render') and callable(icon.render) + self.text = text + self.icon = icon + + def render(self): + if True: + e = maketag('button', {'class':'mdc-tab mdc-tab--active','role':'tab','aria-selected':'true'}) + e1 = maketag('span', {'class':'mdc-tab__content'}) + e.appendChild(e1) + e2 = maketag('span', {'class':'mdc-tab-indicator mdc-tab-indicator--active'}) + e.appendChild(e2) + e3 = maketag('span', {'class':'mdc-tab-indicator__content mdc-tab-indicator__content--underline'}) + e2.appendChild(e3) + e4 = maketag('span', {'class':'mdc-tab__ripple'}) + e.appendChild(e4) + + if self.icon is not None: + icon = self.icon.render() + add_class(icon, 'mdc-tab__icon material-icons') + e1.appendChild(icon) + if self.text is not None: + text = self.text.render() + add_class(text, 'mdc-tab__text-label') + e1.appendChild(text) + return e + +class TabBar: + def __init__(self, tabs=None): + if tabs is not None: + for tmp in tabs: + assert hasattr(tmp, 'render') and callable(tmp.render) + self.tabs = tabs + + def render(self): + e = maketag('div', {'class':'mdc-tab-bar','role':'tablist'}) + if True: + e1 = maketag('div', {'class':'mdc-tab-scroller'}) + e.appendChild(e1) + e2 = maketag('div', {'class':'mdc-tab-scroller__scroll-area'}) + e1.appendChild(e2) + e3 = maketag('div', {'class':'mdc-tab-scroller__scroll-content'}) + e2.appendChild(e3) + + if self.tabs is not None: + for tmp in self.tabs: + e3.appendChild(tmp.render()) + return e from . import flutter_icons Icons = flutter_icons.Icons @@ -576,3 +665,4 @@ Icons = flutter_icons.Icons # https://material.io/components/tabs # https://material.io/components/text-fields # https://material.io/components/tooltips + diff --git a/web/py_lib/flutter_test_2.py b/web/py_lib/flutter_test_2.py index f80538c..c0eb00e 100755 --- a/web/py_lib/flutter_test_2.py +++ b/web/py_lib/flutter_test_2.py @@ -25,8 +25,13 @@ AppBar = flutter.AppBar IconButton = flutter.IconButton Icon = flutter.Icon Icons = flutter.Icons - +ListTile = flutter.ListTile +ListView = flutter.ListView +Tab = flutter.Tab +TabBar = flutter.TabBar # https://flutter.cn/docs/development/ui/widgets-intro + + def 使用Material组件(): return Scaffold( appBar=AppBar( @@ -44,9 +49,21 @@ def 使用Material组件(): ), # body is the majority of the screen. body=Container( - Center( - child=Text('Hello, world!'), - ), + child=Stack(children=[Positioned(child=ListView( + children=[ + ListTile(leading=Icon(Icons.label),title=Text('Line 1')), + ListTile(leading=Icon(Icons.label),title=Text('Line 2')), + ListTile(leading=Icon(Icons.label),title=Text('Line 3')), + ListTile(leading=Icon(Icons.label),title=Text('Line 4')), + ], + ),left=0,top=0), + Positioned(child=TabBar( + tabs = [ + Tab(icon = Icon(Icons.sync), text = Text('a'), ), + Tab(icon = Icon(Icons.mic), text = Text('b'), ), + Tab(icon = Icon(Icons.mode), text = Text('c'), ), + ], + ),left=18,top=350,),],), width=312, height=480-72, color=Colors.white, -- Gitee From 56a9ce6ebff38c30b9c3b8ece4e5d37efde35544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=A5=E8=BF=9C=E6=98=9F?= <1050431815@qq.com> Date: Thu, 28 Apr 2022 04:42:39 +0800 Subject: [PATCH 02/29] no commit message --- web/index.html | 9 +- web/ipad.html | 20 +++- web/iphone.html | 18 ++- web/py_lib/flutter.py | 207 +++++++++++++++-------------------- web/py_lib/flutter_test_2.py | 2 +- 5 files changed, 119 insertions(+), 137 deletions(-) diff --git a/web/index.html b/web/index.html index bcce34c..fbbd1a3 100755 --- a/web/index.html +++ b/web/index.html @@ -1,11 +1,8 @@ - - + - - @@ -16,10 +13,6 @@ - - diff --git a/web/ipad.html b/web/ipad.html index 72014f9..103c31a 100755 --- a/web/ipad.html +++ b/web/ipad.html @@ -1,6 +1,18 @@ -
+ + + + +iPad + + + + +
- +
-
-
\ No newline at end of file +
+
+ + + \ No newline at end of file diff --git a/web/iphone.html b/web/iphone.html index 7fb96a5..e5994bf 100755 --- a/web/iphone.html +++ b/web/iphone.html @@ -1,6 +1,18 @@ -
+ + + + +iPhone + + + + +
- +
-
\ No newline at end of file +
+ + + \ No newline at end of file diff --git a/web/py_lib/flutter.py b/web/py_lib/flutter.py index ae58b54..3c79418 100755 --- a/web/py_lib/flutter.py +++ b/web/py_lib/flutter.py @@ -124,7 +124,7 @@ class Container: self.margin = margin self.boxShadow = boxShadow self.shape = shape - def render(self): + def render(self, parent): style = {} if self.width is not None: style['width'] = f'{self.width}px' if isinstance(self.width, int) else self.width @@ -149,7 +149,8 @@ class Container: if self.child.textAlign is not None: style['text-align'] = self.child.textAlign e = maketag('div', style=style) - e.appendChild(self.child.render()) + parent.appendChild(e) + self.child.render(e) return e class FontWeight: @@ -214,7 +215,7 @@ class Text: self.style = style self.overflow = overflow self.maxLines = maxLines - def render(self): + def render(self, parent): style = {} if self.style is not None: style['font'] = str(self.style) @@ -234,6 +235,7 @@ class Text: style['-webkit-line-clamp'] = self.maxLines style['-webkit-box-orient'] = 'vertical' e = maketag('div', style=style) + parent.appendChild(e) p = javascript.document.createTextNode(self.text) e.appendChild(p) return e @@ -242,8 +244,8 @@ class RichText: def __init__(self, text): assert isinstance(text, TextSpan) self.text = text - def render(self): - return self.text.render() + def render(self, parent): + return self.text.render(parent) class TextSpan: def __init__(self, text=None, color=None, style=None, children=None): @@ -260,7 +262,7 @@ class TextSpan: self.color = color self.style = style self.children = children - def render(self): + def render(self, parent): style = {} if self.style is not None: style['font'] = str(self.style) @@ -274,22 +276,24 @@ class TextSpan: if self.color is not None: style['color'] = self.color e = maketag('span', style=style) + parent.appendChild(e) if self.text is not None: p = javascript.document.createTextNode(self.text) e.appendChild(p) elif self.children is not None: for c in self.children: - e.appendChild(c.render()) + c.render(e) return e class Center: def __init__(self, child): assert hasattr(child, 'render') and callable(child.render) self.child = child - def render(self): + def render(self, parent): e = maketag('div', style={'display': 'flex', 'align-items': 'center', 'justify-content': 'center', 'width': '100%', 'height': '100%'}) - e.appendChild(self.child.render()) + parent.appendChild(e) + self.child.render(e) return e class Stack: @@ -298,10 +302,11 @@ class Stack: for c in children: assert isinstance(c, Positioned) self.children = children - def render(self): + def render(self, parent): e = maketag('div',style={'position':'relative'}) for c in self.children: - e.appendChild(c.render()) + c.render(e) + parent.appendChild(e) return e class Positioned: @@ -312,11 +317,12 @@ class Positioned: self.child = child self.left = left self.top = top - def render(self): + def render(self, parent): top = f'{self.top}px' if isinstance(self.top, int) else self.top left = f'{self.left}px' if isinstance(self.left, int) else self.left e = maketag('div', style={'position':'absolute','top':top,'left':left}) - e.appendChild(self.child.render()) + parent.appendChild(e) + self.child.render(e) return e class Transform: @@ -327,7 +333,7 @@ class Transform: self.child = child self.rotate = rotate self.scale = scale - def render(self): + def render(self, parent): transform = [] if self.rotate is not None: rotate = f'{self.rotate}deg' if isinstance(self.rotate, int) else self.rotate @@ -335,9 +341,10 @@ class Transform: if self.scale is not None: transform.append(f'scale({self.scale})') e = maketag('div') + parent.appendChild(e) if len(transform)>0: e.style.transform = ' '.join(transform) - e.appendChild(self.child.render()) + self.child.render(e) return e @@ -393,7 +400,7 @@ class Flex: self.mainAxisAlignment = mainAxisAlignment self.crossAxisAlignment = crossAxisAlignment self.mainAxisSize = mainAxisSize - def render(self): + def render(self, parent): style = {'display': 'flex', 'flex-direction': self.direction, 'flex-wrap': 'nowrap', @@ -405,8 +412,9 @@ class Flex: else: style['height'] = '100%' e = maketag('div', style=style) + parent.appendChild(e) for child in self.children: - e.appendChild(child.render()) + child.render(e) return e class Row(Flex): @@ -432,69 +440,27 @@ class Column(Flex): mainAxisSize=mainAxisSize) -# 如何开发 MaterialDesignWidgets (用AppBar作为例子): -# -# 1. 在 https://material.io/components/app-bars-top/flutter -# 找到 AppBar 的 Dart 例子后适当简化并翻译为 Python -# -# Scaffold( -# appBar=AppBar( -# leading=IconButton( -# icon=Icon(Icons.menu), -# onPressed=None, -# ), -# title=Text('Example title'), -# actions=[ -# IconButton( -# icon=Icon(Icons.search), -# onPressed=None, -# ), -# ], -# ), -# # body is the majority of the screen. -# body=Center( -# child=Text('Hello, world!'), -# ), -# ) -# -# 2. 在 https://material.io/components/app-bars-top/web -# 找到 AppBar 的 Web实现: -# -#
-#
-#
-# -# Page title -#
-# -#
-#
-#
-# App content -#
-# -# 3. 设计和实现各个需要的 Python 类: Scaffold, AppBar, IconButton, Icon, Icons +# MDC (Material Design Components) class Scaffold: def __init__(self, appBar, body): - if appBar is not None: - assert hasattr(appBar, 'render') and callable(appBar.render) - if body is not None: - assert hasattr(body, 'render') and callable(body.render) + assert hasattr(appBar, 'render') and callable(appBar.render) + assert hasattr(body, 'render') and callable(body.render) self.appBar = appBar self.body = body - def render(self): - e = maketag('div') - header = maketag('header', {'class':'mdc-top-app-bar'}) + def render(self, parent): + scafflod_height = javascript.document.documentElement.clientHeight.data() + e = maketag('div', style={'display':'flex', 'flex-flow':'column', 'height':f'{scafflod_height}px'}) + header = maketag('header', {'class':'mdc-top-app-bar mdc-top-app-bar--fixed'}, + style={'flex': '0 1 auto'}) + parent.appendChild(e) e.appendChild(header) - main = maketag('header', {'class':'mdc-top-app-bar--fixed-adjust'}) + main = maketag('header', {'class':'mdc-top-app-bar--fixed-adjust'}, + style={'flex': '1 1 auto'}) e.appendChild(main) - header.appendChild(self.appBar.render()) - main.appendChild(self.body.render()) + self.appBar.render(header) + self.body.render(main) + self.topAppBar = javascript.mdc.topAppBar.MDCTopAppBar.new(e) return e class AppBar: @@ -510,25 +476,23 @@ class AppBar: self.leading = leading self.title = title self.actions = actions - def render(self): + def render(self, parent): e = maketag('div', {'class':'mdc-top-app-bar__row'}) + parent.appendChild(e) start = maketag('header', {'class':'mdc-top-app-bar__section mdc-top-app-bar__section--align-start'}) e.appendChild(start) end = maketag('header', {'class':'mdc-top-app-bar__section mdc-top-app-bar__section--align-end', 'rule':'toolbar'}) e.appendChild(end) if self.leading is not None: - leading = self.leading.render() + leading = self.leading.render(start) add_class(leading, 'mdc-top-app-bar__navigation-icon') - start.appendChild(leading) if self.title is not None: - title = self.title.render() + title = self.title.render(start) add_class(title, 'mdc-top-app-bar__title') - start.appendChild(title) if self.actions is not None: for action in self.actions: - action = action.render() + action = action.render(end) add_class(action, 'mdc-top-app-bar__action-item') - end.appendChild(action) return e class IconButton: @@ -538,22 +502,47 @@ class IconButton: assert callable(onPressed) self.icon = icon self.onPressed = onPressed - def render(self): + def render(self, parent): e = maketag('button', {'class':'material-icons mdc-top-app-bar__action-item mdc-icon-button'}) + parent.appendChild(e) e.appendChild(javascript.document.createTextNode(self.icon.icon)) if self.onPressed is not None: e.bind('click', self.onPressed) + javascript.mdc.ripple.MDCRipple.new(e) return e class Icon: def __init__(self, icon): assert isinstance(icon, str) self.icon = icon - def render(self): + def render(self, parent): e = maketag('span', {'class':'material-icons'}) + parent.appendChild(e) e.appendChild(javascript.document.createTextNode(self.icon)) return e +from . import flutter_icons +Icons = flutter_icons.Icons + + +# TODO +# https://material.io/components/banners +# https://material.io/components/buttons +# https://material.io/components/cards +# https://material.io/components/checkboxes +# https://material.io/components/chips +# https://material.io/components/data-tables +# https://material.io/components/dialogs +# https://material.io/components/lists +# https://material.io/components/menus +# https://material.io/components/navigation-drawer +# https://material.io/components/radio-buttons +# https://material.io/components/sheets-side +# https://material.io/components/snackbars +# https://material.io/components/switches +# https://material.io/components/tabs +# https://material.io/components/text-fields +# https://material.io/components/tooltips class ListTile: def __init__(self, leading=None, title=None): if leading is not None: @@ -563,18 +552,16 @@ class ListTile: self.leading = leading self.title = title - def render(self): + def render(self,parent): e = maketag('li', {'class':'mdc-list-item'}) + parent.appendChild(e) e1 = maketag('span',{'class':'mdc-list-item__ripple'}) e.appendChild(e1) if self.leading is not None: - leading = self.leading.render() - #add_class(leading, 'mdc-list-item__graphic') - e.appendChild(leading) + leading = self.leading.render(e) if self.title is not None: - title = self.title.render() + title = self.title.render(e) add_class(title, 'mdc-list-item__text') - e.appendChild(title) return e class ListView: @@ -584,11 +571,12 @@ class ListView: assert hasattr(tmp, 'render') and callable(tmp.render) self.children = children - def render(self): + def render(self,parent): e = maketag('ul', {'class':'mdc-list'}) if self.children is not None: for tmp in self.children: - e.appendChild(tmp.render()) + tmp.render(e) + parent.appendChild(e) return e class Tab: @@ -600,7 +588,7 @@ class Tab: self.text = text self.icon = icon - def render(self): + def render(self,parent): if True: e = maketag('button', {'class':'mdc-tab mdc-tab--active','role':'tab','aria-selected':'true'}) e1 = maketag('span', {'class':'mdc-tab__content'}) @@ -613,13 +601,12 @@ class Tab: e.appendChild(e4) if self.icon is not None: - icon = self.icon.render() + icon = self.icon.render(e1) add_class(icon, 'mdc-tab__icon material-icons') - e1.appendChild(icon) if self.text is not None: - text = self.text.render() + text = self.text.render(e1) add_class(text, 'mdc-tab__text-label') - e1.appendChild(text) + parent.appendChild(e) return e class TabBar: @@ -629,7 +616,7 @@ class TabBar: assert hasattr(tmp, 'render') and callable(tmp.render) self.tabs = tabs - def render(self): + def render(self,parent): e = maketag('div', {'class':'mdc-tab-bar','role':'tablist'}) if True: e1 = maketag('div', {'class':'mdc-tab-scroller'}) @@ -641,28 +628,6 @@ class TabBar: if self.tabs is not None: for tmp in self.tabs: - e3.appendChild(tmp.render()) - return e -from . import flutter_icons -Icons = flutter_icons.Icons - - -# TODO -# https://material.io/components/banners -# https://material.io/components/buttons -# https://material.io/components/cards -# https://material.io/components/checkboxes -# https://material.io/components/chips -# https://material.io/components/data-tables -# https://material.io/components/dialogs -# https://material.io/components/lists -# https://material.io/components/menus -# https://material.io/components/navigation-drawer -# https://material.io/components/radio-buttons -# https://material.io/components/sheets-side -# https://material.io/components/snackbars -# https://material.io/components/switches -# https://material.io/components/tabs -# https://material.io/components/text-fields -# https://material.io/components/tooltips - + tmp.render(e3) + parent.appendChild(e) + return e \ No newline at end of file diff --git a/web/py_lib/flutter_test_2.py b/web/py_lib/flutter_test_2.py index c0eb00e..fc4d066 100755 --- a/web/py_lib/flutter_test_2.py +++ b/web/py_lib/flutter_test_2.py @@ -72,4 +72,4 @@ def 使用Material组件(): def run_app(): widget = 使用Material组件() - javascript.document.body.appendChild(widget.render()) + widget.render(parent=javascript.document.body) -- Gitee From fc83e0ce0790708186dc28afcd645d1774c63ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=A5=E8=BF=9C=E6=98=9F?= <1050431815@qq.com> Date: Thu, 28 Apr 2022 04:43:48 +0800 Subject: [PATCH 03/29] no commit message --- README.md | 7 + web/lib/apple.png | Bin 0 -> 17606 bytes web/lib/mdc_test.html | 2630 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 2637 insertions(+) create mode 100644 README.md create mode 100644 web/lib/apple.png create mode 100644 web/lib/mdc_test.html diff --git a/README.md b/README.md new file mode 100644 index 0000000..a235c08 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# Flutter UI for Python + +#### 代码已更新,请互相通知 2022-04-27 13:29:00 + +- 我发现大部分的 Material Design Component (MDC) 需要配上代码才可以正确显示。 +- 我对 web/py_lib/flutter.py 作了相应的更改 (见454和503行)。 +- 另外我添加了 web/lib/mdc_test.html, 里面展示了大部分的 MDC 控件的使用 (编辑器打开看源代码,双击浏览器打开看效果)。 \ No newline at end of file diff --git a/web/lib/apple.png b/web/lib/apple.png new file mode 100644 index 0000000000000000000000000000000000000000..8427fc61872af437de365c5e4124d33fcc5ceb66 GIT binary patch literal 17606 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 literal 0 HcmV?d00001 diff --git a/web/lib/mdc_test.html b/web/lib/mdc_test.html new file mode 100644 index 0000000..37f8499 --- /dev/null +++ b/web/lib/mdc_test.html @@ -0,0 +1,2630 @@ + + + + + + MDC + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+
+
+ + Fixed top app bars stay at the top of the page and elevate above the content when scrolled +
+ +
+
+
+ + + + + + + + + +

buttons

+ +
+ +
+ + +

Text button

+ + + + +

Text button with icon

+ + + + +

Outlined button

+ + + + +

Outlined button with icon

+ + + + +

Contained button

+ + + + +

Contained button with icon

+ + + + +

To add an icon

+ + + + +

use an SVG icon

+ + + + +

Trailing Icon

+ + + + +

Disabled

+ + + + + +

FAB (floating action button)

+ +
+ +
+ + +

Regular FAB example

+ + + + +

Mini FAB example

+ + + + +

Extended FAB example

+ + + + + + +

Cards

+ +
+
+ + +
+
+ + +

Outlined card with icon buttons

+ +
+
+ + + +
+
+ +

Rich media

+ +
+
+
+
Title
+
+
+
+
+ +

Actions

+ +
+
+
+
Title
+
+
+
+
+ + +
+
+ +

Actions 2

+ +
+
+
+
Title
+
+
+
+
+ + + +
+
+ + +

To have a single action button take up the entire width of the action row

+ + + + +

To display buttons and icons in the same row, wrap them in mdc-card__action-buttons and mdc-card__action-icons elements

+ +
+
+
+ + +
+
+ + +
+
+
+ + +

The following is an example incorporating all of the above elements

+ +
+
+
+
Title
+
+ +
+
+
+
+ + +
+
+ + +
+
+
+ + +

checkboxes

+ +
+
+ +
+ + + +
+
+
+
+
+ + +

Checkbox example

+ +
+
+ +
+ + + +
+
+
+
+ +
+ + +

Disabled checkboxes

+ +
+ +
+ + + +
+
+
+
+ + + +

Indeterminate checkboxes

+ +
+ +
+ + + +
+
+
+
+ + + + + + +

Chips

+ + + + + + + + + + + + + + + + + + + + +

Standard data table

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DessertCarbs (g)Protein (g)Comments
Frozen yogurt244.0Super tasty
Ice cream sandwich374.33333333333I like ice cream more
Eclair246.0New filing flavor
+
+
+ + +

Data table with row selection

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + +
+
+
+
+
Signal nameStatusSeverityStageTimeRoles
+
+ +
+ + + +
+
+
+
+
Arcus watch slowdownOnlineMediumTriaged0:33Allison Brie
+
+ +
+ + + +
+
+
+
+
monarch: prod shared ares-managed-features-provider-heavyOfflineHugeTriaged0:33Brie Larson
+
+ +
+ + + +
+
+
+
+
monarch: prod shared ares-managed-features-provider-heavyOnlineMinorNot triaged0:33Jeremy Lake
+
+ +
+ + + +
+
+
+
+
Arcus watch slowdownOnlineNegligibleTriaged0:33Angelina Cheng
+
+
+ +

Data table with pagination

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DessertCarbs (g)Protein (g)Comments
Frozen yogurt244.0Super tasty
Ice cream sandwich374.33333333333I like ice cream more
Eclair246.0New filing flavor
+
+ +
+
+
+
+ Rows per page +
+ +
+
+ + 10 + + + + + + + + + + + + + +
+ +
+
    +
  • + 10 +
  • +
  • + 25 +
  • +
  • + 100 +
  • +
+
+
+
+ +
+
+ 1‑10 of 100 +
+ + + + +
+
+
+
+ +

Data table with progress indicator

+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DessertCarbs (g)Protein (g)Comments
Frozen yogurt244.0Super tasty
Ice cream sandwich374.33333333333I like ice cream more
Eclair246.0New filing flavor
+
+ +
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+ +

Data table with column sorting

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ Dessert +
+ + +
+
+
+ +
+ Carbs (g) +
+ +
+
+
+ +
+ Protein (g) +
+ +
+
+ Comments +
Frozen yogurt + 24 + + 4.0 + Super tasty
Bread + 10 + + 8.0 + Super tasty
+
+ + + + + +

Alert dialog

+ +
+
+
+
+ Discard draft? +
+
+ + +
+
+
+
+
+ + + + + + +

Simple dialog

+ +
+
+
+ +

Choose a Ringtone

+
+
    +
  • + None +
  • +
  • + Callisto +
  • + +
+
+
+
+
+
+ + + + +

Confirmation dialog

+ +
+
+
+ +

Choose a Ringtone

+
+
    +
  • + +
    + +
    +
    +
    +
    +
    +
    + +
  • + +
+
+
+ + +
+
+
+
+
+ + + + +

Full-screen dialog

+ + +
+
+ +
+
+
+ + + + +

Banner

+ + + + + + +

Fixed Banner

+ + + + + + + +

Banner with graphic

+ + + + + + + +

Banner with two actions

+ + + + + + +

Standard Image List

+ +
    +
  • +
    + +
    +
    + Label 1 +
    +
  • +
  • +
    + +
    +
    + Label 2 +
    +
  • +
+ + + +

Masonry Image List

+ +
    +
  • + +
    + Text 1 +
    +
  • +
  • + +
    + Text 2 +
    +
  • +
+ + +

Single-line list

+ +
    +
  • + + Single-line item +
  • +
  • + + Single-line item +
  • +
  • + + Single-line item +
  • +
+ + +

Two-line list

+ +
    +
  • + + + Two-line item + Secondary text + +
  • +
  • + + + Two-line item + Secondary text + +
  • +
  • + + + Two-line item + Secondary text + +
  • +
+ + +

List Groups

+ +
+

List 1

+
    +
  • + + line item +
  • +
  • + + line item +
  • +
  • + + line item +
  • +
+

List 2

+
    +
  • + + line item +
  • +
  • + + line item +
  • +
  • + + line item +
  • +
+
+ + +

List Dividers

+ +
    +
  • + + Item 1 - Division 1 +
  • +
  • + + Item 2 - Division 1 +
  • + +
  • + + Item 1 - Division 2 +
  • +
  • + + Item 2 - Division 2 +
  • +
+ + +

List Dividers 2

+ +
    +
  • + Item 1 - List 1 +
  • +
  • + Item 2 - List 1 +
  • +
+
+
    +
  • + Item 1 - List 2 +
  • +
  • + Item 2 - List 2 +
  • +
+ + +

Single Selection List

+ +
    +
  • + + Single-line item +
  • +
  • + + Single-line item +
  • +
  • + + Single-line item +
  • +
+ + +

Pre-selected list item

+ +
    +
  • + Single-line item +
  • +
  • + Single-line item +
  • +
  • + Single-line item +
  • +
+ + +

List with radio group

+ +
    + + + +
+ + +

List with checkbox items

+ +
    + + + +
+ + + + + +

Basic Menu

+ + + +
+ +
+ + +

Selection Group Menu

+ + + +
+ +
+ + +

Anchored To Parent

+ +
+ + + + +
+ +

Anchor To Element Within Wrapper

+ +
+ + + + + + + +
+ + + +

Standard navigation drawers

+ + + + + +

Dismissible Modal drawers

+ +
+ +
+ + + +

Drawer with separate list groups

+ + + + +

Drawer with header

+ + + + + + + + +

radio buttons

+ +
+
+ +
+
+
+
+
+
+
+ + + + +

Radio button

+ +
+
+ +
+
+
+
+
+
+ +
+ + +

Disabled radio buttons

+ +
+
+ +
+
+
+
+
+
+ +
+ + + +

Continuous slider

+ +
+ +
+
+
+
+
+
+
+
+
+
+ + + + +

Continuous range slider

+ +
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + +

Discrete slider

+ +
+ +
+
+
+
+
+
+
+ +
+
+
+ + + + +

Discrete slider with tick marks

+ +
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + + +

Discrete range slider

+ +
+ + +
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+ + + + +

Disabled slider

+ +
+ +
+
+
+
+
+
+
+
+
+
+ + + + +

Snackbars

+ + + +
+ +
+ + + + +

Snackbars Stacked

+ + + +
+ +
+ + + + +

Snackbars Leading

+ + + +
+ +
+ + + + +

Switches

+ + + + + + + + + + + + + +

Tabs

+ +
+
+
+
+ + +
+
+
+
+ + + + +

text fields

+ + + +

Outlined text

+ + + +

Textarea

+ + + +

Textarea Outlined

+ + + +

Text field without label: Filled

+ + + +

Text field without label: Outlined

+ + + +

Text field without label: Textarea

+ + + +

Disabled text field

+ + + +

Text field with helper text

+ + +
+ +
+ +

Text field with character counter

+ + +
+
0 / 10
+
+ +

Multi-line text field (textarea) with character counter

+ + +
+
0 / 140
+
+ +

Multi-line text field (textarea) with character counter 2

+ + + +

Text field with prefix and suffix text

+ + + +

HTML5 validation

+ + + +

Pre-filled

+ + + +

Baseline alignment

+ +
+ + Text that is aligned with the text field's value +
+ +
+ + Text that is aligned to the bottom of the text field's outline +
+ + + + +

Tooltips

+ + + + Link + +

Rich tooltip

+ +
+ + +
+ +

Default rich tooltip with interactive content

+ +
+ + +
+ +

Persistent rich tooltip with interactive content

+ +
+ + +
+ + +

+ + + + + + + + + + +
+ + + + -- Gitee From 9d90f87da7dedea358fabeb30c633cf364c125ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=A5=E8=BF=9C=E6=98=9F?= <1050431815@qq.com> Date: Thu, 28 Apr 2022 15:27:41 +0800 Subject: [PATCH 04/29] no commit message --- web/py_lib/flutter.py | 2 +- web/py_lib/flutter_test_2.py | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/web/py_lib/flutter.py b/web/py_lib/flutter.py index 3c79418..b23b16b 100755 --- a/web/py_lib/flutter.py +++ b/web/py_lib/flutter.py @@ -590,7 +590,7 @@ class Tab: def render(self,parent): if True: - e = maketag('button', {'class':'mdc-tab mdc-tab--active','role':'tab','aria-selected':'true'}) + e = maketag('button', {'class':'mdc-tab mdc-tab--active','role':'tab'}) e1 = maketag('span', {'class':'mdc-tab__content'}) e.appendChild(e1) e2 = maketag('span', {'class':'mdc-tab-indicator mdc-tab-indicator--active'}) diff --git a/web/py_lib/flutter_test_2.py b/web/py_lib/flutter_test_2.py index fc4d066..75b7a6e 100755 --- a/web/py_lib/flutter_test_2.py +++ b/web/py_lib/flutter_test_2.py @@ -51,20 +51,19 @@ def 使用Material组件(): body=Container( child=Stack(children=[Positioned(child=ListView( children=[ - ListTile(leading=Icon(Icons.label),title=Text('Line 1')), - ListTile(leading=Icon(Icons.label),title=Text('Line 2')), - ListTile(leading=Icon(Icons.label),title=Text('Line 3')), - ListTile(leading=Icon(Icons.label),title=Text('Line 4')), + ListTile(leading=Icon(Icons.label),title=Text('Single-line item 1')), + ListTile(leading=Icon(Icons.label),title=Text('Single-line item 2')), + ListTile(leading=Icon(Icons.label),title=Text('Single-line item 3')), + ListTile(leading=Icon(Icons.label),title=Text('Single-line item 4')), ], ),left=0,top=0), Positioned(child=TabBar( tabs = [ - Tab(icon = Icon(Icons.sync), text = Text('a'), ), - Tab(icon = Icon(Icons.mic), text = Text('b'), ), - Tab(icon = Icon(Icons.mode), text = Text('c'), ), + Tab(icon = Icon(Icons.favorite), text = Text('FAVORITE'), ), + Tab(icon = Icon(Icons.search), text = Text('SEARCH'), ), ], - ),left=18,top=350,),],), - width=312, + ),left=10,top=350,),],), + width=320, height=480-72, color=Colors.white, ), -- Gitee From d5e0aba3c3531997a4ed27ed752d1448c3d40389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=A5=E8=BF=9C=E6=98=9F?= <1050431815@qq.com> Date: Thu, 28 Apr 2022 07:38:26 +0000 Subject: [PATCH 05/29] README.md. --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a235c08..5b5dc95 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,9 @@ - 我发现大部分的 Material Design Component (MDC) 需要配上代码才可以正确显示。 - 我对 web/py_lib/flutter.py 作了相应的更改 (见454和503行)。 -- 另外我添加了 web/lib/mdc_test.html, 里面展示了大部分的 MDC 控件的使用 (编辑器打开看源代码,双击浏览器打开看效果)。 \ No newline at end of file +- 另外我添加了 web/lib/mdc_test.html, 里面展示了大部分的 MDC 控件的使用 (编辑器打开看源代码,双击浏览器打开看效果)。 + + +#### 完成说明 2022-04-28 16:29:00 +我完成的是lists和tabs简化版的例子 +主要过程如下: \ No newline at end of file -- Gitee From b1fcd0594db1f078188ddf871f59fecefdf35f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=A5=E8=BF=9C=E6=98=9F?= <1050431815@qq.com> Date: Thu, 28 Apr 2022 07:43:18 +0000 Subject: [PATCH 06/29] update README.md. --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b5dc95..0fd3b3e 100644 --- a/README.md +++ b/README.md @@ -9,4 +9,8 @@ #### 完成说明 2022-04-28 16:29:00 我完成的是lists和tabs简化版的例子 -主要过程如下: \ No newline at end of file + +主要完成过程如下: + -首先我在https://material.io/components/lists和https://material.io/components/tabs找到lists和tabs的样例代码 + -找到相应的flutter代码,参考它构建类的接口 + -再对照相应的web代码,作为新建类的具体实现 \ No newline at end of file -- Gitee From 15defef928039952334d121cfebf38c5b7df8a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=A5=E8=BF=9C=E6=98=9F?= <1050431815@qq.com> Date: Thu, 28 Apr 2022 07:43:56 +0000 Subject: [PATCH 07/29] update README.md. --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0fd3b3e..1ebcd58 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,11 @@ #### 完成说明 2022-04-28 16:29:00 + 我完成的是lists和tabs简化版的例子 主要完成过程如下: - -首先我在https://material.io/components/lists和https://material.io/components/tabs找到lists和tabs的样例代码 - -找到相应的flutter代码,参考它构建类的接口 - -再对照相应的web代码,作为新建类的具体实现 \ No newline at end of file + + - 首先我在https://material.io/components/lists和https://material.io/components/tabs找到lists和tabs的样例代码 + - 找到相应的flutter代码,参考它构建类的接口 + - 再对照相应的web代码,作为新建类的具体实现 \ No newline at end of file -- Gitee From 76ce4cff973eb73d1d232ce8ace6b417a22bbcc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=A5=E8=BF=9C=E6=98=9F?= <1050431815@qq.com> Date: Thu, 28 Apr 2022 07:49:14 +0000 Subject: [PATCH 08/29] update README.md. --- README.md | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1ebcd58..3859c63 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,28 @@ 我完成的是lists和tabs简化版的例子 -主要完成过程如下: +大概流程过程如下: - 首先我在https://material.io/components/lists和https://material.io/components/tabs找到lists和tabs的样例代码 - - 找到相应的flutter代码,参考它构建类的接口 - - 再对照相应的web代码,作为新建类的具体实现 \ No newline at end of file + - 找到相应的Flutter代码,参考它构建类的接口 + - 再对照相应的Web代码,作为新建类的具体实现 + - 编写调试代码验证结果 + +相关细节: + + - 对于lists这个Widget,我构建了两个类,一个是ListTile可以新建列表的一项,另一个是ListView新建的是整个列表的框架。 + 详细参考的样式如下 +
    +
  • + + Single-line item +
  • +
  • + + Single-line item +
  • +
  • + + Single-line item +
  • +
\ No newline at end of file -- Gitee From b1da355ab49b81e3b92c5902a3cddb05b1727bee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=A5=E8=BF=9C=E6=98=9F?= <1050431815@qq.com> Date: Thu, 28 Apr 2022 07:50:08 +0000 Subject: [PATCH 09/29] update README.md. --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 3859c63..062f5c4 100644 --- a/README.md +++ b/README.md @@ -22,17 +22,17 @@ - 对于lists这个Widget,我构建了两个类,一个是ListTile可以新建列表的一项,另一个是ListView新建的是整个列表的框架。 详细参考的样式如下 -
    -
  • - - Single-line item -
  • -
  • - - Single-line item -
  • -
  • - - Single-line item -
  • -
\ No newline at end of file +#
    +#
  • +# +# Single-line item +#
  • +#
  • +# +# Single-line item +#
  • +#
  • +# +# Single-line item +#
  • +#
\ No newline at end of file -- Gitee From 9935898da3305daf3bf64017519c8b7e817d7540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=A5=E8=BF=9C=E6=98=9F?= <1050431815@qq.com> Date: Thu, 28 Apr 2022 07:51:07 +0000 Subject: [PATCH 10/29] update README.md. --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 062f5c4..048fa56 100644 --- a/README.md +++ b/README.md @@ -22,17 +22,17 @@ - 对于lists这个Widget,我构建了两个类,一个是ListTile可以新建列表的一项,另一个是ListView新建的是整个列表的框架。 详细参考的样式如下 -#
    -#
  • -# -# Single-line item -#
  • -#
  • -# -# Single-line item -#
  • -#
  • -# -# Single-line item -#
  • -#
\ No newline at end of file +###
    +
  • + + Single-line item +
  • +
  • + + Single-line item +
  • +
  • + + Single-line item +
  • +
-- Gitee From 0550374db0d2dfb013ecf5599faf559597ce757b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=A5=E8=BF=9C=E6=98=9F?= <1050431815@qq.com> Date: Thu, 28 Apr 2022 07:52:10 +0000 Subject: [PATCH 11/29] update README.md. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 048fa56..f3e7a16 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ - 对于lists这个Widget,我构建了两个类,一个是ListTile可以新建列表的一项,另一个是ListView新建的是整个列表的框架。 详细参考的样式如下 -###