Introduction
LuaView 是 聚划算无线技术团队 的开源项目,其初衷是为了提升移动端应用动态化能力,提供比H5更好的用户体验,同时做到Android、iOS业务代码共用,减少同一业务的人员重复投入。
目前LuaView已经在聚划算大范围使用,先后经历了聚划算 3.8、6.6、9.9大促,已经服务过千万用户。使用LuaView的客户端能够具备H5同样的动态化能力,做到bug随时修,业务随时上,且在硬件交互,动画等功能上提供比H5更好的体验。
LuaView 使用Lua语言进行代码编写,目前支持两个端:Android和iOS。Android 端使用LuaJ引擎,iOS端使用LuaC引擎。
Design Principles
几乎所有API既可以作为get函数调用,也可以作为set函数调用
- 有参数的时候作为set函数调用,并返回对象本身(可供链式调用)
- 无参数的时候作为get函数调用,并返还调用返回值
- 时间单位是秒,毫秒通过小数来设置
- 所有尺寸单位为点(dot),而非真实像素(px)
- 容器类包含View的容器方法,非容器类没有View的容器方法
如:
view.size(100, 100) -- 设置view的大小为 w=100, h=100,返回view自身
view.size() -- 获取view的大小,返回 {w=100, h=100}
API-LuaView
LuaView 使用 -Android
1. 创建LuaView
LuaView luaview = LuaView.create(getContext());
2. 注册扩展
luaview.registerPanel(CustomLoading.class);
luaview.register("bridge", new CustomBridge());
3. 加载资源
luaview.load("脚本uri");
如:
本地, luaview.load("main.lua"); //加载 assets下的main.lua
网络, luaview.load("http://luaview.github.com/test.zip"); //加载 网络资源test.zip,LuaView会自行下载并解压执行
LuaView 使用 -IOS
1. 创建LuaView
LView* luaview = [[LView alloc] initWithFrame:rect];
2. 注册扩展
luaview.registerPanel(CustomLoading.class);
luaview.register("bridge", new CustomBridge());
3. 加载资源
[luaview.bundle addScriptPath:packagePath];
[luaview.bundle addResourcePath:packagePath];
[luaview runFile:scriptFileName];
[luaview runSignFile:scriptFileName];
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | bundle | - | Bundle对象 | IOS | LuaView的bundle属性用于脚本目录管理 |
2 | create | context: Context | LuaView | Android | 创建LuaView |
3 | createAsync | context: Context, callback: CreatedCallback | - | Android | 异步创建LuaView |
4 | load | url: String | LuaView | Android | 加载指定资源(asset、本地、网络) |
5 | load | url: String, callback: ScriptExecuteCallback | LuaView | Android | 加载指定资源(asset、本地、网络),带回调 |
6 | loadFile | url: String | 错误信息 | IOS | 加载指定资源(本地) |
7 | loadSignFile | url: String | 错误信息 | IOS | 加载指定资源本地 |
8 | runFile | url: String | 错误信息 | IOS | 加载指定资源(本地) |
9 | runSignFile | url: String | 错误信息 | IOS | 加载指定资源本地 |
10 | runData | data: 数据块, fileName:调试信息 | 错误信息 | IOS | 加载指定资源(本地) |
11 | loadScript | script: String | LuaView | Android | 加载指定脚本 |
12 | loadScript | script: String, callback: ScriptExecuteCallback | LuaView | Android | 加载指定脚本,带回调 |
13 | loadScriptBundle | scriptBundle: ScriptBundle | LuaView | Android | 加载指定脚本包 |
14 | loadScriptBundle | scriptBundle: ScriptBundle, callback: ScriptExecuteCallback | LuaView | Android | 加载指定脚本包,带回调 |
15 | loadScriptBundle | scriptBundle: ScriptBundle, main_entry: String, callback: ScriptExecuteCallback | LuaView | Android | 加载指定脚本包,执行main_entry入口文件,带回调 |
16 | register | name: String, bridge: Object | LuaView | Android | 注册一个名称为name的bridge对象 |
17 | unregister | name: String | LuaView | Android | 反注册一个名称为name的bridge对象 |
18 | registerPanel | clazz: Class<? extends LVCustomPanel> | LuaView | Android | 注册一个名称为clazz类名,类型为clazz的panel |
19 | registerPanel | name: String, clazz: Class<? extends LVCustomPanel> | LuaView | Android | 注册一个名称为name,类型为clazz的panel |
20 | registerLibs | binders: LuaValue[] | LuaView | Android | 注册自定义库 |
21 | registerImageProvider | clazz: Class<? extends ImageProvider> | LuaView | Android | 注册一个ImageProvider |
22 | getImageProvider | - | provider: ImageProvider | Android | 获取ImageProvider |
23 | callLuaFunction | funName: String, params: Object[] | result: Object | Android | 调用lua的某个全局函数 |
24 | callWindowFunction | funName: String, params: Object[] | result: Varargs | Android | 调用window.callback下的某个函数 |
25 | getUri | - | uri: String | Android | 获取当前LuaView加载的Uri |
26 | viewWillAppear | - | - | IOS | viewWillAppear |
27 | viewDidAppear | - | - | IOS | viewDidAppear |
28 | viewWillDisAppear | - | - | IOS | viewWillDisAppear |
29 | viewDidDisAppear | - | - | IOS | viewDidDisAppear |
30 | motionBegan | - | - | IOS | motionBegan |
31 | motionEnded | - | - | IOS | motionEnded |
Bundle
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | addResourcePath | path:String | - | IOS | 资源搜索路径 |
2 | removeResourcePath | path:String | - | IOS | 资源搜索路径 |
3 | addScriptPath | path:String | - | IOS | 脚本搜索路径 |
4 | removeScriptPath | path:String | - | IOS | 脚本搜索路径 |
5 | resourcePathWithName | name:String | - | IOS | 资源 |
6 | resourceWithName | name:String | - | IOS | 获取资源 |
7 | imageWithName | name:String | - | IOS | 获取图片 |
8 | scriptPathWithName | name:String | - | IOS | 获取脚本路径 |
9 | scriptWithName | name:String | - | IOS | 获取脚本 |
10 | signedScriptWithName | name:String | - | IOS | 获取签名脚本 |
API-UI
View
initParams
TableView().initParams({
})
frame
view.frame(0, 0, 100, 100)
view.frame()
padding
view.padding(5, 5, 5, 5)
backgroundColor
view.backgroundColor(0xff0000, 0.5)
align
view.align(Align.RIGHT, Align.BOTTOM)
startAnimation
anim1 = Animation().alpha(1, 0).duration(1)
anim2 = Animation().scale(1, 0).duration(2).delay(0.2)
view.startAnimation(anim1, anim2)
flexCss
view = View()
view.flexCss("margin-left: 10, sizetofit: 1, align-self: center")
flxLayout
view = View()
view.flxLayout(true, function()
print("do something")
end)
effects
view.effects(ViewEffect.CLICK) -- 点击特效
view.effects(ViewEffect.CLICK, 0xff0000, 0.5) -- 点击特效,颜色红色,alpha=0.5
view.effects(ViewEffect.NONE) -- 无效果
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | initParams | table: LuaTable | - | Android | 初始化参数 |
2 | invalidate | - | - | - | 强制重绘 |
3 | padding | left: Number top: Number right: Number bottom: Number |
- | - | 内边距 |
4 | frame | x: Number y: Number width: Number height: Number |
- | - | View尺寸 |
5 | backgroundColor | color: Number alpha: Number |
color, alpha | - | 背景色&alpha |
6 | size | width: Number height: Number |
width, height | - | 尺寸 |
7 | xy | x: Number y: Number |
x,y | - | x、y坐标 |
8 | align | aligns[]: Align | - | - | 设置自身在父容器的布局 |
9 | alignLeft | - | - | - | 设置自身位于父容器Left&Top |
10 | alignTop | - | - | - | 设置自身位于父容器Left&Top |
11 | alignRight | - | - | - | 设置自身位于父容器Right&Top |
12 | alignBottom | - | - | - | 设置自身位于父容器Left&Bottom |
13 | alignLeftTop | - | - | Android | 设置自身位于父容器Left&Top |
14 | alignTopLeft | - | - | Android | 设置自身位于父容器Left&Top |
15 | alignCenterTop | - | - | Android | 设置自身位于父容器Center&Top |
16 | alignTopCenter | - | - | Android | 设置自身位于父容器Center&Top |
17 | alignRightTop | - | - | Android | 设置自身位于父容器Right&Top |
18 | alignTopRight | - | - | Android | 设置自身位于父容器Right&Top |
19 | alignLeftBottom | - | - | Android | 设置自身位于父容器Left&Bottom |
20 | alignBottomLeft | - | - | Android | 设置自身位于父容器Left&Bottom |
21 | alignCenterBottom | - | Android | - | 设置自身位于父容器Center&Bottom |
22 | alignBottomCenter | - | Android | - | 设置自身位于父容器Center&Bottom |
23 | alignRightBottom | - | - | Android | 设置自身位于父容器Right&Bottom |
24 | alignBottomRight | - | - | Android | 设置自身位于父容器Right&Bottom |
25 | alignCenter | - | - | - | 设置自身位于父容器Center |
26 | alignLeftCenter | - | - | Android | 设置自身位于父容器Left&Center |
27 | alignCenterLeft | - | - | Android | 设置自身位于父容器Left&Center |
28 | alignRightCenter | - | - | Android | 设置自身位于父容器Right&Center |
29 | alignCenterRight | - | - | Android | 设置自身位于父容器Right&Center |
30 | alignCenterHorizontal | - | - | Android | 设置自身位于父容器center in horizontal |
31 | alignHorizontalCenter | - | - | Android | 设置自身位于父容器center in horizontal |
32 | alignCenterVertical | - | - | Android | 设置自身位于父容器center in vertical |
33 | alignVerticalCenter | - | - | Android | 设置自身位于父容器center in vertical |
34 | center | x: Number y: Number |
x, y | - | 中心点坐标 |
35 | x | x: Number | x | - | x坐标 |
36 | y | y: Number | y | - | y坐标 |
37 | left | left: Number | left | - | 距离父容器左侧边距 |
38 | top | top: Number | top | - | 距离父容器上侧边距 |
39 | right | right: Number | right | - | 距离父容器右侧边距 |
40 | bottom | bottom: Number | bottom | - | 距离父容器底部边距 |
41 | width | width: Number | width | - | 宽度 |
42 | minWidth | width: Number | width | Android | 最小宽度 |
43 | height | height: Number | height | - | 高度 |
44 | centerX | x: Number | x | - | 中心点x坐标 |
45 | centerY | y: Number | y | - | 中心点y坐标 |
46 | visible | v: Boolean | v | Android | 可见性 |
47 | hidden | v: Boolean | v | - | 可见性 |
48 | show | - | - | - | 显示 |
49 | isShow | - | v: Boolean | - | 是否可见 |
50 | hide | - | - | - | 隐藏 |
51 | isHide | - | v: Boolean | - | 是否隐藏 |
52 | enabled | v: Boolean | v | - | 是否可用 |
53 | alpha | alpha: Number | alpha | - | 透明度 |
54 | borderWidth | width: Number | width | - | 边框宽度 |
55 | borderColor | color: Number | color | - | 边框颜色 |
56 | clipsToBounds | v: Boolean | v | iOS | View边框是否剪接 |
57 | shadowPath | v: Boolean | v | iOS | 只对边框外部加阴影 |
58 | masksToBounds | v: Boolean | v | iOS | 设置边框是否裁剪 |
59 | shadowOffset | v: Number | v | iOS | 设置View阴影偏移位置 |
60 | shadowRadius | v: Number | v | iOS | 设置View阴影高斯模糊半径 |
61 | shadowOpacity | v: Number | v | iOS | 设置View阴影透明度 |
62 | shadowColor | v: Number | v | iOS | 设置View阴影颜色 |
63 | sizeToFit | - | - | - | 适应View内容的大小 |
64 | addGestureRecognizer | - | - | iOS | 添加手势 |
65 | removeGestureRecognizer | - | - | iOS | 移除手势 |
66 | transform3D | v: Number[] | - | iOS | 设置3D变换矩阵 |
67 | anchorPoint | x: Number y: Number |
- | - | 锚点 |
68 | removeFromSuper | - | - | - | 从父容器移除 |
69 | removeFromParent | - | - | - | 从父容器移除 |
70 | hasFocus | - | v: Boolean | - | 是否有焦点 |
71 | requestFocus | - | - | - | 请求焦点 |
72 | clearFocus | - | - | - | 取消焦点 |
73 | rotation | v: Number | - | - | 旋转角度 |
74 | rotationXY | rx: Number ry: Number |
rx, ry | - | 根据x坐标和y坐标得到的旋转角度,pivot |
75 | scale | sx: Number sy: Number |
sx, sy | - | x,y缩放 |
76 | scaleX | sx: Number | sx | - | x坐标缩放 |
77 | scaleY | sy: Number | sy | - | y坐标缩放 |
78 | translation | tx: Number ty: Number |
x, y | - | x、y位移 |
79 | translationX | tx: Number | tx | - | x坐标位移 |
80 | translationY | ty: Number | ty | - | y坐标位移 |
81 | bringToFront | - | - | Android | 将view设置到前台 |
82 | scrollTo | sx: Number sy: Number |
- | Android | 滚动到某个位置 |
83 | scrollBy | sx: Number sy: Number |
- | Android | 移动一段距离 |
84 | scrollX | sx: Number | sx | Android | x方向滚动到某个位置 |
85 | offsetX | sx: Number | sx | Android | x方向滚动到某个位置 |
86 | scrollY | sy: Number | sy | Android | y方向滚动到某个位置 |
87 | offsetY | sy: Number | sy | Android | y方向滚动到某个位置 |
88 | scrollXY | sx: Number sy: Number |
sx, sy | Android | x、y方向移动到某个位置 |
89 | offsetXY | sx: Number sy: Number |
sx, sy | Android | x、y方向移动到某个位置 |
90 | offset | sx: Number sy: Number |
sx, sy | Android | x、y方向移动到某个位置 |
91 | showScrollIndicator | h: Boolean v: Boolean |
h, v | Android | 设置滚动条是否显示(横向、纵向) |
92 | callback | v: LuaTable | v | - | 监听view的各种事件 |
93 | onClick | v: LuaFunction | v | - | 设置view的点击事件 |
94 | onLongClick | v: LuaFunction | v | Android | 设置view的长按事件 |
95 | adjustSize | - | - | - | 调整大小以适应内容 |
96 | cornerRadius | radius: Number | radius | - | 设置边框圆角半径 |
97 | startAnimation | anims: Animation[] | - | - | 开始播放动画 |
98 | stopAnimation | - | - | - | 停止动画播放 |
99 | isAnimating | - | v: Boolean | - | 是否正在播放动画 |
100 | flexCss | v: String | v | - | 设置flex属性 |
101 | flxLayout | v: String | v | iOS | 设置flex布局 |
102 | effects | effect: ViewEffect color: Number alpha: Number |
effect | - | 设置view的特效 |
103 | nativeView | - | v: Object | - | 获取NativeView |
104 | borderDash | v: Number | - | - | 设置边框虚线 |
105 | margin | l: Number t: Number r: Number b: Number |
l, t, r, b | Android | 边距 |
106 | onTouch | v: LuaFunction | v | 设置触摸事件 |
作为容器的额外方法
onShow
view.onShow(function()
print("i am show")
end)
onHide
view.onHide(function()
print("i am hide")
end)
onBack
view.onBack(function()
print("back pressed")
end)
onLayout
view.onLayout(function()
print("i am layouted")
end)
addView
child = View()
parent = View()
parent.addView(child)
removeView
child = View()
parent = View()
parent.addView(child)
parent.removeView(child)
removeAllViews
child = View()
parent = View()
parent.addView(child)
parent.removeAllViews()
children
parent.children(function(parent) -- 所有在函数里创建的View都会被自动添加到parent里
view = View()
...
end)
flexChildren
child1 = View()
child2 = View()
parent = View()
parent.flexChildren(child1, child2)
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | onShow | v: LuaFunction | v | - | 显示监听 |
2 | onHide | v: LuaFunction | v | - | 隐藏监听 |
3 | onBack | v: LuaFunction | v | - | 返回按钮监听 |
4 | onLayout | v: LuaFunction | v | - | 布局监听 |
5 | addView | v: View | - | - | 添加子View |
6 | removeView | v: View | - | - | 移除子View |
7 | removeAllViews | - | - | - | 移除所有子View |
8 | children | v: LuaFunction | - | - | 子View构造函数 |
9 | flexChildren | v: View[] | - | - | Flexbox 设置childViews |
Label
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | text | v: String/StyledString/Unicode | v | - | Label文本 |
2 | textColor | color: Number | color | - | 文本颜色 |
3 | textSize | size: Number | size | - | 文本字体大小 |
4 | fontSize | size: Number | size | - | 文本字体大小 |
5 | fontName | name: String | name | - | 文本字体 |
6 | font | name: String size: Number |
name, size | - | 文本字体&大小 |
7 | gravity | v: Gravity | v | - | 文本对齐方式 |
8 | textAlign | v: TextAlign | v | - | 文本对齐方式 |
9 | lines | v: Number | v | Android | 文字行数 |
10 | maxLines | v: Number | v | - | 文本最大行数 |
11 | lineCount | v: Number | v | - | 文本最大行数 |
12 | minLines | v: Number | v | Android | 文本最小行数 |
13 | ellipsize | v: Ellipsize | v | - | 文本省略方式 |
14 | adjustTextSize | - | - | Android | 字体大小适应宽度 |
15 | adjustFontSize | - | - | - | 字体大小适应宽度 |
Button
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | title | v: String/StyledString/Unicode | v | - | 按钮文字 |
2 | titleColor | color: Number | color | - | - |
|3|text|v: String/StyledString/Unicode|v|IOS|按钮文字|
|4|textColor|color: Number|color|-|IOS|文本颜色|
|5|image|img1: String
img2: String|img1, img2|-|-|按钮点按图片(正常,点击)|
|6|selected|-|-|iOS|是否selected|
|6|enabled|-|-|iOS|是否使能|
Image
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | image | v: String, c: LuaFunction | v | - | 设置图片url(本地、网络),回调 |
2 | contentMode | type: ScaleType | type | Android | 图片缩放模式 |
3 | scaleType | type: ScaleType | type | - | 图片缩放模式 |
4 | startAnimationImages | images: String[] | - | - | 帧动画(本地图) |
5 | stopAnimationImages | - | - | - | 停止播放帧动画 |
6 | isAnimationImages | - | - | - | 是否正在播放帧动画 |
TextField
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | hint | v: String/StyledString/Unicode | v | - | 提示 |
2 | placeholder | v: String/StyledString/Unicode | v | - | 提示 |
ScrollView
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | contentSize | - | - | IOS | 设置内容区域大小 |
2 | offset | - | - | iOS | 设置内容偏移 |
3 | contentInset | - | - | iOS | 设置ContentInset |
4 | showScrollIndicator | v: Boolean | v | iOS | 是否显示滚动条信息 |
5 | isRefreshing | - | v: Boolean | iOS | 是否正在刷新 |
6 | startRefreshing | - | - | iOS | 开始刷新 |
7 | stopRefreshing | - | - | iOS | 停止刷新 |
TableView
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | reload | section: Number row: Number |
- | - | Android支持参数 |
2 | contentSize | - | - | IOS | 设置内容区域大小 |
3 | contentOffset | - | - | iOS | 设置内容偏移 |
4 | contentInset | - | - | iOS | 设置ContentInset |
5 | showScrollIndicator | v: Boolean | v | - | 是否显示滚动条信息 |
6 | scrollToTop | offset: Number animate: Boolean |
- | - | 滚动到顶部(offset间隔,animate是否动画) |
7 | scrollToCell | section: Number rowInSection: Number offset: Number animate: Boolean |
- | - | 滚动到指定cell,offset间隔,animate是否动画 |
8 | miniSpacing | space: Number | space | - | cell间隙 |
9 | lazyLoad | v: Boolean | - | - | 是否懒加载Cell |
10 | header | v: View | - | - | 设置Header,nil的时候清空header |
11 | footer | v: View | - | - | 设置Footer,nil的时候清空footer |
12 | dividerHeight | v: Number | height: Number | height | - |
CollectionView
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | reload | section: Number row: Number |
- | - | Android支持参数 |
5 | showScrollIndicator | v: Boolean | v | - | 是否显示滚动条信息 |
6 | scrollToTop | offset: Number animate: Boolean |
- | - | 滚动到顶部(offset间隔,animate是否动画) |
7 | scrollToCell | section: Number rowInSection: Number offset: Number animate: Boolean |
- | - | 滚动到指定cell,offset间隔,animate是否动画 |
8 | miniSpacing | space: Number | space | - | cell间隙 |
9 | lazyLoad | v: Boolean | - | Android | 是否懒加载Cell |
-- CollectionView 例子
local cv = CollectionView {
Section = {
SectionCount = function()
-- 返回页面区块的个数(不同区块的种类数)
return sectionCount
end,
RowCount = function(section)
-- 返回每个区块对应有的坑位数
if(section == 1) then
return rowCount1
else
return rowCount2
end
end
},
Cell = {
Id = function(section, row)
-- 返回每个区块对应额坑位ID
if (section == 1) then
return "Label"
elseif(section == 2) then
return "ImageAndLabel"
end
end,
Label = {
Size = function(section, row)
return w, cellHeight
end,
Init = function(cell, section, row)
cell.title = Label()
end,
Layout = function(cell, section, row)
cell.title.frame(0, 0, w - cellHeight, cellHeight)
cell.title.text("测试" .. section .. "--" .. row .. "--" .. rowTitle)
cell.title.backgroundColor(0xdcdcdc)
end
},
ImageAndLabel = {
Size = function(section, row)
-- 返回Cell的宽、高
return w, cellHeight
end,
Init = function(cell, section, row)
-- Cell的初始化,一般在这里创建对应的Cell各个UI元素
cell.icon = Image()
cell.title = Label()
end,
Layout = function(cell, section, row)
-- Cell的布局,一般在这里对Cell的各个UI元素进行布局(设置位置、内容)
cell.icon.frame(20, 0, cellHeight, cellHeight)
cell.icon.image(imageUrl1)
cell.title.frame(20 + cellHeight, 0, w - cellHeight, cellHeight)
cell.title.text("测试" .. section .. "--" .. row .. "--" .. rowTitle)
end,
Callback = function(section, row)
-- 在这里处理Cell的点击事件,或者长按时间,默认处理的是点击事件,长按时间需要定义Callback为表
end
}
},
Callback = {-- 整个CollectionView的事件回调
Scrolling = function( firstVisibleSection, firstVisibleRow, visibleCellCount )
-- 滚动中回调
end,
ScrollBegin = function(firstVisibleSection, firstVisibleRow, visibleCellCount )
-- 滚动开始回调
end,
ScrollEnd = function(firstVisibleSection, firstVisibleRow, visibleCellCount )
-- 滚动结束回调
end
}
}
RefreshTableView
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | refreshEnable | v: Boolean | - | - | - |
2 | initRefreshing | - | - | - | 初始化刷新组件 |
3 | isRefreshing | - | v: Boolean | - | 是否正在刷新 |
4 | startRefreshing | - | - | - | 开始刷新 |
5 | stopRefreshing | - | - | - | 停止刷新 |
RefreshCollectionView
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | refreshEnable | v: Boolean | - | - | - |
2 | initRefreshing | - | - | iOS | 初始化刷新组件 |
3 | isRefreshing | - | v: Boolean | - | 是否正在刷新 |
4 | startRefreshing | - | - | - | 开始刷新 |
5 | stopRefreshing | - | - | - | 停止刷新 |
-- RefreshCollectionView 例子
local cv = RefreshCollectionView {
...
Callback = {-- 相比CollectionView,多了PullDown回调
...
PullDown = function()
-- 下拉刷新回调
end
}
}
PagerView
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | reload | - | - | - | 重新加载数据 |
2 | indicator | v: PagerIndicator | - | - | 设置页面组指示器 |
3 | currentPage | v: Number | v | - | 设置/获取当前页 |
4 | currentItem | v: Number | v | - | 设置/获取当前页 |
5 | autoScroll | duration: Number | - | - | 自动轮播 |
6 | looping | v: Boolean | v | - | 自动轮播 |
7 | previewSide | l: Number, r: Number | - | - | 支持左右透出预览 |
8 | showScrollBar | - | - | IOS | 是否显示类似CollectionView的滚动条 |
-- PagerView 列子
pagerView = PagerView{
PageCount = function()
-- 获取页面个数
return table:getn(net.options);
end,
Pages = {
Init = function(page, pos)
-- 页面初始化代码放置在这里,一般在这里创建出对应的视图,如
-- page.ui = Image()
end,
Layout = function(page, pos)
-- 页面对应的布局代码放置在这里,一般是对Page页面的内容进行填充,如
-- page.ui.image("image_url")
end
},
Callback = {-- 处理PagerView的各种事件,如滚动开始,滚动中,滚动结束事件
Scrolling = function(pageIndex, percent, offset)
-- PagerView的滚动监听写在这里
local x = (pageIndex - 1) * scrW + offset;
local y = 0;
if (bar) then
bar.renewContentScrollOffset(x, y);
end
end,
ScrollEnd = function(pageIndex)
-- PagerView滚动结束回调
end
}
};
PagerIndicator
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | unselectedColor | color: Number | color | - | 未选中指示器颜色 |
2 | selectedColor | color: Number | color | - | 选中指示器颜色 |
3 | fillColor | color: Number | color | Android | 未选中指示器颜色 |
4 | pageColor | color: Number | color | - | 未选中指示器颜色 |
4 | currentPageColor | color: Number | color | - | 选中指示器颜色 |
5 | strokeWidth | width: Number | width | Android | 线条宽度 |
6 | strokeColor | color: Number | color | Android | 线条颜色 |
7 | radius | v: Number | v | Android | 圆点半径 |
8 | snap | v: Boolean | v | Android | 是否有点移动动画 |
9 | currentPage | v: Number | v | - | 设置/获取当前页面 |
10 | currentItem | v: Number | v | Android | 设置/获取当前页面 |
CustomPagerIndicator
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | currentPage | v: Number | v | Android | 设置/获取当前页面 |
2 | currentItem | v: Number | v | Android | 设置/获取当前页面 |
CustomPanel
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | nativeView | - | - | - | 获取NativeView |
2 | getNativeView | - | - | - | 获取NativeView |
供第三方扩展用,不可直接创建。第三方通过扩展CustomPanel,实现已有的 Native UI 组件与 lua 互操作。
扩展后的CustomPanel,有所有View容器的API,如 frame、size、backgroundColor 等。
CustomPanel 扩展 - Android
1. 扩展LVCustomPanel,创建Native UI,并将创建出来的View添加到CustomPanel里
public class CustomLoading extends LVCustomPanel {
public CustomLoading(Globals globals, LuaValue metaTable, Varargs varargs) {
super(globals, metaTable, varargs);
}
@Override
public void initPanel() {
final View customLoading = new NativeLoading(getContext());
LayoutParams layoutParams = LuaViewUtil.createRelativeLayoutParamsWW();
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
customLoading.setVisibility(View.VISIBLE);
addView(customLoading, layoutParams);
}
}
2. 使用LuaView对象初始化的时候注册该 CustomPanel
luaview.registerPanel(CustomLoading.class)
或
luaview.registerPanel("CustomLoading", CustomLoading.class)
3. 在lua里使用该 CustomPanel,CustomPanel有所有View的api
local loading = CustomLoading()
loading.frame(0, 0, 100, 100)
HScrollView
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | offset | x: Number y: Number smooth: Boolean |
x, y | - | 滚动到x,y,smooth表示是否平滑滚动 |
2 | scrollTo | x: Number y: Number smooth: Boolean |
- | Android | 滚动到x,y,smooth表示是否平滑滚动 |
3 | offsetBy | dx: Number dy: Number smooth: Boolean |
x, y | Android | 滚动dx,dy,smooth表示是否平滑滚动 |
4 | scrollBy | dx: Number dy: Number smooth: Boolean |
- | Android | 滚动dx,dy,smooth表示是否平滑滚动 |
5 | smoothScrollTo | x: Number y: Number |
- | Android | 平滑滚动到x,y |
6 | smoothScrollBy | x: Number y: Number |
- | Android | 滚动到x,y |
7 | pageScroll | direction: Number | - | Android | 滚动一页(direction>0右滚,否则左滚) |
8 | fullScroll | direction: Number | - | Android | 滚动到底(direction>0右滚,否则左滚) |
9 | contentSize | - | - | iOS | 内容区域大小 |
WebView
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | loadUrl | v: String | - | - | 加载url |
2 | canGoBack | - | v: Boolean | - | 是否可以回退 |
3 | canGoForward | - | v: Boolean | - | 是否可以前进 |
4 | goBack | - | - | - | 回退一页 |
5 | goForward | - | - | - | 前进一页 |
6 | reload | - | - | - | 重新加载 |
7 | title | - | v: String | - | 获取Title |
8 | isLoading | - | v: Boolean | - | 是否正在加载 |
9 | stopLoading | - | - | - | 停止加载 |
10 | url | - | v: String | - | 获取url |
11 | pullRefreshEnable | v: Boolean | v | - | 是否可以下拉刷新 |
LoadingIndicator
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | start | - | - | - | 开始转动 |
2 | isStart | - | v: Boolean | Android | 是否开始转动 |
3 | startAnimating | - | - | Android | 开始转动 |
4 | isAnimating | - | v: Boolean | - | 是否在动画中 |
5 | stop | - | - | - | 停止动画 |
6 | stopAnimating | - | - | Android | 停止动画 |
7 | color | v: Number | v | - | 颜色 |
LoadingDialog
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | show | - | - | - | 开始转动 |
2 | isShow | - | v: Boolean | - | 是否开始转动 |
3 | start | - | - | - | 开始转动 |
4 | isStart | - | v: Boolean | - | 是否开始转动 |
5 | startAnimating | - | - | - | 开始转动 |
6 | isAnimating | - | v: Boolean | - | 是否开始转动 |
7 | hide | - | - | - | 停止动画 |
8 | stop | - | - | - | 停止动画 |
9 | stopAnimating | - | - | - | 停止动画 |
10 | color | v: Number | v | - | 颜色 |
Alert
Alert
Alert("提示", "这是一个提示", "OK", function()
print("OK clicked")
end)
Alert("提示", "这是一个提示", "OK", "Cancel", function()
print("OK clicked")
end, function()
print("Cancel clicked")
end)
local as1 = StyledString("一个按钮", { fontColor = 0xffff0000, backgroundColor = 0xff00ff00, fontSize = 30 })
local text = StyledString("文字", { fontColor = 0xffff0000, backgroundColor = 0xff00ff00, fontSize = 30 })
local ok = StyledString("确定", { fontColor = 0xffff0000, backgroundColor = 0xff00ff00, fontSize = 30 })
Alert(as1, text, ok, function()
print("点击了")
end)
Alert(title, content, buttonTexts[], buttonCallbacks[])
- title: String/StyledString/Unicode
- content: String/StyledString/Unicode
- buttonTexts[]: String/StyledString/Unicode []
- buttonCallbacks[]: LuaFunction[]
Toast
Toast
Toast("测试")
Toast(StyledString("测试", {fontColor=0xffff0000, backgroundColor=0xff00ff00, fontSize=50}))
Toast(message)
- message: String/StyledString/Unicode
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | show | v: String/StyledString/Unicode | - | - | 显示提示 |
StyledString
StyledString
StyledString("test", { fontColor = 0xff0000ff, fontSize = 14 })
StyledString(Unicode(0xe607), { fontColor = 0xff00aaff, fontStyle = "bold" })
StyledString(text, config)
- text: String/Unicode
- config: LuaTable
- fontSize: Number, 文字大小
- fontColor: Number, 文字颜色
- fontName: String, 文字样式
- fontWeight: Number/FontWeight, 文字权重
- fontStyle: String/FontStyle,文字样式
- backgroundColor: Number, 文字背景色
- strikethrough: Boolean,是否删除线
- underline: Boolean,是否下划线
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | append | v: StyledString | v | - | 新增一段 |
Animation
Animation
-- alpha动画
Animation().scale(2, 0.5).duration(2).delay(1)
-- 位移动画
view = View()
Animation().with(view).translation(100, -100).duration(3).interpolator(Interpolator.ACCELERATE_DECELERATE).callback({
onStart = function()
print("Running")
end,
onCancel = function()
print("Canceled")
end,
onEnd = function()
print("End")
end,
onPause = function()
print("Paused")
end,
onResume = function()
print("Running")
end,
})
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | with | v: View | - | - | 设置动画target |
2 | start | - | - | - | 开始动画 |
3 | alpha | v0: Number v1: Number |
- | - | 设置alpha动画 |
4 | rotation | v0: Number v1: Number |
- | - | 设置旋转动画 |
5 | scale | x: Number y: Number |
- | - | 设置缩放动画(x轴缩放比、y轴缩放比) |
6 | scaleX | x: Number |
- | - | 设置x轴缩放动画 |
7 | scaleY | y: Number |
- | - | 设置y轴缩放动画 |
8 | translation | x: Number y: Number |
- | - | 设置x轴、y轴位移动画 |
9 | translationX | x: Number | - | - | 设置x轴位移动画 |
10 | translationY | y: Number | - | - | 设置y轴位移动画 |
11 | duration | time: Number | - | - | 设置动画时长 |
12 | delay | time: Number | - | - | 设置动画启动延时 |
13 | repeatCount | count: Number | - | - | 设置动画重复测试(<0表示一直重复) |
14 | interpolator | v: Interplator | - | - | 插值器 |
15 | cancel | - | - | - | 取消动画 |
16 | pause | - | - | - | 暂停动画 |
17 | isPaused | - | v: Boolean | - | 动画是否暂停 |
18 | isRunning | - | v: Boolean | - | 动画是否运行 |
19 | resume | - | - | - | 恢复动画 |
20 | reverses | v: Boolean | - | - | 动画重复播放时是否反转 |
21 | values | v: Number[] | - | - | 设置动画用到的参数 |
22 | callback | v: LuaTable | - | - | 设置动画的回调 |
23 | onStart | v: LuaFunction | - | - | 动画开始回调 |
24 | onEnd | v: LuaFunction | - | - | 动画结束回调 |
25 | onRepeat | v: LuaFunction | - | - | 动画重复回调 |
26 | onCancel | v: LuaFunction | - | - | 动画取消回调 |
27 | onPause | v: LuaFunction | - | - | 动画暂停回调 |
28 | onUpdate | v: LuaFunction | - | Android | 动画状态更新回调 |
29 | onResume | v: LuaFunction | - | - | 动画恢复回调 |
Navigation
Navigation
Navigation.title("测试view")
img = Image();
img.image("http://gtms02.alicdn.com/tps/i2/TB1qmXnHpXXXXcuaXXXQG.m0FXX-640-128.jpg",function()
Navigation.background(img)
end);
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | title | v: String/StyledString/Unicode | v | - | 导航条标题 |
2 | background | v: String/Image | - | - | 设置导航条背景 |
3 | left | v: Boolean | v | - | 显示左侧按钮 |
4 | right | v: Boolean | v | - | 显示右侧按钮 |
Canvas
Canvas
local view = CustomView() -- onDraw方法需要配合CustomView使用
view.onDraw(function(canvas)
print(canvas)
-- drawLine
canvas.color(0xff0000)
canvas.strokeWidth(2)
canvas.drawLine(0, 50, 100, 50)
canvas.drawLine(50, 0, 50, 100)
canvas.resetPaint()
canvas.color(0x00ff00)
canvas.alpha(0.5)
canvas.drawLine(0, 0, 100, 0)
canvas.drawLine(100, 0, 100, 100)
canvas.drawLine(100, 100, 0, 100)
canvas.drawLine(0, 100, 0, 0)
canvas.drawLine(0, 0, 100, 100)
canvas.drawLine(100, 0, 0, 100)
-- drawPoint
canvas.color(0xff0000)
canvas.strokeWidth(2)
canvas.drawPoint(1, 5)
canvas.drawPoint(99, 93)
-- drawRect
canvas.resetPaint()
canvas.style(PaintStyle.STROKE)
canvas.drawRect(5, 5, 5, 5)
canvas.style(PaintStyle.FILL)
canvas.drawRect(10, 10, 5, 5)
-- drawRoundRects
canvas.drawRoundRect(45, 1, 5, 5, 2, 2)
canvas.drawRoundRect(45, 5, 10, 5, 2, 2)
-- drawCircle
canvas.drawCircle(80, 0, 5)
canvas.drawCircle(80, 15, 5)
-- drawText
canvas.textSize(20)
canvas.drawText("x", 20, 55)
canvas.textSize(14)
canvas.drawText("y", 20, 65)
canvas.resetPaint()
-- drawOval
canvas.drawOval(45, 50, 25, 10)
canvas.drawOval(45, 60, 25, 10)
-- draw Arc
canvas.drawArc(30, 30, 20, 20, 0, 90, true)
-- drawBitmap
canvas.save()
canvas.rotate(-10, 100, 100)
canvas.scale(1.2)
canvas.translate(-10, -10)
canvas.strokeWidth(10)
canvas.textSize(15)
canvas.bold(true)
canvas.drawText("测试一下", 20, 150)
canvas.alpha(0.5)
canvas.drawImage("animate1", 0, 100, 100, 100)
canvas.restore()
canvas.resetPaint()
print(img)
if(img) then
canvas.drawImage(img, 100, 0, 100, 100)
end
-- clipRect
canvas.clipRect(100, 100, 35, 35)
canvas.drawCircle(100, 100, 40)
canvas.clipRect(150, 150, 30, 30)
canvas.drawText("TestABCDEFGHEFGHIJKLMOPQRST", 150, 150)
print(canvas.nativeObj())
end)
-- ps
1. Android所有绘制API支持同时多个参数,如:
canvas.drawLine({
{ 0, 0, 100, 0 },
{ 100, 0, 100, 100 },
{ 100, 100, 0, 100 },
{ 0, 100, 0, 0 },
{ 0, 0, 100, 100 },
{ 100, 0, 0, 100 }
})
2. Android所有绘制API支持设置绘制参数,如:
canvas.drawText({
{ "xx", 20, 75, { color = 0x0000ff, strikeThrough = true, textSize = 20, textSkewX = 1.5, bold = true } },
{ "yy", 20, 85 },
}, { color = 0x0fff00, underline = true, textSize = 10, textScaleX = 3, letterSpacing = 0.2, linearText = true })
a. 绘制API
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | drawLine | x1: Number y1: Number x2: Number y2: Number |
- | - | 绘制线条。(x1,y1), (x2, y2)分别为起点终点 |
2 | drawPoint | x: Number y: Number |
- | - | 绘制点 |
3 | drawRect | x: Number y: Number w: Number h: Number |
- | - | 绘制矩形。x起点x坐标,y起点y坐标,w宽度,h高度 |
4 | drawRoundRect | x: Number y: Number w: Number h: Number rx: Number ry: Number |
- | - | 绘制圆角矩形。x起点x坐标,y起点y坐标,w宽度,h高度,rx为x轴圆角半径,ry为y轴圆角半径 |
5 | drawCircle | x: Number y: Number r: Number |
- | - | 绘制圆。(x, y)为圆心坐标,r为半径 |
6 | drawOval | x: Number y: Number rx: Number ry: Number |
- | - | 绘制椭圆。(x, y)为圆心坐标,rx, ry为椭圆半径 |
7 | drawArc | x: Number y: Number w: Number h: Number startAngle: Number sweepAngle: Number useCenter: Boolean |
- | - | 绘制扇形。(x,y)为左上角坐标,(w,h)为扇形宽高,startAngle为开始角度,sweepAngle为覆盖角度, useCenter为是否覆盖完整扇形面积(默认为false) |
8 | drawText | text: String/StyledString/Unicode x: Number y:Number |
- | - | 绘制文本 |
9 | drawImage | image: String/Image x: Number y: Number w: Number h: Number |
- | - | 绘制图片,支持本地图和Image对象 |
b. 画笔属性API
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | color | color: Number | - | - | 设置画笔颜色 |
2 | alpha | alpha: Number | - | - | 设置画笔透明度 |
3 | strokeWidth | w: Number | - | - | 设置画笔粗细 |
4 | style | style: PaintStyle | - | - | 设置画笔填充样式 |
5 | textSize | size: Number | - | - | 设置文本字体大小 |
6 | font | name: String | - | - | 设置字体名称 |
7 | bold | bold: Boolean | - | - | 设置是否粗体 |
8 | resetPaint | - | - | - | 重置画笔所有属性 |
c. 画布变换API
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | translate | dx: Number dy: Number |
- | - | 位移变换,dx为x轴移动距离,dy为y轴移动距离 |
2 | scale | sx: Number sy: Number |
- | - | 缩放变换,sx为x轴缩放比率,sy为y轴缩放比率 |
3 | rotate | r: Number x: Number y: Number |
- | - | 旋转变换,r为角度;(x,y) 坐标(可选) |
4 | skew | x: Number y: Number |
- | Android | 斜切变换,xy斜切比率 |
d. 其它API
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | nativeObj | - | native canvas | - | 获取对应的native对象 |
2 | save | - | - | - | 保存当前画布状态 |
3 | restore | - | - | - | 恢复当前画布状态 |
4 | clipRect | left: Number top: Number right: Number bottom: Number |
- | - | 裁剪矩形区域 |
5 | size | - | w, h | - | 获取画布尺寸 |
API-NUI
Http
Http
Http({
"method": "POST",
"params": {
"k1": "v1",
"k2": "v2"
}
}, function(response)
print("called success")
end)
http = Http()
http.get("http://luaview.github.io", {
query = 1
}, function(response)
print("called success")
end)
Http(initParams, callback)
- initParams: LuaTable,请求参数
- method: String, 请求方法
- params: LuaTable, 请求业务参数
- callback: LuaFunction, 回调
- 返回参数response为LuaTable
- response.data() 得到 Data数据
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | url | v: String | v | Android | 设置请求Url |
2 | method | v: String, get/post | v | Android | 设置请求方法 |
3 | retryTimes | v: Number | v | Android | 重试次数 |
4 | timeout | v: Number | v | Android | 超时时间 |
5 | params | v: LuaTable | v | Android | 请求参数 |
6 | callback | v: LuaFunction | Android | 请求回调 | |
7 | request | - | - | Android | 请求 |
8 | cancel | - | - | - | 中止 |
9 | get | url: String params: LuaTable callback: LuaFunction |
- | - | GET请求 |
10 | post | url: String params: LuaTable callback: LuaFunction |
- | - | POST请求 |
11 | header | - | IOS | http响应的头信息 | |
11 | data | - | IOS | http响应的数据体(数据块类型) | |
11 | code | - | IOS | http响应的code |
Timer
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | delay | v: Number | v | - | 启动延时 |
2 | repeat | v: Number | v | - | 重复次数 |
3 | repeatCount | v: Number | v | - | 重复次数 |
4 | interval | v: Number | v | - | 重复间隔 |
5 | start | v: Number | v | - | 启动 |
6 | callback | v: LuaFunction | v | - | 回调 |
7 | cancel | - | - | - | 取消 |
System
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | ios | - | v: Boolean | - | 是否iOS平台 |
2 | android | - | v: Boolean | - | 是否Android平台 |
3 | vmVersion | - | v: String | - | LuaView版本 |
4 | osVersion | - | v: String | - | 操作系统版本 |
5 | platform | - | v: String | - | 平台系统型号 |
6 | scale | - | v: Number | - | 屏幕缩放比 |
7 | device | - | v: LuaTable | - | 设备信息 |
8 | screenSize | - | w: Number h: Number |
- | 屏幕尺寸 |
9 | network | - | v: String | - | 网络类型(“none”, “2g”, “3g”, “4g”, “wifi”, “unknown”) |
10 | gc | - | - | - | 执行内存回收 |
11 | keepScreenOn | v: Boolean | - | - | 是否保持屏幕常亮 |
AudioPlayer
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | play | name: String times: Number |
- | - | 播放(uri,重复次数) |
2 | pause | - | - | Android | 暂停播放 |
3 | resume | - | - | Android | 恢复播放 |
4 | stop | - | - | - | 停止播放 |
5 | seekTo | sec: Number | - | Android | 到某个位置 |
6 | callback | v: LuaFunction | v | Android | 回调 |
7 | playing | - | v: Boolean | Android | 是否播放 |
8 | pausing | - | v: Boolean | Android | 是否暂停 |
9 | looping | - | v: Boolean | Android | 是否循环播放 |
Vibrator
Vibrator
local vibrator = Vibrator()
vibrator.vibrate() -- 默认震动
vibrator.vibrate(2) -- 震动两次
vibrator.vibrate({1, 2, 1, 0.3, 0.2, 0.1, 0.01, 1.1}, 4) -- 特殊震动模式
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | hasVibrator | - | v: Boolean | - | 是否有震动硬件 |
2 | vibrate | mode: Number[], repeatTimes: Number | - | - | 震动(模式,次数) |
3 | cancel | - | - | - | 取消震动 |
Unicode
Unicode
Unicode(0xe607)
Unicode(char)
- char 为Unicode字符编码
Data
Data
Data("a")
Data(97, "abc", "def")
Data('{"a":"1"}')
Data('a').toString("latin-1")
Data('{"a":"1"}').toTable()
Data('{"a":"1"}').toJson()
Data(str)
- str: String/JsonString
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | append | v: Data/byte[] | - | - | 新增部分数据 |
2 | toString | code: String | v: String | - | 转成String(编码格式) |
3 | toJson | - | v: String | - | 转成Json String |
4 | toTable | - | v: LuaTable | - | 转成LuaTable |
Json
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | toTable | v: String/Data/LuaTable | r: LuaTable | - | 给定内容转成LuaTable |
2 | isValid | v: String/Data | r: Boolean | Android | 是否有效JsonString |
File
File
http = Http()
http.get("http://luaview.github.io", {
query = 1
}, function(response)
local data = response:data()
-- 保存
File.save(data, "test.html") -- 同步存
File.save(data, "test.html", function(status)
-- 异步存
end)
-- 读取
data = File.read("test.html") -- 同步读
File.read("test.html", function(data)
-- 异步读取
end)
-- 存在判断
print(File.exists("test.html"))
-- 文件路径
print(File.path("test.html"))
end)
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | save | path: String data: Data callback: LuaFunction or data: Data path: String callback: LuaFunction |
- | - | 保存data内数据到path指定的文件内,文件名支持子目录或者上级目录 |
2 | read | path: String callback: LuaFunction |
Data | - | 读取给定path的文件,并返回Data数据,支持异步读取,异步返回数据通过callback返回 |
3 | exists | path: String | - | - | 文件是否存在 |
4 | path | name: filename | path:String | - | 获取给定文件名的绝对存储路径 |
Downloader
ID | API | 参数 | 返回值 | 平台 | 备注 |
---|---|---|---|---|---|
1 | fetch | url: String name: String callback: LuaFunction |
- | - | TODO |
API-Constants
Align
ID | 值 | 平台 | 备注 |
---|---|---|---|
1 | LEFT | - | 左对齐 |
2 | TOP | - | 顶对齐 |
3 | RIGHT | - | 右对齐 |
4 | BOTTOM | - | 底对齐 |
5 | CENTER | - | 整体居中 |
6 | H_CENTER | - | 水平居中 |
7 | V_CENTER | - | 垂直居中 |
8 | START | Android | 左or上对齐 |
9 | END | Android | 右or下对齐 |
TextAlign
ID | 值 | 平台 | 备注 |
---|---|---|---|
1 | LEFT | - | 左&垂直居中 |
2 | RIGHT | - | 整体居中 |
3 | CENTER | - | 右&垂直居中 |
FontWeight
ID | 值 | 平台 | 备注 |
---|---|---|---|
1 | NORMAL | - | 正常 |
2 | BOLD | - | 粗体 |
FontStyle
ID | 值 | 平台 | 备注 |
---|---|---|---|
1 | NORMAL | - | 正常 |
2 | ITALIC | - | 斜体 |
3 | BOLD | - | 粗体 |
ScaleType
ID | 值 | 平台 | 备注 |
---|---|---|---|
1 | FIT_XY | - | 左上铺满 |
2 | FIT_START | - | 左or上铺满 |
3 | FIT_END | - | 右or下铺满 |
4 | FIT_CENTER | - | 居中铺满 |
5 | CENTER | - | 居中 |
6 | CENTER_CROP | - | 居中裁剪 |
7 | CENTER_INSIDE | - | 居中包含 |
8 | MATRIX | - | 矩阵 |
Gravity
ID | 值 | 平台 | 备注 |
---|---|---|---|
1 | LEFT | Android | 左对齐 |
2 | TOP | Android | 上对齐 |
3 | RIGHT | Android | 右对齐 |
4 | BOTTOM | Android | 下对齐 |
5 | START | Android | 左or上对齐 |
6 | END | Android | 右or下对齐 |
7 | CENTER | Android | 居中对齐 |
8 | H_CENTER | Android | 水平居中对齐 |
9 | V_CENTER | Android | 垂直居中对齐 |
10 | FILL | Android | 铺满 |
11 | H_FILL | Android | 水平铺满 |
12 | V_FILL | Android | 垂直铺满 |
Ellipsize
ID | 值 | 平台 | 备注 |
---|---|---|---|
1 | START | - | 起始位置省略 |
2 | MIDDLE | - | 中间位置省略 |
3 | END | - | 结束为止省略 |
4 | MARQUEE | - | 跑马灯 |
Interpolator
ID | 值 | 平台 | 备注 |
---|---|---|---|
1 | ACCELERATE_DECELERATE | - | 先加速后减速插值 |
2 | ACCELERATE | - | 加速插值 |
3 | ANTICIPATE | - | 预期插值 |
4 | ANTICIPATE_OVERSHOOT | - | 预期弹性插值 |
5 | BOUNCE | Android | 回弹插值 |
6 | CYCLE | Android | 环形插值 |
7 | DECELERATE | - | 减速插值 |
8 | LINEAR | - | 线性插值 |
9 | OVERSHOOT | Android | 弹性插值 |
ViewEffect
ID | 值 | 平台 | 备注 |
---|---|---|---|
1 | NONE | - | 无特效 |
2 | CLICK | Android | 点击水波纹特效 |
3 | PARALLAX | - | 视差特效 |
PaintStyle
ID | 值 | 平台 | 备注 |
---|---|---|---|
1 | FILL | - | 填充 |
2 | STROKE | - | 中空 |
3 | EOFILL | IOS | 中空 |
4 | FILLSTROKE | IOS | 中空 |
5 | EOFILLSTROKE | IOS | 中空 |
Extends LuaView
Scenarios
虽然LuaView包含了常用的大部分控件,但是开发者有自己的定制需求,这些定制需求可以大致分为以下几种情况
1. 已经有native的UI组件,想让该native组件与lua进行交互。
如:开发者A在使用LuaView之前,已经开发了一个自定义的View,该自定义View能够完成某些功能,想在lua中使用该组件,实现native与lua互操作。
2. 有某些功能,需要与lua码进行交互。
如以下场景:
- 需要在 native 中调用 lua 函数,执行某个功能,或者得到某个结果。
- 需要在 lua 调用 native 函数,执行 native 中的某个功能,或者得到某个结果。
3. 需要使用自己的图片库。
如:开发者A使用自定义的图片库,而非Glide(LuaView默认图片库)。
4. 预定义组件无法满足需求,需要自己实现一套组件。
如以下场景:
- 开发者A不想使用LuaView内置的Button,而是使用自己开发的Button组件。
- 开发者想跟LuaView一样,在lua代码中使用完整的组件,并包含自己的API,如 VideoView
1. 已有 Native UI 组件
开发者A,在自己的项目中,有统一的Native Loading UI,在 lua 中写的页面或UI组件中也需要使用该Loading UI。为了避免重复开发已有功能,LuaView 支持将现有功能通过简单封装,桥接到 lua 层,赋予该 Native UI 与 lua 互操作的能力。既可以在 lua 中创建出该UI,也可以操作该UI,改变其状态或功能,也可以在在该 Native UI 中调用相应的 lua 代码。
扩展方式大概分为以下几步:
CustomPanel - Android
1. 继承LVCustomPanel
public class CustomLoading extends LVCustomPanel {
public CustomLoading(Globals globals, LuaValue metaTable, Varargs varargs) {
super(globals, metaTable, varargs);
}
@Override
public void initPanel() {
//TODO 在这里创建Native UI
}
}
2. 实现initPanel方法,创建Native UI,并添加的CustomPanel里
@Override
public void initPanel() {
//创建Native UI
final View customLoading = new NativeLoading(getContext());
LayoutParams layoutParams = LuaViewUtil.createRelativeLayoutParamsWW();
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
customLoading.setVisibility(View.VISIBLE);
//添加到CustomPanel里
addView(customLoading, layoutParams);
}
3. Native调用Lua
@Override
public void initPanel() {
//创建Native UI
final View customLoading = new NativeLoading(getContext());
//添加View...
//绑定事件
customLoading.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
//1. 调用该View的回调,params为函数参数,类型为Object...
callLuaCallback(params);
//2. 调用脚本的全局方法,params为函数参数,类型为Object...
callLuaFunction("globalFun", params);
}
});
}
4. LuaView注册CustomPanel
luaview.registerPanel(CustomLoading.class)
或者
luaview.registerPanel("新名称(默认是类名称)", CustomLoading.class)
5. Lua代码
-- 在Lua代码中直接创建CustomPanel对象
local loading = CustomLoading()
loading.frame(0, 0, 100, 100)
loading.callback(function()
-- Native UI调用该函数
end)
function globalFun(param1, param2)
-- Native UI调用该函数
end
a. 扩展CustomPanel
在LuaView中有一个CustomPanel组件,用于将已有的Native UI组件进行包装。开发者可以通过扩展CustomPanel来实现现有组件复用。
b. 实现initPanel()方法
在initPanel里面创建Native UI组件,并添加到CustomPanel中。 CustomPanel本身实际上是一个Android的ViewGroup, 所创建的Native UI是该ViewGroup的子View
c. Native UI 中绑定事件,以便调用 Lua 代码
在Native UI中事件发生时,通过调用对应脚本的Lua函数,来实现相互通信。目前有两种调用方式 * 一种是调用脚本的全局方法 * 一种是调用CustomPanel的Callback方法
d. 注册CustomPanel到LuaView
写好CustomPanel以后,就可以在LuaView启动的时候注册对应的CustomPanel。使用函数registerPanel()
e. 在Lua中使用CustomPanel
注册好的CustomPanel,可以在Lua脚本中直接使用,且有View的所有方法,包含容器方法
2. native-lua 互操作
开发者A有部分功能需要在Lua中使用,如判断是否登陆,页面跳转等逻辑。
扩展方式大概分为以下几步:
Bridge - Android
1. 书写Bridge函数
public class LuaViewBridge {
private Activity mActivity;
public LuaViewBridge(Activity activity) {
this.mActivity = activity;
}
//页面跳转
public void openPage(String pageUri){
Intent intent = new Intent();
intent.setData(Uri.parse(pageUri));
mActivity.startActivity(intent);
}
//判断是否登陆
public boolean isLogin(){
return true;
}
}
2. 注册Bridge
luaview.register("bridge", new LuaViewBridge())
3. Lua中使用
-- open page
bridge.openPage("http://luaview.github.io")
-- 判断是否login
local isLogin = bridge.isLogin()
a. 创建Bridge
在Android中,LuaView的Bridge就是一个简单的Object,任何Object都可以,创建出该Object,注册到LuaView即可实现lua操作Native。
b. 注册Bridge
使用LuaView.register(“bridge”, new LuaViewBridge())注册一个bridge对象。
c. Lua中使用
创建出来的bridge可以在lua中直接使用,支持所有基本类型互传。
3. 使用自己的图片库
默认LuaViewSDK使用Glide图片库,第三方可以通过实现ImageProvider来自接入自定义的图片库
扩展方式大概分为以下几步:
自定义图片库 - Android
1. 实现ImageProvider接口
public class CustomImageProvider implements ImageProvider {
/**
* 下载图片
* @param imageView
* @param url
* @param callback
*/
void load(final Context context, final WeakReference<BaseImageView> imageView, final String url, final WeakReference<BaseImageView.LoadCallback> callback);
/**
* 预下载图片
* @param context
* @param url
* @param callback
*/
void preload(final Context context, final String url, final BaseImageView.LoadCallback callback);
/**
* pause all requests
* @param context
*/
void pauseRequests(final ViewGroup view, final Context context);
/**
* resume all requests
* @param context
*/
void resumeRequests(final ViewGroup view, final Context context);
}
2. 注册ImageProvider
luaview.registerImageProvider(CustomImageProvider.class)
a. 自定义CustomImageProvider,实现ImageProvider接口
自定义一个ImageProvider,实现对应的方法。
b. 注册ImageProvider
使用LuaView.registerImageProvider()注册Provider。
4. 扩展完整组件
某些情况下,开发者想要自己实现一整套组件,然后在lua中使用,或者想要覆盖SDK里的内置组件。如,开发者A想要开发一个组件CustomButton组件,在lua中直接使用;或A想要使用自定义的native Button,而非SDK里的Button组件。
扩展方式大概分为以下几步:
扩展完整组件 - Android
1. 创建Binder
public class CustomButtonBinder extends BaseFunctionBinder {
public CustomButtonBinder() {
//在这里指定名称
}
@Override
public Class<? extends LibFunction> getMapperClass() {
//TODO 在这里指定方法列表 return CustomButtonMethodMapper.class;
}
@Override
public LuaValue createCreator(LuaValue env, LuaValue metaTable) {
// Userdata 对象
}
}
2. 指定名称、方法映射表、Lua userdata
a. 指定名称:
public CustomButtonBinder() {
super("CustomButton"); //名称为CustomButton
}
b. 指定方法列表
@Override
public Class<? extends LibFunction> getMapperClass() {
return CustomButtonMethodMapper.class; //方法列表为CustomButtonMethodMapper类对应的所有方法
}
c. Lua userdata
@Override
public LuaValue createCreator(LuaValue env, LuaValue metaTable) {
return new BaseVarArgUICreator(env.checkglobals(), metaTable, getMapperClass()) {//这里使用的UICreator,对应的有BaseVarArgCreator、BaseVarArgUICreator
@Override
public ILVView createView(Globals globals, LuaValue metaTable, Varargs varargs) {
return new CustomButton(globals, metaTable, varargs);
}
};
}
3. 实现 CustomButton,实现 ILVView接口,如果是ViewGroup的话,实现ILVViewGroup接口
public class CustomButton extends Button implements ILVView {
private UDView mLuaUserdata;
public CustomButton(Globals globals, LuaValue metaTable, Varargs varargs) {
super(globals.getContext());
this.mLuaUserdata = new UDCustomButton(this, globals, metaTable, varargs);
}
@Override
public UDView getUserdata() {
return mLuaUserdata;
}
}
4. 实现UDCustomButton,继承自UDView,如果是ViewGroup的话,继承UDViewGroup
public class UDCustomButton extends UDTextView<Button> {
public UDButton(Button view, Globals globals, LuaValue metatable, Varargs initParams) {
super(view, globals, metatable, initParams);
}
}
5. 实现CustomButtonMethodMapper,通过继承不同的MethodMapper来复用已经定义好的方法
@LuaViewLib
public class CustomButtonMethodMapper<U extends UDCustomButton> extends UITextViewMethodMapper<U> {
private static final String TAG = CustomButtonMethodMapper.class.getSimpleName();
private static final String[] sMethods = new String[]{
"customMethod"
};
@Override
public List<String> getAllFunctionNames() {
return mergeFunctionNames(TAG, super.getAllFunctionNames(), sMethods);
}
@Override
public Varargs invoke(int code, U target, Varargs varargs) {
final int optcode = code - super.getAllFunctionNames().size();
switch (optcode) {
case 0:
return customMethod(target, varargs);
}
return super.invoke(code, target, varargs);
}
public LuaValue customMethod(U view, Varargs varargs) {
//获取参数 varargs.arg(2), 参数从2开始,1的位置是self。具体使用参见SDK实现
//set方法返回view本身,用于链式调用,get方法返回函数调用值
}
}
6. 注册CustomButton
luaview.registerLibs(new CustomButtonBinder()))
7. lua调用
local btn = CustomButton()
btn.frame(0, 0, 100, 100)
btn.text("自定义按钮")
btn.customMethod()
a. 创建Binder
binder用于将native功能绑定到lua中,定义了在lua中的名称、方法映射表、对象。 通过继承BaseFunctionBinder可以创建一个Binder
b. 指定名称、方法映射表、Lua userdata
- 名称:是在Lua中使用的直接名称,如Button
- 方法映射表:是该lua对象拥有的native-lua方法列表,是该组件的完整api列表
- lua实体:是lua中对象的实体,是一个Userdata
c. 实现CustomButton
CustomButton是自定义的Button组件,为了跟Lua进行交互,需要在其内部绑定一个Lua对象。可以通过实现ILVView或者ILVViewGroup接口,实现对应接口来完成。
d. 实现UDCustomButton
UDXXX是Lua中的Userdata对象,自定义的Userdata可以继承UDView或者UDViewGroup来扩展功能
e. 实现CustomButtonMethodMapper
MethodMapper是Native-Lua方法的映射表,如果想要复用以后的方法表,可以通过继承对应的MethodMapper来实现,如View的话继承LVViewMethodMapper,ViewGroup的话继承LVViewGroupMethodMapper。
f. 注册CustomButton
使用luaview.registerLibs()来实现
g. lua调用
注册好后,可以直接在lua代码中使用自定义的库
Examples
Tools for LuaView
1. LuaViewDegbugger
LuaViewSDK 的lua代码调试器
2. LuaViewBytecodeCompiler
- LuaViewBytecodeCompiler用于将LuaView的源码预编译成Lua bytecode。加速LuaViewSDK for Android的执行
- 该工具编译出来的bytecode代码只能用于Android端,暂时不能用于iOS端
Usage
- 创建项目普通Java项目ProjA
- 引入jar包
- 使用jar包提供的函数对lua代码进行打包(LuaViewBytecodeCompiler类)
- A:public static byte[] compile(byte[] source, String filename) throws Exception
- 将一个源码的二进制流编译成lua bytecode二进制流
- B:public static void compile(String filePath) throws Exception
- 将给定代码地址的代码编译成lua bytecode并保存在同目录下,文件名为*.luap
- A:public static byte[] compile(byte[] source, String filename) throws Exception
- 在Android项目直接使用编译好的bytecode,功能同load函数
- luaView.loadPrototype(final InputStream inputStream, final String name, final LuaScriptLoader.ScriptExecuteCallback callback)
Changes Log
V6.0 (2017-?) TODO
- large changes
V5.8.0 (2017-1.10)
- 自定义下拉刷新
V5.5.0 (2016-12)
- Canvas 支持
- 手势 支持
- 全局坐标
- 下拉定制
V5.4.0 (2016-11)
- 吸附菜单(CollectionView)
- 视差动画(ViewEffect.PARALLAX)
- 圆角图片
- Android
- 图片内存回收机制优化
V5.3.0 (2016-10)
- WebView
- CollectionView 支持按Section、Row进行刷新
- Android
- ViewEffect.CLICK 的 Ripple 支持不同颜色
- 图片Alpha动画优化