{"id":13722873,"url":"https://github.com/githubliruiyuan/HybridFlutter","last_synced_at":"2025-05-07T16:31:13.433Z","repository":{"id":39419479,"uuid":"203164795","full_name":"githubliruiyuan/HybridFlutter","owner":"githubliruiyuan","description":"Flutter + V8/JsCore 动态化","archived":false,"fork":false,"pushed_at":"2022-12-11T02:43:51.000Z","size":12756,"stargazers_count":350,"open_issues_count":23,"forks_count":83,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-11-14T12:50:32.423Z","etag":null,"topics":["android","dart","flutter","ios","js"],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/githubliruiyuan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-08-19T12:05:57.000Z","updated_at":"2024-11-09T01:04:12.000Z","dependencies_parsed_at":"2023-01-26T14:30:45.133Z","dependency_job_id":null,"html_url":"https://github.com/githubliruiyuan/HybridFlutter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/githubliruiyuan%2FHybridFlutter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/githubliruiyuan%2FHybridFlutter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/githubliruiyuan%2FHybridFlutter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/githubliruiyuan%2FHybridFlutter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/githubliruiyuan","download_url":"https://codeload.github.com/githubliruiyuan/HybridFlutter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252915272,"owners_count":21824533,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","dart","flutter","ios","js"],"created_at":"2024-08-03T01:01:34.118Z","updated_at":"2025-05-07T16:31:09.989Z","avatar_url":"https://github.com/githubliruiyuan.png","language":"Dart","funding_links":[],"categories":["Dart"],"sub_categories":[],"readme":"# HybridFlutter\nFlutter + V8/JsCore 动态化实践\n\nDSL（HTML+CSS+JS）\n\n由HTML标签来开发原生组件，那么首先需要将HTML做解析，这里我们将HTML通过node脚本解析成JSON字符串，再用Dart来解析JSON，映射对应的标签到flutter的组件。\n\n# 一、HTML部分\n为了高效解析，直接用flutter的组件名在HTML文件上开发\n\n* 文件目录如下：\n\n![](https://github.com/githubliruiyuan/HybridFlutter/blob/master/image/file-dir.png)\n\n- config\n``` json\n{\n  \"navigationBarTitleText\": \"\",\n  \"backgroundColor\": \"#eeeeee\",\n  \"enablePullDownRefresh\": true  \n}\n```\n- HTML\n```\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\" html-identify=\"CC\"\u003e\n\n\u003chead\u003e\n    \u003cmeta charset=\"UTF-8\" /\u003e\n    \u003cstyle type=\"text/css\" media=\"screen\"\u003e\n        @import \"home.css\";\n    \u003c/style\u003e\n\u003c/head\u003e\n\n\u003cbody\u003e\n    \u003csinglechildscrollview\u003e  \n        \u003ccolumn\u003e   \n            \u003ccontainer id=\"btn-container\" cc:for=\"{{list}}\"\u003e \n                \u003craisedbutton id=\"raised-button\" bindtap=\"onItemClick\" data-index=\"{{index}}\"\u003e\n                    \u003crow\u003e\n                        \u003ccontainer id=\"image-container\"\u003e\n                            \u003cimage src=\"{{item.image}}\" /\u003e  \n                        \u003c/container\u003e\n                        \u003cexpanded\u003e  \n                            \u003ccolumn id=\"column-text\"\u003e\n                                \u003ctext id=\"text-title\"\u003e{{item.title}}\u003c/text\u003e\n                                \u003ctext id=\"text-publisher\"\u003e{{item.publisher}}\u003c/text\u003e \n                                \u003ctext id=\"text-summary\"\u003e{{item.summary.substring(0, 20) + '...'}}\u003c/text\u003e    \n                            \u003c/column\u003e\n                        \u003c/expanded\u003e\n                    \u003c/row\u003e\n                \u003c/raisedbutton\u003e\n            \u003c/container\u003e\n        \u003c/column\u003e\n    \u003c/singlechildscrollview\u003e\n\u003c/body\u003e\n\n\u003c/html\u003e\n```\n\n- css样式\n```css\n/* home */\n.btn-container{\n    margin-top:10;\n    margin-left: 10; \n    margin-right: 10;\n}\n\n.raised-button {\n    color: white;\n}\n\n.image-container {\n    width: 100px; \n    height:100px; \n    padding: 5;\n}\n\n.column-text {\n    cross-axis-alignment: start;\n}\n\n.text-title {\n    font-size: 14px;\n    color: black;\n}\n\n.text-publisher {\n    font-size: 12px;\n    color: gray;\n}\n\n.text-summary {\n    font-size: 12px;\n    color: gray;\n}\n\n```\n\n\n- js交互\n```js\n/** home */\nPage({\n    /**\n    * 页面数据\n    */\n    data: {\n        list: [],\n    },\n\n    /**\n    * 页面加载时触发。一个页面只会调用一次，可以在 onLoad 的参数中获取打开当前页面路径中的参数。\n    */\n    onLoad(e) {\n        cc.setNavigationBarTitle({\n            title: 'Python系列丛书'\n        }); \n        cc.showLoading({});\n        this.doRequest(true);  \n    },\n\n    doRequest(isOnload) {\n        let that = this;\n        cc.request({\n            url: 'https://douban.uieee.com/v2/book/search?q=python', \n            data: {},\n            header: {},\n            method: 'get',\n            success: function (response) {\n                that.setData({\n                    list: response.body.books\n                });\n                cc.showToast({\n                    title: '加载成功'\n                });\n            },\n            fail: function (error) {\n                console.log('request error:' + JSON.stringify(error));\n                cc.showToast({\n                    title: '加载失败'\n                });\n            },\n            complete: function () {\n                console.log('request complete');\n                if (isOnload) {\n                    cc.hideLoading(); \n                } else {\n                    cc.stopPullDownRefresh();\n                }\n            } \n        });\n    },\n\n    onItemClick(e) {\n        var item = this.data.list[e.target.dataset.index];  \n        cc.navigateTo({ \n            url: \"detail?item=\" + JSON.stringify(item)\n        });\n    },   \n\n    onPullDownRefresh() { \n        console.log(\"onPullDownRefresh\");\n        this.doRequest(false);\n    },\n\n    /**\n    * 页面卸载时触发。如cc.redirectTo或cc.navigateBack到其他页面时。\n    */\n    onUnload() {\n\n    }\n});\n```\n\n# 二、渲染效果\n\n![](https://github.com/githubliruiyuan/HybridFlutter/blob/master/image/total.gif)\n\n# 三、组件部分\n直接使用flutter的组件\n\n## 1、组件\n### a、布局类组件\n- 线性布局（row和column）\n- 弹性布局（flex）\n- 流式布局（wrap、flow）\n- 层叠布局（stack、positioned）\n- 对齐与相对定位（align）\n\n### b、基础组件\n- text\n- image\n- raisedbutton\n- circularprogressindicator\n\n### c、容器类组件\n- 填充（padding）\n- 尺寸限制类容器（constrainedbox等）\n- 装饰容器（decoratedbox）\n- 变换（transform）\n- container容器\n- 剪裁（clip）\n\n### d、可滚动组件\n- singlechildscrollview\n- listview\n- gridview\n\n# 四、Api\n模仿微信小程序的Api，cc对应是微信小程序的wx\n## 1、界面\n### a、交互\n- cc.showToast\n- cc.showLoading\n- cc.hideToast\n- cc.hideLoading\n- ...\n\n### b、背景 \n- cc.setBackgroundColor\n\n### c、导航栏\n- cc.setNavigationBarTitle\n- cc.setNavigationBarColor\n\n### e、下拉刷新 \n- cc.startPullDownRefresh\n- cc.stopPullDownRefresh\n\n## 2、网络\n### a、cc.request\n以上HTML中的例子\n\n# 五、框架\n## 1、语法参考\n### a、数据绑定\n\u003e HTML 中的动态数据均来自对应 Page 的 data。\n\u003e \n\u003e 双大括号 {{}} 将变量包起来\n\n```\n\u003ctext\u003e{{message}}\u003c/text\u003e\n\nPage({\n  data: {\n    message: \"hello world\"\n  }\n})\n\n```\n\n### b、列表渲染\n\n- cc:for\n\u003e 在组件上使用 cc:for 控制属性绑定一个数组，即可使用数组中各项的数据重复渲染该组件。\n\u003e\n\u003e 默认数组的当前项的下标变量名默认为 index，数组当前项的变量名默认为 item\n\n```\n\u003ccolumn\u003e\n    \u003ctext cc:for=\"{{array}}\"\u003e\n      {{index + '-' + item.name}}\n    \u003c/text\u003e\n\u003c/column\u003e  \n\nPage({\n  data: {\n    array: [{\n      name: 'first',\n    }, {\n      name: 'second'\n    }]\n  }\n})\n```\n\n\u003e 使用 cc:for-item 可以指定数组当前元素的变量名，\n\u003e\n\u003e 使用 cc:for-index 可以指定数组当前下标的变量名：\n\n```\n\u003ccolumn\u003e\n    \u003ctext cc:for=\"{{array}}\" cc:for-index=\"idx\" cc:for-item=\"itemName\"\u003e\n      {{idx + ' - ' + itemName.name}}\n    \u003c/text\u003e\n\u003c/column\u003e\n```\n\n- cc:for 嵌套\n```\n\u003ccolumn\u003e\n    \u003crow cc:for=\"{{array1}}\" cc:for-item=\"i\"\u003e\n        \u003ctext cc:for=\"{{array2}}\" cc:for-item=\"j\"\u003e\n            {{'i * j = ' + i * j}}\n        \u003c/text\u003e\n    \u003c/row\u003e\n\u003c/column\u003e\nPage({\n  data: {\n    array1: [1, 2, 3, 4, 5, 6, 7, 8, 9],\n    array2: [1, 2, 3, 4, 5, 6, 7, 8, 9]\n  }\n})\n\n```\n# 六、API 演示\n![](https://github.com/githubliruiyuan/HybridFlutter/blob/master/image/api.gif)\n\n# 七、实时调试\n\n\n![](https://github.com/githubliruiyuan/HybridFlutter/blob/master/image/real-time.gif)\n\n\n# 八、代码运行\n\n- 1、目前只实现了Android版，需要使用Android Studio导入项目，路径如下图所示；\n- 2、将main.dart中的_pageCode值改为\"home\"。\n\n\n- 3、由于代码直接run出来的debug包里面lib下armabi-v7a没有生成Flutter的so包，所以不能直接在真机上面直接测试\n\n- 4、真机上面运行需要通过build-\u003eFlutter-\u003eBuild APK方式得到app-release.apk包进行安装\n\n\n- 系列文章：\n\n[《使用Flutter + V8开发小程序引擎（一）》](https://juejin.im/post/5d68c2046fb9a06aca3833a2)\n\n[《使用Flutter + V8开发小程序引擎（二）》](https://juejin.im/post/5d68f1b36fb9a06ad0058541)\n\n[《使用Flutter + V8开发小程序引擎（三）》](https://juejin.im/post/5d70af6ee51d456206115a6f)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgithubliruiyuan%2FHybridFlutter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgithubliruiyuan%2FHybridFlutter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgithubliruiyuan%2FHybridFlutter/lists"}