NAV
lua

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函数调用

如:
 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[])

Toast

Toast

Toast("测试")

Toast(StyledString("测试", {fontColor=0xffff0000, backgroundColor=0xff00ff00, fontSize=50}))

Toast(message)

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)

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.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)

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)

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)

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码进行交互。

如以下场景:

3. 需要使用自己的图片库。

如:开发者A使用自定义的图片库,而非Glide(LuaView默认图片库)。

4. 预定义组件无法满足需求,需要自己实现一套组件。

如以下场景:

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

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

Usage

  1. 创建项目普通Java项目ProjA
  2. 引入jar包
  3. 使用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
  4. 在Android项目直接使用编译好的bytecode,功能同load函数
    • luaView.loadPrototype(final InputStream inputStream, final String name, final LuaScriptLoader.ScriptExecuteCallback callback)

Changes Log

V6.0 (2017-?) TODO

V5.8.0 (2017-1.10)

V5.5.0 (2016-12)

V5.4.0 (2016-11)

V5.3.0 (2016-10)

lua