├── .gitignore
├── .idea
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── gradle.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── LICENSE
├── README.md
├── app
├── .gitignore
├── app-release.apk
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── sf
│ │ └── ALuaGuide
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ ├── AndroLua帮助.txt
│ │ ├── Intent类.txt
│ │ ├── LuaManual
│ │ │ ├── contents.html
│ │ │ ├── glossary.html
│ │ │ ├── logo.gif
│ │ │ └── manual.html
│ │ ├── Lua教程.txt
│ │ ├── 基础代码.txt
│ │ ├── 实用代码.txt
│ │ ├── 文件操作.txt
│ │ ├── 用户界面.txt
│ │ ├── 笔记.txt
│ │ └── 网络操作.txt
│ ├── java
│ │ └── com
│ │ │ └── sf
│ │ │ ├── ALuaGuide
│ │ │ ├── CodeActivity.java
│ │ │ ├── DataManager.java
│ │ │ ├── ExceptionsHandle.java
│ │ │ ├── MainActivity.java
│ │ │ ├── MainPagerAdapter.java
│ │ │ ├── MyPreferenceActivity.java
│ │ │ ├── MySwipeBackActivity.java
│ │ │ ├── MySwipeRefreshLayout.java
│ │ │ ├── PreviewActivity.java
│ │ │ ├── RecyclerAdapter.java
│ │ │ ├── ScrollingFABBehavior.java
│ │ │ ├── SearchActivity.java
│ │ │ ├── SearchAdapter.java
│ │ │ ├── SettingsActivity.java
│ │ │ ├── ShowActivity.java
│ │ │ ├── ShowAdapter.java
│ │ │ └── WebViewActivity.java
│ │ │ └── LuaEditor
│ │ │ ├── CodeEditText.java
│ │ │ ├── LuaLexer.java
│ │ │ ├── LuaTokenTypes.java
│ │ │ └── ShaderEditor.java
│ └── res
│ │ ├── drawable
│ │ ├── ic_book.png
│ │ ├── ic_close.png
│ │ ├── ic_search.png
│ │ └── touch_item.xml
│ │ ├── layout
│ │ ├── activity_code.xml
│ │ ├── activity_lua_manual.xml
│ │ ├── activity_main.xml
│ │ ├── activity_preview.xml
│ │ ├── activity_search.xml
│ │ ├── activity_show.xml
│ │ ├── content_main.xml
│ │ ├── page1.xml
│ │ ├── page1_item.xml
│ │ ├── page2.xml
│ │ ├── page2_item.xml
│ │ ├── search_item.xml
│ │ └── show_item.xml
│ │ ├── menu
│ │ └── menu_main.xml
│ │ ├── mipmap
│ │ └── ic_launcher.png
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ │ └── xml
│ │ └── pref_main.xml
│ └── test
│ └── java
│ └── com
│ └── sf
│ └── ALuaGuide
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 王家晔
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ALua手册(ALuaGuide)
2 |
3 | 重生版ALua手册对比老版本新增了非常多的内容,并且使用了自己写的编辑器,内容比之前多了很多,并且纯手册,零权限,美观而又实用。
4 |
5 | ## 关于
6 |
7 | 因老版本内容太少,兼容性差,并且因服务器出现问题而无法加载内容,于是时隔了近一年的我,在暑假拥有了自己的电脑后,开始了Android Studio的第一个项目——ALua手册重生版,以此纪念我第一个上架的App,从Lua语言,AndroLua开始的Android开发旅程。
8 |
9 | ## 截图
10 | 
11 | 
12 | 
13 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/app-release.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HK-SHAO/ALuaGuide/26822e92d4a0f150d0355af883542ed33fea5f6d/app/app-release.apk
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion "26.0.0"
6 | defaultConfig {
7 | applicationId "com.sf.ALuaGuide"
8 | minSdkVersion 15
9 | targetSdkVersion 25
10 | versionCode 9
11 | versionName "0.9"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | vectorDrawables.useSupportLibrary = true
14 | resConfigs "cn"
15 | }
16 | buildTypes {
17 | release {
18 | minifyEnabled true
19 | shrinkResources true
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | }
24 |
25 | dependencies {
26 | compile fileTree(include: ['*.jar'], dir: 'libs')
27 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
28 | exclude group: 'com.android.support', module: 'support-annotations'
29 | })
30 | compile 'com.android.support:appcompat-v7:25.3.1'
31 | compile 'com.android.support:design:25.3.1'
32 | compile 'com.android.support:recyclerview-v7:25.3.1'
33 | compile 'com.android.support:support-v4:25.3.1'
34 | compile 'com.android.support:cardview-v7:25.3.1'
35 | compile 'me.imid.swipebacklayout.lib:library:+'
36 | testCompile 'junit:junit:4.12'
37 | }
38 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | -optimizationpasses 5 # 指定代码的压缩级别
2 | -dontusemixedcaseclassnames # 是否使用大小写混合
3 | -dontpreverify # 混淆时是否做预校验
4 | -verbose # 混淆时是否记录日志
5 |
6 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # 混淆时所采用的算法
7 |
8 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/sf/ALuaGuide/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.sf.ALuaGuide", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
23 |
24 |
25 |
29 |
32 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/assets/AndroLua帮助.txt:
--------------------------------------------------------------------------------
1 | 《《关于AndroLua》》
2 | 《《AndroLua是基于LuaJava开发的安卓平台轻量级脚本编程语言工具,既具有Lua简洁优雅的特质,又支持绝大部分安卓API,可以使你在手机上快速编写小型应用。
3 | 官方QQ群:236938279;官方QQ2群:621400904
4 | 百度贴吧:
5 | http://c.tieba.baidu.com/mo/m?kw=androlua
6 | 项目地址:
7 | https://github.com/nirenr/AndroLua_pro
8 | 打开链接支持nirenr的工作,一块也可以哦:
9 | https://qr.alipay.com/apt7ujjb4jngmu3z9a
10 |
11 | AndroLua使用了以下开源项目部分代码
12 |
13 | bson,crypt,md5
14 | https://github.com/cloudwu/skynet
15 |
16 | cjson
17 | https://sourceforge.net/projects/cjson/
18 |
19 | zlib
20 | https://github.com/brimworks/lua-zlib
21 |
22 | xml
23 | https://github.com/chukong/quick-cocos2d-x
24 |
25 | luv
26 | https://github.com/luvit/luv
27 | https://github.com/clibs/uv
28 |
29 | zip
30 | https://github.com/brimworks/lua-zip
31 | https://github.com/julienr/libzip-android
32 |
33 | luagl
34 | http://luagl.sourceforge.net/
35 |
36 | luasocket
37 | https://github.com/diegonehab/luasocket
38 |
39 | sensor
40 | https://github.com/ddlee/AndroidLuaActivity
41 |
42 | canvas
43 | 由落叶似秋开发
44 |
45 | jni
46 | 由nirenr开发》》
47 | 《《软件基本操作》》
48 | 《《工程结构
49 | init.lua 工程配置文件
50 | main,lua 工程主入口文件
51 | layout.aly 工程默认创建的布局文件
52 |
53 | 菜单功能
54 | 三角形 运行:执行当前工程
55 | 左箭头 撤销:撤销输入的内容
56 | 右箭头 重做:恢复撤销的内容
57 | 打开:打开文件,在文件列表长按可删除文件
58 | 最近:显示最近打开过的文件
59 |
60 | 文件
61 | 保存:保存当前文件
62 | 新建:新建lua代码文件或者aly布局文件,代码文件与布局文件文件名不可以相同
63 | 编译:把当前文件编译为luac文件,通常用不到
64 |
65 | 工程
66 | 代开:在工程列表打开工程
67 | 打包:将当前工程编译为apk,默认使用debug签名
68 | 新建:新建一个工程
69 | 导出:将当前工程备份为alp文件
70 | 属性:编辑当前工程的属性,如 名称 权限等
71 |
72 | 代码
73 | 格式化:重新缩进当前文件使其更加便于阅读
74 | 导入分析:分析当前文件及引用文件需要导入的java类
75 | 查错:检查当前文件是否有语法错误
76 |
77 | 转到
78 | 搜索:搜索指定内容位置
79 | 转到:按行号跳转
80 | 导航:按函数跳转
81 |
82 | 插件:使用安装的插件
83 |
84 | 其他
85 | 布局助手:在编辑器打开aly文件时用于设计布局,目前功能尚不完善
86 | 日志:查看程序运行时的日志
87 | java浏览器:用于查看java类的方法
88 | 手册:离线版lua官方手册
89 | 联系作者:加入官方qq群与作者交流
90 | 捐赠:使用支付宝捐赠作者,使软件更好的发展下去》》
91 | 《《快速入门》》
92 | 《《AndroLua是一个使用Lua语法编写可以使用安卓API的轻型脚本编程工具,使用它可以快速编写安卓应用。
93 | 第一次打开程序默认创建new.lua,并添加以下代码
94 |
95 | require "import"
96 | import "android.widget."
97 | import "android.view."
98 |
99 | require "import" 是导入import模块,该模块集成了很多实用的函数,可以大幅度减轻写代码负担,详细函数说明参考程序帮助。
100 | import "android.widget.*" 是导入Java包。
101 | 这里导入了android的widget和view两个包。
102 |
103 | 导入包后使用类是很容易的,新建类实例和调用Lua的函数一样。
104 | 比如新建一个TextView
105 | tv=TextView(activity)
106 | activity表示当前活动的context。
107 | 同理新建按钮 btn=Button(activity)
108 |
109 | 给视图设置属性也非常简单
110 | btn.text="按钮"
111 | btn.backgroundColor=0xff0000ff
112 |
113 | 添加视图事件回调函数
114 | btn.onClick=function(v)
115 | print(v)
116 | end
117 | 函数参数v是视图本身。
118 |
119 | 安卓的视图需要添加到布局才能显示到活动,一般我们常用LinearLayout
120 | layout=LinearLayout(activity)
121 |
122 | 用addView添加视图
123 | layout.addView(btn)
124 |
125 | 最后调用activity的setContentView方法显示内容
126 | activity.setContentView(layout)
127 | 这里演示androlua基本用法,通常我们需要新建一个工程来开发,代码的用法是相同的,具体细节请详细阅读后面的内容。》》
128 | 《《与标准Lua5.3的不同》》
129 | 《《打开了部分兼容选项,module,unpack,bit32
130 | 添加string.gfind函数,用于递归返回匹配位置
131 | 增加tointeger函数,强制将数值转为整数
132 | 修改tonumber支持转换Java对象》》
133 | 《《参考链接》》
134 | 《《关于lua的语法和Android API请参考以下网页。
135 | Lua官网:
136 | http://www.lua.org
137 | Android 中文API:
138 | http://android.toolib.net/reference/packages.html》》
139 | 《《导入模块》》
140 | 《《require "import"
141 | 以导入import模块,简化写代码的难度。
142 | 目前程序还内置bmob,bson,canvas,cjson,crypt,ftp,gl,http,import,md5,smtp,socket,sensor,xml,zip,zlib等模块。
143 | 一般模块导入形式
144 | local http=require "http"
145 | 这样导入的是局部变量
146 | 导入import后也可以使用
147 | import "http"
148 | 的形式,导入为全局变量》》
149 | 《《导入包或类》》
150 | 《《在使用Java类之前需要导入相应的包或者类,
151 | 可以用包名.*的形式导入导入包
152 | import "android.widget.*"
153 | 或者用完整的类名导入类
154 | import "android.widget.Button"
155 | 导入内部类
156 | import "android.view.View_OnClickListener"
157 | 或者在导入类后直接使用内部类
158 | View.OnClickListene
159 | 包名和类名必须用引号包围。
160 | 导入的类为全局变量,你可以使用
161 | local Burton=import "android.widget.Button"
162 | 的形式保存为局部变量,以解决类名冲突问题。》》
163 | 《《创建布局与组件》》
164 | 《《安卓使用布局与视图管理和显示用户界面。
165 | 布局负责管理视图如何显示,如LinearLayout以线性排列视图,FrameLayout则要求自行指定停靠与位置。
166 | 视图则显示具体内容,如TextView可以向用户展示文字内容,Button可以响应用户点击事件。
167 |
168 | 创建一个线性布局
169 | layout=LinearLayout(activity)
170 | 创建一个按钮视图
171 | button=Button(activity)
172 | 将按钮添加到布局
173 | layout.addView(button)
174 | 将刚才的内容设置为活动内容视图
175 | activity.setContentView(layout)
176 |
177 | 注.activity是当前窗口的Context对象,如果你习惯也可以使用this
178 | button=Button(this)》》
179 | 《《使用方法》》
180 | 《《button.setText("按钮")
181 |
182 | getter/setter
183 | Java的getxxx方法没有参数与setxxx方法只有一个参数时可以简写,
184 | button.Text="按钮"
185 | x=button.Text》》
186 | 《《使用事件》》
187 | 《《创建事件处理函数
188 | function click(s)
189 | print("点击")
190 | end
191 | 把函数添加到事件接口
192 | listener=View.OnClickListener{onClick = click}
193 | 把接口注册到组件
194 | button.setOnClickListener(listener)
195 |
196 | 也可以使用匿名函数
197 | button.setOnClickListener(View.OnClickListener {onClick = function(s)
198 | print("点击")
199 | end
200 | })
201 |
202 | onxxx事件可以简写
203 | button.onClick=function(v)
204 | print(v)
205 | end》》
206 | 《《回调方法》》
207 | 《《在活动文件添加以下函数,这些函数可以在活动的特定状态执行。
208 | function main(...)
209 | --...:newActivity传递过来的参数。
210 | print("入口函数",...)
211 | end
212 |
213 | function onCreate()
214 | print("窗口创建")
215 | end
216 |
217 | function onStart()
218 | print("活动开始")
219 | end
220 |
221 | function onResume()
222 | print("返回程序")
223 | end
224 |
225 | function onPause()
226 | print("活动暂停")
227 | end
228 |
229 | function onStop()
230 | print("活动停止")
231 | end
232 |
233 | function onDestroy()
234 | print("程序已退出")
235 | end
236 |
237 | function onResult(name,...)
238 | --name:返回的活动名称
239 | --...:返回的参数
240 | print("返回活动",name,...)
241 | end
242 |
243 | function onCreateOptionsMenu(menu)
244 | --menu:选项菜单。
245 | menu.add("菜单")
246 | end
247 |
248 | function onOptionsItemSelected(item)
249 | --item:选中的菜单项
250 | print(item.Title)
251 | end
252 |
253 | function onConfigurationChanged(config)
254 | --config:配置信息
255 | print("屏幕方向关闭")
256 | end
257 |
258 | function onKeyDown(keycode,event)
259 | --keycode:键值
260 | --event:事件
261 | print("按键按下",keycode)
262 | end
263 |
264 | function onKeyUp(keycode,event)
265 | --keycode:键值
266 | --event:事件
267 | print("按键抬起",keycode)
268 | end
269 |
270 | function onKeyLongPress(keycode,event)
271 | --keycode:键值
272 | --event:事件
273 | print("按键长按",keycode)
274 | end
275 |
276 | function onTouchEvent(event)
277 | --event:事件
278 | print("触摸事件",event)
279 | end》》
280 | 《《按键与触控》》
281 | 《《function onKeyDown(code,event)
282 | print(code event)
283 | end
284 | function onTouchEvent(event)
285 | print(event)
286 | end
287 | 支持onKeyDown,onKeyUp,onKeyLongPress,onTouchEvent
288 | 函数必须返布尔值》》
289 | 《《使用数组》》
290 | 《《array=float{1,2,3}
291 | 或者
292 | array=int[10]
293 | a=array[0]
294 | array[0]=4》》
295 | 《《使用线程》》
296 | 《《需导入import模块,参看thread,timer与task函数说明。
297 | 线程中使用独立环境运行,不能使用外部变量与函数,需要使用参数和回调与外部交互。
298 | 任务
299 |
300 | task(str,args,callback)
301 |
302 | str 为任务执行代码,args 为参数,callback 为回调函数,任务返回值将传递到回调方法
303 | 线程
304 |
305 | t=thread(str,args)
306 |
307 | str 为线程中执行的代码,args 为初始传入参数
308 | 调用线程中方法
309 | call(t,fn,args)
310 | t 为线程,fn 为方法名称,args 为参数
311 | 设置线程变量
312 | set(t,fn,arg)
313 | t 为线程,fn 为变量名称,arg 为变量值
314 | 线程调用主线程中方法
315 | call(fn,args)
316 | fn 为方法名称,args 为参数
317 | 线程设置主线程变量
318 | set(fn,arg)
319 | fn 为变量名称,arg 为变量值
320 |
321 | 注. 参数类型为 字符串,数值,Java对象,布尔值与nil
322 | 线程要使用quit结束线程。
323 |
324 | t=timer(func,delay,period,args)
325 |
326 | func 为定时器执行的函数,delay 为定时器延时,period 为定时器间隔,args 为初始化参数
327 | t.Enable=false 暂停定时器
328 | t.Enable=true 启动定时器
329 | t.stop() 停止定时器
330 |
331 | 注意:定时器函数定义run函数时定时器重复执行run函数,否则重复执行构建时的func函数》》
332 | 《《使用布局表》》
333 | 《《使用布局表须导入android.view与android.widget包。
334 | require "import"
335 | import "android.widget.*"
336 | import "android.view.*"
337 | 布局表格式
338 | layout={
339 | 控件类名称,
340 | id=控件名称,
341 | 属性=值,
342 | {
343 | 子控件类名称,
344 | id=控件名称,
345 | 属性=值,
346 | }
347 | }
348 |
349 | 例如:
350 | layout={
351 | LinearLayout,--视图类名称
352 | id="linear",--视图ID,可以在loadlayout后直接使用
353 | orientation="vertical",--属性与值
354 | {
355 | TextView,--子视图类名称
356 | text="hello AndroLua+",--属性与值
357 | layout_width="fill"--布局属性
358 | },
359 | }
360 | 使用loadlayout函数解析布局表生成布局。
361 | activity.setContentView(loadlayout(layout))
362 | 也可以简化为:
363 | activity.setContentView(layout)
364 | 如果使用单独文件布局(比如有个layout.aly布局文件)也可以简写为:
365 | activity.setContentView("layout")
366 | 此时不用导入布局文件。
367 |
368 | 布局表支持大全部安卓控件属性,
369 | 与安卓XML布局文件的不同点:
370 | id表示在Lua中变量的名称,而不是安卓的可以findbyid的数字id。
371 | ImageView的src属性是当前目录图片名称或绝对文件路径图片或网络上的图片,
372 | layout_width与layout_height的值支持fill与wrap简写,
373 | onClick值为lua函数或java onClick接口或他们的全局变量名称,
374 | 背景background支持背景图片,背景色与LuaDrawable自绘制背景,背景图片参数为是当前目录图片名称或绝对文件路径图片或网络上的图片,颜色同backgroundColor,自绘制背景参数为绘制函数或绘制函数的全局变量名称,
375 | 控件背景色使用backgroundColor设置,值为"十六进制颜色值"。
376 | 尺寸单位支持 px,dp,sp,in,mm,%w,%h。
377 | 其他参考loadlayout与loadbitmap》》
378 | 《《2D绘图》》
379 | 《《require "import"
380 | import "android.app.*"
381 | import "android.os.*"
382 | import "android.widget.*"
383 | import "android.view.*"
384 | import "android.graphics.*"
385 | activity.setTitle('AndroLua')
386 |
387 | paint=Paint()
388 | paint.setARGB(100,0,250,0)
389 | paint.setStrokeWidth(20)
390 | paint.setTextSize(28)
391 |
392 | sureface = SurfaceView(activity);
393 | callback=SurfaceHolder_Callback{
394 | surfaceChanged=function(holder,format,width,height)
395 | end,
396 | surfaceCreated=function(holder)
397 | ca=holder.lockCanvas()
398 | if (ca~=nil) then
399 | ca.drawRGB(0,79,90);
400 | ca.drawRect(0,0,200,300,paint)
401 | end
402 | holder.unlockCanvasAndPost(ca)
403 | end,
404 | surfaceDestroyed=function(holder)
405 | end
406 | }
407 | holder=sureface.getHolder()
408 | holder.addCallback(callback)
409 | activity.setContentView(sureface)》》
410 | 《《Lua类型与Java类型》》
411 | 《《在大多数情况下androlua可以很好的处理Lua与Java类型之间的自动转换,但是Java的数值类型有多种(double,float,long,int,short,byte),而Lua只有number,在必要的情况下可以使用类型的强制转换。
412 | i=int(10)
413 | i就是一个Java的int类型数据
414 | d=double(10)
415 | d是一个Java的double类型
416 | 在调用Java方法时androlua可以自动将Lua的table转换成Java的array,Map或interface
417 | Map类型可以像使用Lua表一样简便。
418 | map=HashMap{a=1,b=2}
419 | print(map.a)
420 | map.a=3
421 | 取长度运算符#可以获取Java中array,List,Map,Set,String的长度。》》
422 |
423 | 《《canvas模块》》
424 | 《《require "import"
425 | import "canvas"
426 | import "android.app.*"
427 | import "android.os.*"
428 | import "android.widget.*"
429 | import "android.view.*"
430 | import "android.graphics.*"
431 | activity.setTitle('AndroLua')
432 |
433 | paint=Paint()
434 | paint.setARGB(100,0,250,0)
435 | paint.setStrokeWidth(20)
436 | paint.setTextSize(28)
437 |
438 | sureface = SurfaceView(activity);
439 | callback=SurfaceHolder_Callback{
440 | surfaceChanged=function(holder,format,width,height)
441 | end,
442 | surfaceCreated=function(holder)
443 | ca=canvas.lockCanvas(holder)
444 | if (ca~=nil) then
445 | ca:drawRGB(0,79,90)
446 | ca:drawRect(0,0,200,300,paint)
447 | end
448 | canvas.unlockCanvasAndPost(holder,ca)
449 | end,
450 | surfaceDestroyed=function(holder)
451 | end
452 | }
453 | holder=sureface.getHolder()
454 | holder.addCallback(callback)
455 | activity.setContentView(sureface)》》
456 | 《《OpenGL模块》》
457 | 《《require "import"
458 | import "gl"
459 | import "android.app.*"
460 | import "android.os.*"
461 | import "android.widget.*"
462 | import "android.view.*"
463 | import "android.opengl.*"
464 | activity.setTitle('AndroLua')
465 | --activity.setTheme( android.R.style.Theme_Holo_Light_NoActionBar_Fullscreen)
466 |
467 | mTriangleData ={
468 | 0.0, 0.6, 0.0,
469 | -0.6, 0.0, 0.0,
470 | 0.6, 0.0, 0.0,
471 | };
472 | mTriangleColor = {
473 | 1, 0, 0, 0,
474 | 0, 1, 0, 0,
475 | 0, 0, 1, 0,
476 | };
477 |
478 | sr=GLSurfaceView.Renderer{
479 | onSurfaceCreated=function(gl2, config)
480 | gl.glDisable(gl.GL_DITHER);
481 | gl.glHint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_FASTEST);
482 | gl.glClearColor(0, 0, 0, 0);
483 | gl.glShadeModel(gl.GL_SMOOTH);
484 | gl.glClearDepth(1.0)
485 | gl.glEnable(gl.GL_DEPTH_TEST);
486 | gl.glDepthFunc(gl.GL_LEQUAL);
487 | end,
488 | onDrawFrame=function(gl2, config)
489 | gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT);
490 | gl.glMatrixMode(gl.GL_MODELVIEW);
491 | gl.glLoadIdentity();
492 | gl.glRotate(0,1,1,1)
493 | gl.glTranslate(0, 0,0);
494 | gl.glEnableClientState(gl.GL_VERTEX_ARRAY);
495 | gl.glEnableClientState(gl.GL_COLOR_ARRAY);
496 | gl.glVertexPointer( mTriangleData,3);
497 | gl.glColorPointer(mTriangleColor,4);
498 | gl.glDrawArrays( gl.GL_TRIANGLE_STRIP , 0, 3);
499 | gl.glFinish();
500 | gl.glDisableClientState(gl.GL_VERTEX_ARRAY);
501 | gl.glDisableClientState(gl.GL_COLOR_ARRAY);
502 | end,
503 | onSurfaceChanged= function (gl2, w, h)
504 | gl.glViewport(0, 0, w, h);
505 | gl.glLoadIdentity();
506 | ratio = w / h;
507 | gl.glFrustum(-rautio, ratio, -1, 1, 1, 10);
508 | end
509 | }
510 |
511 | glSurefaceView = GLSurfaceView(activity);
512 | glSurefaceView.setRenderer(sr);
513 | activity.setContentView(glSurefaceView);》》
514 | 《《http 同步网络模块》》
515 | 《《body,cookie,code,headers=http.get(url [,cookie,ua,header])
516 | body,cookie,code,headers=http.post(url ,postdata [,cookie,ua,header])
517 | code,headers=http.download(url [,cookie,ua,ref,header])
518 | body,cookie,code,headers=http.upload(url ,datas ,files [,cookie,ua,header])
519 | 参数说明
520 | url 网址
521 | postdata post的字符串或字符串数据组表
522 | datas upload的字符串数据组表
523 | files upload的文件名数据表
524 | cookie 网页要求的cookie
525 | ua 浏览器识别
526 | ref 来源页网址
527 | header http请求头
528 |
529 | require "import"
530 | import "http"
531 |
532 | --get函数以get请求获取网页,参数为请求的网址与cookie
533 | body,cookie,code,headers=http.get("http://www.androlua.com")
534 |
535 | --post函数以post请求获取网页,通常用于提交表单,参数为请求的网址,要发送的内容与cookie
536 | body,cookie,code,headers=http.post("http://androlua.com/Login.Asp?Login=Login&Url=http://androlua.com/bbs/index.asp","name=用户名&pass=密码&ki=1")
537 |
538 | --download函数和get函数类似,用于下载文件,参数为请求的网址,保存文件的路径与cookie
539 | http.download("http://androlua.com","/sdcard/a.txt")
540 |
541 | --upload用于上传文件,参数是请求的网址,请求内容字符串部分,格式为以key=value形式的表,请求文件部分,格式为key=文件路径的表,最后一个参数为cookie
542 | http.upload("http://androlua.com",{title="标题",msg="内容"},{file1="/sdcard/1.txt",file2="/sdcard/2.txt"})》》
543 | 《《import模块》》
544 | 《《require "import"
545 | import "android.widget.*"
546 | import "android.view.*"
547 | layout={
548 | LinearLayout,
549 | orientation="vertical",
550 | {
551 | EditText,
552 | id="edit",
553 | layout_width="fill"
554 | },
555 | {
556 | Button,
557 | text="按钮",
558 | layout_width="fill",
559 | onClick="click"
560 | }
561 | }
562 |
563 | function click()
564 | Toast.makeText(activity, edit.getText().toString(), Toast.LENGTH_SHORT ).show()
565 | end
566 | activity.setContentView(loadlayout(layout))》》
567 | 《《Http 异步网络模块》》
568 | 《《获取内容 get函数
569 | Http.get(url,cookie,charset,header,callback)
570 | url 网络请求的链接网址
571 | cookie 使用的cookie,也就是服务器的身份识别信息
572 | charset 内容编码
573 | header 请求头
574 | callback 请求完成后执行的函数
575 |
576 | 除了url和callback其他参数都不是必须的
577 |
578 | 回调函数接受四个参数值分别是
579 | code 响应代码,2xx表示成功,4xx表示请求错误,5xx表示服务器错误,-1表示出错
580 | content 内容,如果code是-1,则为出错信息
581 | cookie 服务器返回的用户身份识别信息
582 | header 服务器返回的头信息
583 |
584 | 向服务器发送数据 post函数
585 | Http.post(url,data,cookie,charset,header,callback)
586 | 除了增加了一个data外,其他参数和get完全相同
587 | data 向服务器发送的数据
588 |
589 | 下载文件 download函数
590 | Http.download(url,path,cookie,header,callback)
591 | 参数中没有编码参数,其他同get,
592 | path 文件保存路径
593 |
594 | 需要特别注意一点,只支持同时有127个网络请求,否则会出错
595 |
596 |
597 | Http其实是对Http.HttpTask的封装,Http.HttpTask使用的更加通用和灵活的形式
598 | 参数格式如下
599 | Http.HttpTask( url, String method, cookie, charset, header, callback)
600 | 所有参数都是必选,没有则传入nil
601 |
602 | url 请求的网址
603 | method 请求方法可以是get,post,put,delete等
604 | cookie 身份验证信息
605 | charset 内容编码
606 | header 请求头
607 | callback 回调函数
608 |
609 | 该函数返回的是一个HttpTask对象,
610 | 需要调用execute方法才可以执行,
611 | t=Http.HttpTask(xxx)
612 | t.execute{data}
613 |
614 | 注意调用的括号是花括号,内容可以是字符串或者byte数组,
615 | 使用这个形式可以自己封装异步上传函数》》
616 | 《《bmob网络数据库》》
617 | 《《b=bmob(id,key)
618 | id 用户id,key 应用key。
619 |
620 | b:insert(key,data,callback)
621 | 新建数据表,key 表名称,data 数据,callback 回调函数。
622 |
623 | b:update(key,id,data,callback)
624 | 更新数据表,key 表名称id 数据id,data 数据,callback 回调函数。
625 |
626 | b:query(key,data,callback)
627 | 查询数据表,key 表名称,data 查询规则,callback 回调函数。
628 |
629 | b:increment(key,id,k,v,c)
630 | 原子计数,key 表名称,id 数据id,k 数据key,v 计数增加量。
631 |
632 | b:delete(key,id,callback)
633 | 删除数据,key 表名称,id 数据id,callback 回调函数。
634 |
635 | b:sign(user,pass,mail,callback)
636 | 注册用户,user 用户名,pass 密码,mail 电子邮箱,callback 回调函数。
637 |
638 | b:login(user or mail,pass,callback)
639 | 登录用户,user 用户名,pass 密码,mail 电子邮箱,callback 回调函数。
640 |
641 | b:upload(path,callback)
642 | 上传文件,path 文件路径,callback 回调函数。
643 |
644 | b:remove(url,callback)
645 | 删除文件,url 文件路径,callback 回调函数。
646 |
647 |
648 | 注:
649 | 1,查询规则支持表或者json格式,具体用法参考官方api
650 | 2,回调函数的第一个参数为状态码,-1 出错,其他状态码参考http状态码,第二个参数为返回内容。》》
651 | 《《LuaUtil 辅助库》》
652 | 《《copyDir(from,to)
653 | 复制文件或文件夹,from 源路径,to 目标路径。
654 |
655 | zip(from,dir,name)
656 | 压缩文件或文件夹,from 源路径,dir 目标文件夹,name zip文件名称。
657 |
658 | unZip(from,to)
659 | 解压文件,from zip文件路径,to 目标路径。
660 |
661 | getFileMD5(path)
662 | 获取文件MD5值, path 文件路径。
663 |
664 | getFileSha1(path)
665 | 获取文件Sha1值, path 文件路径。》》
666 | 《《LuaAdapter 适配器》》
667 | 《《构建方法
668 | adapter=LuaAdapter(activity,data,layout)
669 | 构建适配器,activity 当前活动,data 列表数据,layout 列表项目布局。
670 | data格式为{{id=value},{id=value}}格式的数组表。
671 |
672 | adapter.add(data)
673 | 添加数据,data 为列表项目数据,格式为{id=value}。
674 |
675 | adapter.insert(idx,{id=value})
676 | 插入数据,idx 为从0计数的插入位置,data 为列表项目数据,格式为{id=value}。
677 |
678 | adapter.remove(idx)
679 | 删除数据,idx 为从0计数的删除位置。
680 |
681 | adapter.clear()
682 | 清空数据。
683 |
684 | adapter.notifyDataSetChanged()
685 | 更新数据。
686 |
687 | 也可以使用table.insert/table.remove直接对data表操作,table库操作从1开始计数,改操作需要手动更新列表。
688 |
689 | 在使用LuaAdapter的ListView的onItemClick/onItemLongClick回调函数中,第三个参数为从0开始的项目序号,第四个参数为从1开始的项目序号。》》
690 | 《《关于AndroLua打包》》
691 | 《《新建工程或在脚本目录新建init.lua文件。
692 | 写入以下内容,即可将文件夹下所有lua文件打包,main.lua为程序人口。
693 | appname="demo"
694 | appver="1.0"
695 | packagename="com.androlua.demo"
696 | 目录下icon.png替换图标,welcome.png替换启动图。
697 | 打包使用debug签名。》》
698 | 《《部分函数参考》》
699 | 《《[a]表示参数a可选,(...)表示不定参数。函数调用在只有一个参数且参数为字符串或表时可以省略括号。
700 | AndroLua库函数在import模块,为便于使用都是全局变量。
701 | s 表示string类型,i 表示整数类型,n 表示浮点数或整数类型,t 表示表类型,b 表示布尔类型,o 表示Java对象类型,f为Lua函数。
702 | --表示注释。
703 |
704 | each(o)
705 | 参数:o 实现Iterable接口的Java对象
706 | 返回:用于Lua迭代的闭包
707 | 作用:Java集合迭代器
708 |
709 |
710 | enum(o)
711 | 参数:o 实现Enumeration接口的Java对象
712 | 返回:用于Lua迭代的闭包
713 | 作用:Java集合迭代器
714 |
715 | import(s)
716 | 参数:s 要载入的包或类的名称
717 | 返回:载入的类或模块
718 | 作用:载入包或类或Lua模块
719 | import "http" --载入http模块
720 | import "android.widget.*" --载入android.widget包
721 | import "android.widget.Button" --载入android.widget.Button类
722 | import "android.view.View$OnClickListener" --载入android.view.View.OnClickListener内部类
723 |
724 | loadlayout(t [,t2])
725 | 参数:t 要载入的布局表,t2 保存view的表
726 | 返回:布局最外层view
727 | 作用:载入布局表,生成view
728 | layout={
729 | LinearLayout,
730 | layout_width="fill",
731 | {
732 | TextView,
733 | text="Androlua",
734 | id="tv"
735 | }
736 | }
737 | main={}
738 | activity.setContentView(loadlayout(layout,main))
739 | print(main.tv.getText())
740 |
741 | loadbitmap(s)
742 | 参数:s 要载入图片的地址,支持相对地址,绝对地址与网址
743 | 返回:bitmap对象
744 | 作用:载入图片
745 | 注意:载入网络图片需要在线程中进行
746 |
747 | task(s [,...], f)
748 | 参数:s 任务中运行的代码或函数,... 任务传入参数,f 回调函数
749 | 返回:无返回值
750 | 作用:在异步线程运行Lua代码,执行完毕在主线程调用回调函数
751 | 注意:参数类型包括 布尔,数值,字符串,Java对象,不允许Lua对象
752 | function func(a,b)
753 | require "import"
754 | print(a,b)
755 | return a+b
756 | end
757 | task(func,1,2,print)
758 |
759 | thread(s[,...])
760 | 参数:s 线程中运行的lua代码或脚本的相对路径(不加扩展名)或函数,... 线程初始化参数
761 | 返回:返回线程对象
762 | 作用:开启一个线程运行Lua代码
763 | 注意:线程需要调用quit方法结束线程
764 | func=[[
765 | a,b=...
766 | function add()
767 | call("print",a+b)
768 | end
769 | ]]
770 | t=thread(func,1,2)
771 | t.add()
772 |
773 | timer(s,i1,i2[,...])
774 | 参数:s 定时器运行的代码或函数,i1 前延时,i2 定时器间隔,... 定时器初始化参数
775 | 返回:定时器对象
776 | 作用:创建定时器重复执行函数
777 | function f(a)
778 | function run()
779 | print(a)
780 | a=a+1
781 | end
782 | end
783 |
784 | t=timer(f,0,1000,1)
785 | t.Enabled=false--暂停定时器
786 | t.Enabled=true--重新定时器
787 | t.stop()--停止定时器
788 |
789 | luajava.bindClass(s)
790 | 参数:s class的完整名称,支持基本类型
791 | 返回:Java class对象
792 | 作用:载入Java class
793 | Button=luajava.bindClass("android.widget.Button")
794 | int=luajava.bindClass("int")
795 |
796 | luajava.createProxy(s,t)
797 | 参数:s 接口的完整名称,t 接口函数表
798 | 返回:Java接口对象
799 | 作用:创建Java接口
800 | onclick=luajava.createProxy("android.view.View$OnClickListener",{onClick=function(v)print(v)end})
801 |
802 | luajava.createArray(s,t)
803 | 参数:s 类的完整名称,支持基本类型,t 要转化为Java数组的表
804 | 返回:创建的Java数组对象
805 | 作用:创建Java数组
806 | arr=luajava.createArray("int",{1,2,3,4})
807 |
808 | luajava.newInstance(s [,...])
809 | 参数:s 类的完整名称,... 构建方法的参数
810 | 作用:创建Java类的实例
811 | b=luajava.newInstance("android.widget.Button",activity)
812 |
813 | luajava.new(o[,...])
814 | 参数:o Java类对象,... 参数
815 | 返回:类的实例或数组对象或接口对象
816 | 作用:创建一个类实例或数组对象或接口对象
817 | 注意:当只有一个参数且为表类型时,如果类对象为interface创建接口,为class创建数组,参数为其他情况创建实例
818 | b=luajava.new(Button,activity)
819 | onclick=luajava.new(OnClickListener,{onClick=function(v)print(v)end})
820 | arr=luajava.new(int,{1,2,3})
821 | (示例中假设已载入相关类)
822 |
823 | luajava.coding(s [,s2 [, s3]])
824 | 参数:s 要转换编码的Lua字符串,s2 字符串的原始编码,s3 字符串的目标编码
825 | 返回:转码后的Lua字符串
826 | 作用:转换字符串编码
827 | 注意:默认进行GBK转UTF8
828 |
829 | luajava.clear(o)
830 | 参数:o Java对象
831 | 返回:无
832 | 作用:销毁Java对象
833 | 注意:仅用于销毁临时对象
834 |
835 | luajava.astable(o)
836 | 参数:o Java对象
837 | 返回:Lua表
838 | 作用:转换Java的Array List或Map为Lua表
839 |
840 | luajava.tostring(o)
841 | 参数:o Java对象
842 | 返回:Lua字符串
843 | 作用:相当于 o.toString()》》
844 | 《《activity部分API参考》》
845 | 《《setContentView(layout, env)
846 | 设置布局表layout为当前activity的主视图,env是保存视图ID的表,默认是_G
847 | getLuaDir()
848 | 返回脚本当前目录
849 | getLuaDir(name)
850 | 返回脚本当前目录的子目录
851 | getLuaExtDir()
852 | 返回Androlua在SD的工作目录
853 | getLuaExtDir(name)
854 | 返回Androlua在SD的工作目录的子目录
855 | getWidth()
856 | 返回屏幕宽度
857 | getHeight()
858 | 返回屏幕高度,不包括状态栏与导航栏
859 | loadDex(path)
860 | 加载当前目录dex或jar,返回DexClassLoader
861 | loadLib(path)
862 | 加载当前目录c模块,返回载入后模块的返回值(通常是包含模块函数的包)
863 | registerReceiver(filter)
864 | 注册一个广播接收者,当再次调用该方法时将移除上次注册的过滤器
865 | newActivity(req, path, enterAnim, exitAnim, arg)
866 | 打开一个新activity,运行路径为path的Lua文件,其他参数为可选,arg为表,接受脚本为变长参数
867 | result{...}
868 | 向来源activity返回数据,在源activity的onResult回调
869 | newTask(func[, update], callback)
870 | 新建一个Task异步任务,在线程中执行func函数,其他两个参数可选,执行结束回调callback,在任务调用update函数时在UI线程回调该函数
871 | 新建的Task在调用execute{}时通过表传入参数,在func以unpack形式接收,执行func可以返回多个值
872 | newThread(func, arg)
873 | 新建一个线程,在线程中运行func函数,可以以表的形式传入arg,在func以unpack形式接收
874 | 新建的线程调用start()方法运行,线程为含有loop线程,在当前activity结束后自动结束loop
875 | newTimer(func, arg)
876 | 新建一个定时器,在线程中运行func函数,可以以表的形式传入arg,在func以unpack形式接收
877 | 调用定时器的start(delay, period)开始定时器,stop()停止定时器,Enabled暂停恢复定时器,Period属性改变定时器间隔》》
878 | 《《布局表字符串常量》》
879 | 《《布局表支持属性字符串常量
880 | -- android:drawingCacheQuality
881 | auto=0,
882 | low=1,
883 | high=2,
884 |
885 | -- android:importantForAccessibility
886 | auto=0,
887 | yes=1,
888 | no=2,
889 |
890 | -- android:layerType
891 | none=0,
892 | software=1,
893 | hardware=2,
894 |
895 | -- android:layoutDirection
896 | ltr=0,
897 | rtl=1,
898 | inherit=2,
899 | locale=3,
900 |
901 | -- android:scrollbarStyle
902 | insideOverlay=0x0,
903 | insideInset=0x01000000,
904 | outsideOverlay=0x02000000,
905 | outsideInset=0x03000000,
906 |
907 | -- android:visibility
908 | visible=0,
909 | invisible=1,
910 | gone=2,
911 |
912 | wrap_content=-2,
913 | fill_parent=-1,
914 | match_parent=-1,
915 | wrap=-2,
916 | fill=-1,
917 | match=-1,
918 |
919 | -- android:orientation
920 | vertical=1,
921 | horizontal= 0,
922 |
923 | -- android:gravity
924 | axis_clip = 8,
925 | axis_pull_after = 4,
926 | axis_pull_before = 2,
927 | axis_specified = 1,
928 | axis_x_shift = 0,
929 | axis_y_shift = 4,
930 | bottom = 80,
931 | center = 17,
932 | center_horizontal = 1,
933 | center_vertical = 16,
934 | clip_horizontal = 8,
935 | clip_vertical = 128,
936 | display_clip_horizontal = 16777216,
937 | display_clip_vertical = 268435456,
938 | --fill = 119,
939 | fill_horizontal = 7,
940 | fill_vertical = 112,
941 | horizontal_gravity_mask = 7,
942 | left = 3,
943 | no_gravity = 0,
944 | relative_horizontal_gravity_mask = 8388615,
945 | relative_layout_direction = 8388608,
946 | right = 5,
947 | start = 8388611,
948 | top = 48,
949 | vertical_gravity_mask = 112,
950 | end = 8388613,
951 |
952 | -- android:textAlignment
953 | inherit=0,
954 | gravity=1,
955 | textStart=2,
956 | textEnd=3,
957 | textCenter=4,
958 | viewStart=5,
959 | viewEnd=6,
960 |
961 | -- android:inputType
962 | none=0x00000000,
963 | text=0x00000001,
964 | textCapCharacters=0x00001001,
965 | textCapWords=0x00002001,
966 | textCapSentences=0x00004001,
967 | textAutoCorrect=0x00008001,
968 | textAutoComplete=0x00010001,
969 | textMultiLine=0x00020001,
970 | textImeMultiLine=0x00040001,
971 | textNoSuggestions=0x00080001,
972 | textUri=0x00000011,
973 | textEmailAddress=0x00000021,
974 | textEmailSubject=0x00000031,
975 | textShortMessage=0x00000041,
976 | textLongMessage=0x00000051,
977 | textPersonName=0x00000061,
978 | textPostalAddress=0x00000071,
979 | textPassword=0x00000081,
980 | textVisiblePassword=0x00000091,
981 | textWebEditText=0x000000a1,
982 | textFilter=0x000000b1,
983 | textPhonetic=0x000000c1,
984 | textWebEmailAddress=0x000000d1,
985 | textWebPassword=0x000000e1,
986 | number=0x00000002,
987 | numberSigned=0x00001002,
988 | numberDecimal=0x00002002,
989 | numberPassword=0x00000012,
990 | phone=0x00000003,
991 | datetime=0x00000004,
992 | date=0x00000014,
993 | time=0x00000024,
994 |
995 | --android:ellipsize
996 | end
997 | start
998 | middle
999 | marquee
1000 |
1001 | 相对布局rule
1002 | layout_above=2,
1003 | layout_alignBaseline=4,
1004 | layout_alignBottom=8,
1005 | layout_alignEnd=19,
1006 | layout_alignLeft=5,
1007 | layout_alignParentBottom=12,
1008 | layout_alignParentEnd=21,
1009 | layout_alignParentLeft=9,
1010 | layout_alignParentRight=11,
1011 | layout_alignParentStart=20,
1012 | layout_alignParentTop=10,
1013 | layout_alignRight=7,
1014 | layout_alignStart=18,
1015 | layout_alignTop=6,
1016 | layout_alignWithParentIfMissing=0,
1017 | layout_below=3,
1018 | layout_centerHorizontal=14,
1019 | layout_centerInParent=13,
1020 | layout_centerVertical=15,
1021 | layout_toEndOf=17,
1022 | layout_toLeftOf=0,
1023 | layout_toRightOf=1,
1024 | layout_toStartOf=16
1025 |
1026 |
1027 |
1028 | 尺寸单位
1029 | px=0,
1030 | dp=1,
1031 | sp=2,
1032 | pt=3,
1033 | in=4,
1034 | mm=5》》
--------------------------------------------------------------------------------
/app/src/main/assets/Intent类.txt:
--------------------------------------------------------------------------------
1 | 《《Intent类介绍》》
2 | 《《Intent(意图)主要是解决Android应用的各项组件之间的通讯。
3 | Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述.
4 | Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。
5 |
6 | 因此,Intent在这里起着一个媒体中介的作用
7 | 专门提供组件互相调用的相关信息
8 | 实现调用者与被调用者之间的解耦。
9 |
10 | 例如,在一个联系人维护的应用中,当我们在一个联系人列表屏幕(假设对应的Activity为listActivity)上
11 | 点击某个联系人后,希望能够跳出此联系人的详细信息屏幕(假设对应的Activity为detailActivity)
12 | 为了实现这个目的,listActivity需要构造一个 Intent
13 | 这个Intent用于告诉系统,我们要做“查看”动作,此动作对应的查看对象是“某联系人”
14 | 然后调用startActivity (Intent intent),将构造的Intent传入
15 |
16 | 系统会根据此Intent中的描述到ManiFest中找到满足此Intent要求的Activity,系统会调用找到的 Activity,即为detailActivity,最终传入Intent,detailActivity则会根据此Intent中的描述,执行相应的操作。》》
17 |
18 |
19 | 《《调用浏览器搜索关键字》》
20 | 《《import "android.content.Intent"
21 | import "android.app.SearchManager"
22 | intent = Intent()
23 | intent.setAction(Intent.ACTION_WEB_SEARCH)
24 | intent.putExtra(SearchManager.QUERY,"Alua开发手册")
25 | activity.startActivity(intent)》》
26 |
27 |
28 | 《《调用浏览器打开网页》》
29 | 《《import "android.content.Intent"
30 | import "android.net.Uri"
31 | url="http://www.androlua.cn"
32 | viewIntent = Intent("android.intent.action.VIEW",Uri.parse(url))
33 | activity.startActivity(viewIntent)》》
34 |
35 |
36 |
37 |
38 | 《《打开其它程序》》
39 | 《《packageName=程序包名
40 | import "android.content.Intent"
41 | import "android.content.pm.PackageManager"
42 | manager = activity.getPackageManager()
43 | open = manager.getLaunchIntentForPackage(packageName)
44 | this.startActivity(open)》》
45 |
46 |
47 | 《《安装其它程序》》
48 | 《《import "android.content.Intent"
49 | import "android.net.Uri"
50 | intent = Intent(Intent.ACTION_VIEW)
51 | 安装包路径="/sdcard/a.apk"
52 | intent.setDataAndType(Uri.parse("file://"..安装包路径), "application/vnd.android.package-archive")
53 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
54 | activity.startActivity(intent)》》
55 |
56 |
57 | 《《卸载其它程序》》
58 | 《《import "android.net.Uri"
59 | import "android.content.Intent"
60 | 包名="com.huluxia.gametools"
61 | uri = Uri.parse("package:"..包名)
62 | intent = Intent(Intent.ACTION_DELETE,uri)
63 | activity.startActivity(intent)》》
64 |
65 | 《《播放Mp4》》
66 | 《《import "android.content.Intent"
67 | import "android.net.Uri"
68 | intent = Intent(Intent.ACTION_VIEW)
69 | uri = Uri.parse("file:///sdcard/a.mp4")
70 | intent.setDataAndType(uri, "video/mp4")
71 | activity.startActivity(intent)》》
72 |
73 | 《《播放Mp3》》
74 | 《《import "android.content.Intent"
75 | import "android.net.Uri"
76 | intent = Intent(Intent.ACTION_VIEW)
77 | uri = Uri.parse("file:///sdcard/song.mp3")
78 | intent.setDataAndType(uri, "audio/mp3")
79 | this.startActivity(intent)》》
80 |
81 | 《《搜索应用》》
82 | 《《import "android.content.Intent"
83 | import "android.net.Uri"
84 | intent = Intent("android.intent.action.VIEW")
85 | intent .setData(Uri.parse( "market://details?id="..activity.getPackageName()))
86 | this.startActivity(intent)》》
87 |
88 |
89 | 《《调用系统设置》》
90 | 《《import "android.content.Intent"
91 | import "android.provider.Settings"
92 | intent = Intent(android.provider.Settings.ACTION_SETTINGS)
93 | this.startActivity(intent)
94 |
95 | 字段列表:
96 | ACTION_SETTINGS 系统设置
97 | CTION_APN_SETTINGS APN设置
98 | ACTION_LOCATION_SOURCE_SETTINGS 位置和访问信息
99 | ACTION_WIRELESS_SETTINGS 网络设置
100 | ACTION_AIRPLANE_MODE_SETTINGS 无线和网络热点设置
101 | ACTION_SECURITY_SETTINGS 位置和安全设置
102 | ACTION_WIFI_SETTINGS 无线网WIFI设置
103 | ACTION_WIFI_IP_SETTINGS 无线网IP设置
104 | ACTION_BLUETOOTH_SETTINGS 蓝牙设置
105 | ACTION_DATE_SETTINGS 时间和日期设置
106 | ACTION_SOUND_SETTINGS 声音设置
107 | ACTION_DISPLAY_SETTINGS 显示设置——字体大小等
108 | ACTION_LOCALE_SETTINGS 语言设置
109 | ACTION_INPUT_METHOD_SETTINGS 输入法设置
110 | ACTION_USER_DICTIONARY_SETTINGS 用户词典
111 | ACTION_APPLICATION_SETTINGS 应用程序设置
112 | ACTION_APPLICATION_DEVELOPMENT_SETTINGS 应用程序设置
113 | ACTION_QUICK_LAUNCH_SETTINGS 快速启动设置
114 | ACTION_MANAGE_APPLICATIONS_SETTINGS 已下载(安装)软件列表
115 | ACTION_SYNC_SETTINGS 应用程序数据同步设置
116 | ACTION_NETWORK_OPERATOR_SETTINGS 可用网络搜索
117 | ACTION_DATA_ROAMING_SETTINGS 移动网络设置
118 | ACTION_INTERNAL_STORAGE_SETTINGS 手机存储设置
119 | 》》
120 |
121 |
122 | 《《调用系统打开文件》》
123 | 《《function OpenFile(path)
124 | import "android.webkit.MimeTypeMap"
125 | import "android.content.Intent"
126 | import "android.net.Uri"
127 | import "java.io.File"
128 | FileName=tostring(File(path).Name)
129 | ExtensionName=FileName:match("%.(.+)")
130 | Mime=MimeTypeMap.getSingleton().getMimeTypeFromExtension(ExtensionName)
131 | if Mime then
132 | intent = Intent()
133 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
134 | intent.setAction(Intent.ACTION_VIEW);
135 | intent.setDataAndType(Uri.fromFile(File(path)), Mime);
136 | activity.startActivity(intent)
137 | return true
138 | else
139 | return false
140 | end
141 | end
142 | OpenFile(文件路径)》》
143 |
144 |
145 | 《《调用图库选择图片》》
146 | 《《import "android.content.Intent"
147 | local intent= Intent(Intent.ACTION_PICK)
148 | intent.setType("image/*")
149 | this.startActivityForResult(intent, 1)
150 | -------
151 |
152 | --回调
153 | function onActivityResult(requestCode,resultCode,intent)
154 | if intent then
155 | local cursor =this.getContentResolver ().query(intent.getData(), nil, nil, nil, nil)
156 | cursor.moveToFirst()
157 | import "android.provider.MediaStore"
158 | local idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)
159 | fileSrc = cursor.getString(idx)
160 | bit=nil
161 | --fileSrc回调路径路径
162 | import "android.graphics.BitmapFactory"
163 | bit =BitmapFactory.decodeFile(fileSrc)
164 | -- iv.setImageBitmap(bit)
165 | end
166 | end--nirenr》》
167 |
168 | 《《调用文件管理器选择文件》》
169 | 《《function ChooseFile()
170 | import "android.content.Intent"
171 | import "android.net.Uri"
172 | import "java.net.URLDecoder"
173 | import "java.io.File"
174 | intent = Intent(Intent.ACTION_GET_CONTENT)
175 | intent.setType("*/");
176 | intent.addCategory(Intent.CATEGORY_OPENABLE)
177 | activity.startActivityForResult(intent,1);
178 | function onActivityResult(requestCode,resultCode,data)
179 | if resultCode == Activity.RESULT_OK then
180 | local str = data.getData().toString()
181 | local decodeStr = URLDecoder.decode(str,"UTF-8")
182 | print(decodeStr)
183 | end
184 | end
185 | end
186 |
187 | ChooseFile()》》
188 |
189 |
190 | 《《分享文件》》
191 | 《《function Sharing(path)
192 | import "android.webkit.MimeTypeMap"
193 | import "android.content.Intent"
194 | import "android.net.Uri"
195 | import "java.io.File"
196 | FileName=tostring(File(path).Name)
197 | ExtensionName=FileName:match("%.(.+)")
198 | Mime=MimeTypeMap.getSingleton().getMimeTypeFromExtension(ExtensionName)
199 | intent = Intent()
200 | intent.setAction(Intent.ACTION_SEND)
201 | intent.setType(Mime)
202 | file = File(path)
203 | uri = Uri.fromFile(file)
204 | intent.putExtra(Intent.EXTRA_STREAM,uri)
205 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
206 | activity.startActivity(Intent.createChooser(intent, "分享到:"))
207 | end
208 |
209 | Sharing(文件路径)》》
210 |
211 |
212 |
213 | 《《发送短信》》
214 | 《《import "android.net.Uri"
215 | import "android.content.Intent"
216 | uri = Uri.parse("smsto:10010")
217 | intent = Intent(Intent.ACTION_SENDTO, uri)
218 | intent.putExtra("sms_body","cxll")
219 | intent.setAction("android.intent.action.VIEW")
220 | activity.startActivity(intent)》》
221 |
222 | 《《发送彩信》》
223 | 《《import "android.net.Uri"
224 | import "android.content.Intent"
225 | uri=Uri.parse("file:///sdcard/a.png") --图片路径
226 | intent= Intent();
227 | intent.setAction(Intent.ACTION_SEND);
228 | intent.putExtra("address",mobile) --邮件地址
229 | intent.putExtra("sms_body",content) --邮件内容
230 | intent.putExtra(Intent.EXTRA_STREAM,uri)
231 | intent.setType("image/png") --设置类型
232 | this.startActivity(intent)》》
233 |
234 | 《《拨打电话》》
235 | 《《import "android.net.Uri"
236 | import "android.content.Intent"
237 | uri = Uri.parse("tel:10010")
238 | intent = Intent(Intent.ACTION_CALL, uri)
239 | intent.setAction("android.intent.action.VIEW")
240 | activity.startActivity(intent)》》
241 |
--------------------------------------------------------------------------------
/app/src/main/assets/LuaManual/glossary.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Lua 5.3 术语中英对照表
5 |
6 |
7 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Lua 5.3 术语中英对照表
21 |
22 |
23 |
24 | 译者在翻译时,使用了一些尚未统一的中文术语译词,统一罗列如下:
25 |
26 |
27 | 元表 | metatable
28 | |
元方法 | metamethod
29 | |
弱表 | weak table
30 | |
协程 | coroutine
31 | |
闭包 | closure
32 | |
注册表 | registry
33 | |
让出 | yield
34 | |
表 | table
35 | |
用户数据 | userdata
36 | |
延续点 | continuation
37 | |
宿主 | host
38 | |
一等公民 | first-class
39 | |
语法糖 | syntactic sugar
40 | |
序列 | sequence
41 | |
异构 | heterogeneous
42 | |
终结器 | finalizer
43 | |
暂时表 | ephemeron table
44 | |
符记 | token
45 | |
字面串 | literal string
46 | |
代码块 | chunk
47 | |
标签 | label
48 | |
实例化 | instantiated
49 | |
上值 | upvalue
50 | |
51 |
52 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/assets/LuaManual/logo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HK-SHAO/ALuaGuide/26822e92d4a0f150d0355af883542ed33fea5f6d/app/src/main/assets/LuaManual/logo.gif
--------------------------------------------------------------------------------
/app/src/main/assets/基础代码.txt:
--------------------------------------------------------------------------------
1 | 《《打印》》
2 | 《《print"Hello World!"
3 | print("Hello World")》》
4 |
5 |
6 |
7 |
8 | 《《注释》》
9 | 《《单行注释 --
10 | 多行注释 --[[]]》》
11 |
12 |
13 |
14 | 《《字符串》》
15 | 《《a="String"
16 | a=[[String]]
17 | a=[===[String]===]》》
18 |
19 |
20 |
21 |
22 |
23 | 《《赋值》》
24 | 《《a="Hello World"
25 |
26 | --lua支持多重赋值
27 | a,b="String a","String b"
28 |
29 | --交换值
30 | a,b="String a","String b"
31 | a,b=b,a》》
32 |
33 |
34 |
35 |
36 | 《《类型简介》》
37 | 《《Lua 存在的数据类型包括:
38 | 1.nil
39 | 此类型只有一个值 nil。用于表示“空”值。全局变量默认为 nil,删除一个已经赋值的全局变量只需要将其赋值为 nil(对比 JavaScript,赋值 null 并不能完全删除对象的属性,属性还存在,值为 null)
40 |
41 | 2.boolean
42 | 此类型有两个值 true 和 false。在 Lua 中,false 和 nil 都表示条件假,其他值都表示条件真(区别于 C/C++ 等语言的是,0 是真)
43 |
44 |
45 | 3.number
46 | 双精浮点数(IEEE 754 标准),Lua 没有整数类型
47 |
48 | 4.string
49 | 你可以保存任意的二进制数据到字符串中(包括 0)。字符串中的字符是不可以改变的(需要改变时,你只能创建一个新的字符串)。获取字符串的长度,可以使用 # 操作符(长度操作符)。例如:print(#”hello”)。字符串可以使用单引号,也可以使用双引号包裹,对于多行的字符串还可以使用 [[ 和 ]] 包裹。字符串中可以使用转义字符,例如 \n \r 等。使用 [[ 和 ]] 包裹的字符串中的转义字符不会被转义
50 |
51 | 5.userdata
52 | 用于保存任意的 C 数据。userdata 只能支持赋值操作和比较测试
53 |
54 | 6.function
55 | 函数是第一类值(first-class value),我们能够像使用其他变量一样的使用函数(函数能够保存在变量中,可以作为参数传递给函数)
56 |
57 | 7.thread
58 | 区别于我们常常说的系统级线程
59 |
60 | 8.table
61 | 被实现为关联数组(associative arrays),可以通过任何值来进行索引(nil 除外)。和全局变量一样,table 中未赋值的域为 nil,删除一个域只需要将其赋值为 nil(实际上,全局变量就是被放置在一个 table 中)
62 |
63 |
64 |
65 | type 函数用于返回值的类型:
66 | print(type("Hello World")) --> string
67 | print(type(10.4*3)) --> number
68 | print(type(print)) --> function
69 | print(type(type(X))) --> string》》
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | 《《Table(数组)》》
80 | 《《table是lua唯一的数据结构。
81 | table是lua中最重要的数据类型。
82 | table类似于 python 中的字典。
83 | table只能通过构造式来创建。其他语言提供的其他数据结构如array、list等等,lua都是通过table来实现的。
84 | table非常实用,可以用在不同的情景下。最常用的方式就是把table当成其他语言的数组。
85 |
86 | 实例1:
87 | mytable = {}
88 | for index = 1, 100 do
89 | mytable[index] = math.random(1,1000)
90 | end
91 |
92 | 说明:
93 | 1.数组不必事先定义大小,可动态增长。
94 | 2.创建包含100个元素的table,每个元素随机赋1-1000之间的值。
95 | 3.可以通过mytable[x]访问任意元素,x表示索引。
96 | 4.索引从1开始。
97 |
98 | 实例2:
99 | tab = { a = 10, b = 20, c = 30, d = 'www.jb51.net' }
100 | print(tab["a"])
101 |
102 | 说明:
103 | 1.table 中的每项要求是 key = value 的形式。
104 | 2.key 只能是字符串, 这里的 a, b, c, d 都是字符串,但是不能加上引号。
105 | 3.通过 key 来访问 table 的值,这时候, a 必须加上引号。
106 |
107 | 实例3:
108 | tab = { 10, s = 'abc', 11, 12, 13 }
109 | print(tab[1]) = 10
110 | print(tab[2]) = 11
111 | print(tab[3]) = 12
112 | print(tab[4]) = 13
113 | 说明:
114 | 1.数标从1开始。
115 | 2.省略key,会自动以1开始编号,并跳过设置过的key。》》
116 |
117 |
118 |
119 | 《《比较操作符》》
120 | 《《--Lua 支持下列比较操作符:
121 |
122 | ==: 等于
123 | ~=: 不等于
124 | <: 小于
125 | >: 大于
126 | <=: 小于等于
127 | >=: 大于等于
128 | 这些操作的结果不是 false就是 true。》》
129 |
130 |
131 |
132 |
133 | 《《For循环》》
134 | 《《--给定条件进行循环
135 |
136 | --输出从1到10
137 | for i=1,10 do
138 | print(i)
139 | end
140 |
141 |
142 | --输出从10到1
143 | for i=10,1,-1 do
144 | print(i)
145 | end
146 |
147 | --打印数组a中所有的值
148 | a={"a","b","c","d"}
149 | for index,content in pairs(a) do
150 | print(content)
151 | end》》
152 |
153 |
154 | 《《While循环》》
155 | 《《--只要条件为真便会一直循环下去
156 |
157 | --输出1到10
158 | a=0
159 | while a~=10 do
160 | a=a+1
161 | print(a)
162 | end
163 |
164 | --输出10到1
165 | a=11
166 | while a~=1 do
167 | a=a-1
168 | print(a)
169 | end
170 |
171 | --打印数组a中的所有值
172 | shuzu={"a","b","c","d"}
173 | a=0
174 | while a~=#shuzu do
175 | a=a+1
176 | print(shuzu[a])
177 | end》》
178 |
179 |
180 |
181 | 《《if(判断语句)》》
182 | 《《--判断值是否为真
183 | a=true
184 | if a then
185 | print("真")
186 | else
187 | print("假")
188 | end
189 |
190 | --比较值是否相同
191 | a=true
192 | b=false
193 | if a==b then
194 | print("真")
195 | else
196 | print("假")
197 | end》》
198 |
199 |
200 | 《《function(函数)》》
201 | 《《函数有两个用途
202 | 1.完成指定功能,函数作为调用语句使用
203 | 2.计算并返回值,函数作为赋值语句的表达式使用
204 |
205 |
206 | 实例1:
207 | function 读取文件(路径)
208 | 文件内容=io.open(路径):read("*a")
209 | return 文件内容--return用来返回值
210 | end
211 |
212 |
213 |
214 | 实例2:
215 | require "import"
216 | import "android.widget.EditText"
217 | import "android.widget.LinearLayout"
218 | function 编辑框()
219 | return EditText(activity)
220 | end
221 | layout={
222 | LinearLayout;
223 | id="父布局",
224 | {编辑框,
225 | id="edit",
226 | text="文本",
227 | },
228 | };
229 | activity.setContentView(loadlayout(layout))
230 | --把这段代码放到调试里面去测试》》
231 |
232 |
233 | 《《基础代码》》
234 | 《《activity.setTitle('Title')--设置窗口标题
235 | activity.setContentView(loadlayout(layout))--设置窗口视图
236 | activity.setTheme(android.R.style.Theme_DeviceDefault_Light)--设置主题
237 | activity.getWidth()--获取屏幕宽
238 | activity.getHeight()--获取屏幕高
239 | activity.newActivity("main")--跳转页面
240 | activity.finish()--关闭当前页面
241 | activity.recreate()--重构activity
242 | os.exit()--结束程序
243 | tostring()--转换字符串
244 | tonumber()--转换数字
245 | tointeger()--转换整数
246 | --线程
247 | --thread
248 | thread(function()print"线程"end)
249 | --task
250 | task(function()print"线程"end)》》
--------------------------------------------------------------------------------
/app/src/main/assets/实用代码.txt:
--------------------------------------------------------------------------------
1 | 《《获取设备标识码》》
2 | 《《import "android.provider.Settings$Secure"
3 | android_id = Secure.getString(activity.getContentResolver(), Secure.ANDROID_ID)》》
4 |
5 | 《《获取IMEI》》
6 | 《《import "android.content.Context"
7 | imei=activity.getSystemService(Context.TELEPHONY_SERVICE).getDeviceId()》》
8 |
9 | 《《控件背景渐变动画》》
10 | 《《view=控件id
11 | color1 = 0xffFF8080;
12 | color2 = 0xff8080FF;
13 | color3 = 0xff80ffff;
14 | color4 = 0xff80ff80;
15 | import "android.animation.ObjectAnimator"
16 | import "android.animation.ArgbEvaluator"
17 | import "android.animation.ValueAnimator"
18 | import "android.graphics.Color"
19 | colorAnim = ObjectAnimator.ofInt(view,"backgroundColor",{color1, color2, color3,color4})
20 | colorAnim.setDuration(3000)
21 | colorAnim.setEvaluator(ArgbEvaluator())
22 | colorAnim.setRepeatCount(ValueAnimator.INFINITE)
23 | colorAnim.setRepeatMode(ValueAnimator.REVERSE)
24 | colorAnim.start()》》
25 |
26 |
27 | 《《精准获取屏幕尺寸》》
28 | 《《function getScreenPhysicalSize(ctx)
29 | import "android.util.DisplayMetrics"
30 | dm = DisplayMetrics();
31 | ctx.getWindowManager().getDefaultDisplay().getMetrics(dm);
32 | diagonalPixels = Math.sqrt(Math.pow(dm.widthPixels, 2) + Math.pow(dm.heightPixels, 2));
33 | return diagonalPixels / (160 * dm.density);
34 | end
35 | print(getScreenPhysicalSize(activity))》》
36 |
37 |
38 |
39 | 《《发送邮件》》
40 | 《《import "android.content.Intent"
41 | i = Intent(Intent.ACTION_SEND)
42 | i.setType("message/rfc822")
43 | i.putExtra(Intent.EXTRA_EMAIL, {"2113075983@.com"})
44 | i.putExtra(Intent.EXTRA_SUBJECT,"Feedback")
45 | i.putExtra(Intent.EXTRA_TEXT,"Content")
46 | activity.startActivity(Intent.createChooser(i, "Choice"))》》
47 |
48 | 《《自定义默认弹窗标题,消息,按钮的颜色》》
49 | 《《dialog=AlertDialog.Builder(this)
50 | .setTitle("标题")
51 | .setMessage("消息")
52 | .setPositiveButton("积极",{onClick=function(v) print"点击了积极按钮"end})
53 | .setNeutralButton("中立",nil)
54 | .setNegativeButton("否认",nil)
55 | .show()
56 | dialog.create()
57 |
58 |
59 | --更改消息颜色
60 | message=dialog.findViewById(android.R.id.message)
61 | message.setTextColor(0xff1DA6DD)
62 |
63 | --更改Button颜色
64 | import "android.graphics.Color"
65 | dialog.getButton(dialog.BUTTON_POSITIVE).setTextColor(0xff1DA6DD)
66 | dialog.getButton(dialog.BUTTON_NEGATIVE).setTextColor(0xff1DA6DD)
67 | dialog.getButton(dialog.BUTTON_NEUTRAL).setTextColor(0xff1DA6DD)
68 |
69 | --更改Title颜色
70 | import "android.text.SpannableString"
71 | import "android.text.style.ForegroundColorSpan"
72 | import "android.text.Spannable"
73 | sp = SpannableString("标题")
74 | sp.setSpan(ForegroundColorSpan(0xff1DA6DD),0,#sp,Spannable.SPAN_EXCLUSIVE_INCLUSIVE)
75 | dialog.setTitle(sp)》》
76 |
77 |
78 | 《《获取手机存储空间》》
79 | 《《--获取手机内置剩余存储空间
80 | function GetSurplusSpace()
81 | fs = StatFs(Environment.getDataDirectory().getPath())
82 | return Formatter.formatFileSize(activity, (fs.getAvailableBytes()))
83 | end
84 |
85 | --获取手机内置存储总空间
86 | function GetTotalSpace()
87 | path = Environment.getExternalStorageDirectory()
88 | stat = StatFs(path.getPath())
89 | blockSize = stat.getBlockSize()
90 | totalBlocks = stat.getBlockCount()
91 | return Formatter.formatFileSize(activity, blockSize * totalBlocks)
92 | end》》
93 |
94 |
95 | 《《获取视频第一帧》》
96 | 《《function GetVideoFrame(path)
97 | import "android.media.MediaMetadataRetriever"
98 | media = MediaMetadataRetriever()
99 | media.setDataSource(tostring(path))
100 | return media.getFrameAtTime()
101 | end》》
102 |
103 | 《《选择文件模块》》
104 | 《《import "android.widget.ArrayAdapter"
105 | import "android.widget.LinearLayout"
106 | import "android.widget.TextView"
107 | import "java.io.File"
108 | import "android.widget.ListView"
109 | import "android.app.AlertDialog"
110 | function ChoiceFile(StartPath,callback)
111 | --创建ListView作为文件列表
112 | lv=ListView(activity).setFastScrollEnabled(true)
113 | --创建路径标签
114 | cp=TextView(activity)
115 | lay=LinearLayout(activity).setOrientation(1).addView(cp).addView(lv)
116 | ChoiceFile_dialog=AlertDialog.Builder(activity)--创建对话框
117 | .setTitle("选择文件")
118 | .setView(lay)
119 | .show()
120 | adp=ArrayAdapter(activity,android.R.layout.simple_list_item_1)
121 | lv.setAdapter(adp)
122 | function SetItem(path)
123 | path=tostring(path)
124 | adp.clear()--清空适配器
125 | cp.Text=tostring(path)--设置当前路径
126 | if path~="/" then--不是根目录则加上../
127 | adp.add("../")
128 | end
129 | ls=File(path).listFiles()
130 | if ls~=nil then
131 | ls=luajava.astable(File(path).listFiles()) --全局文件列表变量
132 | table.sort(ls,function(a,b)
133 | return (a.isDirectory()~=b.isDirectory() and a.isDirectory()) or ((a.isDirectory()==b.isDirectory()) and a.Name=48 and c<=57) or (c>= 65 and c<=90) or (c>=97 and c<=122) then
301 | if not string.char(c):find("%w") then
302 | table.insert(ss, string.char(c))
303 | end
304 | elseif c>=228 and c<=233 then
305 | local c1 = string.byte(s,k+1)
306 | local c2 = string.byte(s,k+2)
307 | if c1 and c2 then
308 | local a1,a2,a3,a4 = 128,191,128,191
309 | if c == 228 then a1 = 184
310 | elseif c == 233 then a2,a4 = 190,c1 ~= 190 and 191 or 165
311 | end
312 | if c1>=a1 and c1<=a2 and c2>=a3 and c2<=a4 then
313 | k = k + 2
314 | table.insert(ss, string.char(c,c1,c2))
315 | end
316 | end
317 | end
318 | end
319 | return table.concat(ss)
320 | end
321 | print(filter_spec_chars("A1B2汉C3D4字E5F6,,,"))
322 | --来源网络,加了个if过滤掉英文与数字,使其只捕获中文》》
323 |
324 |
325 |
326 | 《《播放音乐与视频》》
327 | 《《import "android.media.MediaPlayer"
328 | mediaPlayer = MediaPlayer()
329 |
330 | --初始化参数
331 | mediaPlayer.reset()
332 |
333 | --设置播放资源
334 | mediaPlayer.setDataSource("storage/sdcard0/a.mp3")
335 |
336 | --开始缓冲资源
337 | mediaPlayer.prepare()
338 |
339 | --是否循环播放该资源
340 | mediaPlayer.setLooping(true)
341 |
342 | --缓冲完成的监听
343 | mediaPlayer.setOnPreparedListener(MediaPlayer.OnPreparedListener() {
344 | onPrepared=function(mediaPlayer
345 | mediaPlayer.start()
346 | end});
347 |
348 | --是否在播放
349 | mediaPlayer.isPlaying()
350 |
351 | --暂停播放
352 | mediaPlayer.pause()
353 |
354 | --从30位置开始播放
355 | mediaPlayer.seekTo(30)
356 |
357 | --停止播放
358 | mediaPlayer.stop()
359 |
360 |
361 |
362 |
363 |
364 |
365 | --播放视频
366 | --视频的播放与音乐播放过程一样:
367 |
368 | --先创建一个媒体对象
369 | import "android.media.MediaPlayer"
370 | mediaPlayer = MediaPlayer()
371 | --初始化参数
372 | mediaPlayer.reset()
373 |
374 | --设置播放资源
375 | mediaPlayer.setDataSource("storage/sdcard0/a.mp4")
376 |
377 | --拿到显示的SurfaceView
378 | sh = surfaceView.getHolder()
379 | sh.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS)
380 |
381 | --设置显示SurfaceView
382 | mediaPlayer.setDisplay(sh)
383 |
384 | --设置音频流格式
385 | mediaPlayer.setAudioStreamType(AudioManager.Stream_Music)
386 |
387 | --开始缓冲资源
388 | mediaPlayer.prepare()
389 |
390 | --缓冲完成的监听
391 | mediaPlayer.setOnPreparedListener(MediaPlayer.OnPreparedListener{
392 | onPrepared=function(mediaPlayer)
393 | --开始播放
394 | mediaPlayer.start()
395 | end
396 | });
397 |
398 | --释放播放器
399 | mediaPlayer.release()
400 |
401 |
402 | --非原创》》
403 |
404 |
405 |
406 | 《《获取系统SDK,Android版本及设备型号》》
407 | 《《device_model = Build.MODEL --设备型号
408 |
409 | version_sdk = Build.VERSION.SDK --设备SDK版本
410 |
411 | version_release = Build.VERSION.RELEASE --设备的系统版本》》
412 |
413 |
414 |
415 | 《《控件颜色修改》》
416 | 《《import "android.graphics.PorterDuffColorFilter"
417 | import "android.graphics.PorterDuff"
418 |
419 | --修改按钮颜色
420 | button.getBackground().setColorFilter(PorterDuffColorFilter(0xFFFB7299,PorterDuff.Mode.SRC_ATOP))
421 |
422 | --修改编辑框颜色
423 | edittext.getBackground().setColorFilter(PorterDuffColorFilter(0xFFFB7299,PorterDuff.Mode.SRC_ATOP));
424 |
425 | --修改Switch颜色
426 | switch.ThumbDrawable.setColorFilter(PorterDuffColorFilter(0xFFFB7299,PorterDuff.Mode.SRC_ATOP));
427 | switch.TrackDrawable.setColorFilter(PorterDuffColorFilter(0xFFFB7299,PorterDuff.Mode.SRC_ATOP))
428 |
429 | --修改ProgressBar颜色
430 | progressbar.IndeterminateDrawable.setColorFilter(PorterDuffColorFilter(0xFFFB7299,PorterDuff.Mode.SRC_ATOP))
431 |
432 | --修改SeekBar滑条颜色
433 | seekbar.ProgressDrawable.setColorFilter(PorterDuffColorFilter(0xFFFB7299,PorterDuff.Mode.SRC_ATOP))
434 | --修改SeekBar滑块颜色
435 | seekbar.Thumb.setColorFilter(PorterDuffColorFilter(0xFFFB7299,PorterDuff.Mode.SRC_ATOP))》》
436 |
437 |
438 |
439 |
440 |
441 | 《《修改对话框按钮颜色》》
442 | 《《function DialogButtonFilter(dialog,button,WidgetColor)
443 | if Build.VERSION.SDK_INT >= 21 then
444 | import "android.graphics.PorterDuffColorFilter"
445 | import "android.graphics.PorterDuff"
446 | if button==1 then
447 | dialog.getButton(dialog.BUTTON_POSITIVE).setTextColor(WidgetColor)
448 | elseif button==2 then
449 | dialog.getButton(dialog.BUTTON_NEGATIVE).setTextColor(WidgetColor)
450 | elseif button==3 then
451 | dialog.getButton(dialog.BUTTON_NEUTRAL).setTextColor(WidgetColor)
452 | end
453 | end
454 | end
455 | --第一个参数为对话框的变量
456 | --第二个参数为1时,则修改POSITIVE按钮颜色,为二则修改NEGATIVE按钮颜色,为三则修改NEUTRAL按钮颜色
457 | --第三个参数为要修改成的颜色》》
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 | 《《查询本地所有视频》》
466 | 《《function QueryAllVideo()
467 | import "android.provider.MediaStore"
468 | cursor = activity.ContentResolver
469 | mImageUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
470 | mCursor = cursor.query(mImageUri,nil,nil,nil,MediaStore.Video.Media.DATE_TAKEN)
471 | mCursor.moveToLast()
472 | VideoTable={}
473 | while mCursor.moveToPrevious() do
474 | path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Video.Media.DATA))
475 | table.insert(VideoTable,tostring(path))
476 | end
477 | mCursor.close()
478 | return VideoTable
479 | end
480 | --返回一个表》》
481 |
482 |
483 |
484 |
485 | 《《查询本地所有图片》》
486 | 《《function QueryAllImage()
487 | import "android.provider.MediaStore"
488 | cursor = activity.ContentResolver
489 | mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
490 | mCursor = cursor.query(mImageUri,nil,nil,nil,MediaStore.Images.Media.DATE_TAKEN)
491 | mCursor.moveToLast()
492 | imageTable={}
493 | while mCursor.moveToPrevious() do
494 | path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DATA))
495 | table.insert(imageTable,tostring(path))
496 | end
497 | mCursor.close()
498 | return imageTable
499 | end
500 | --返回一个表》》
501 |
502 |
503 |
504 |
505 | 《《递归查找文件》》
506 | 《《function outPath(ret)
507 | for i,p in pairs(luajava.astable(ret)) do
508 | print(p)
509 | end
510 | end
511 | function find(catalog,name)
512 | local n=0
513 | local t=os.clock()
514 | local ret={}
515 | require "import"
516 | import "java.io.File"
517 | import "java.lang.String"
518 | function FindFile(catalog,name)
519 | local name=tostring(name)
520 | local ls=catalog.listFiles() or File{}
521 | for 次数=0,#ls-1 do
522 | --local 目录=tostring(ls[次数])
523 | local f=ls[次数]
524 | if f.isDirectory() then--如果是文件夹则继续匹配
525 | FindFile(f,name)
526 | else--如果是文件则
527 | n=n+1
528 | if n%1000==0 then
529 | print(n,os.clock()-t)
530 | end
531 | local nm=f.Name
532 | if string.find(nm,name) then
533 | --thread(insert,目录)
534 | table.insert(ret,tostring(f))
535 | end
536 | end
537 | luajava.clear(f)
538 | end
539 | end
540 | FindFile(catalog,name)
541 | call("outPath",ret)
542 | end
543 |
544 | import "java.io.File"
545 |
546 | catalog=File("/sdcard/AndroLua")
547 | name=".j?pn?g"
548 | thread(find,catalog,name)》》
549 |
550 | 《《获取手机内置存储路径》》
551 | 《《Environment.getExternalStorageDirectory().toString()》》
552 |
553 |
554 |
555 |
556 | 《《获取已安装程序的包名、版本号、最后更新时间、图标、应用名称》》
557 | 《《function GetAppInfo(包名)
558 | import "android.content.pm.PackageManager"
559 | local pm = activity.getPackageManager();
560 | local 图标 = pm.getApplicationInfo(tostring(包名),0)
561 | local 图标 = 图标.loadIcon(pm);
562 | local pkg = activity.getPackageManager().getPackageInfo(包名, 0);
563 | local 应用名称 = pkg.applicationInfo.loadLabel(activity.getPackageManager())
564 | local 版本号 = activity.getPackageManager().getPackageInfo(包名, 0).versionName
565 | local 最后更新时间 = activity.getPackageManager().getPackageInfo(包名, 0).lastUpdateTime
566 | local cal = Calendar.getInstance();
567 | cal.setTimeInMillis(最后更新时间);
568 | local 最后更新时间 = cal.getTime().toLocaleString()
569 | return 包名,版本号,最后更新时间,图标,应用名称
570 | end》》
571 |
572 | 《《获取指定安装包的包名,图标,应用名》》
573 | 《《import "android.content.pm.PackageManager"
574 | import "android.content.pm.ApplicationInfo"
575 | function GetApkInfo(archiveFilePath)
576 | pm = activity.getPackageManager()
577 | info = pm.getPackageArchiveInfo(archiveFilePath, PackageManager.GET_ACTIVITIES);
578 | if info ~= nil then
579 | appInfo = info.applicationInfo;
580 | appName = tostring(pm.getApplicationLabel(appInfo))
581 | packageName = appInfo.packageName; --安装包名称
582 | version=info.versionName; --版本信息
583 | icon = pm.getApplicationIcon(appInfo);--图标
584 | end
585 | return packageName,version,icon
586 | end》》
587 |
588 | 《《获取某程序是否安装》》
589 | 《《if pcall(function() activity.getPackageManager().getPackageInfo("包名",0) end) then
590 | print("安装了")
591 | else
592 | print("没安装")
593 | end》》
594 |
595 | 《《设置TextView字体风格》》
596 | 《《import "android.graphics.Paint"
597 | --设置中划线
598 | id.getPaint().setFlags(Paint. STRIKE_THRU_TEXT_FLAG)
599 | --设置下划线
600 | id.getPaint().setFlags(Paint. UNDERLINE_TEXT_FLAG )
601 | --设置加粗
602 | id.getPaint().setFakeBoldText(true)
603 | --设置斜体
604 | id.getPaint().setTextSkewX(0.2)
605 |
606 | --设置TypeFace
607 | import "android.graphics.Typeface"
608 | id.getPaint().setTypeface()
609 | --参数列表
610 | Typeface.DEFAULT 默认字体
611 | Typeface.DEFAULT_BOLD 加粗字体
612 | Typeface.MONOSPACE monospace字体
613 | Typeface.SANS_SERIF sans字体
614 | Typeface.SERIF serif字体》》
615 |
616 |
617 |
618 | 《《缩放图片》》
619 | 《《function rotateToFit(bm,degrees)
620 | import "android.graphics.Matrix"
621 | import "android.graphics.Bitmap"
622 | width = bm.getWidth()
623 | height = bm.getHeight()
624 | matrix = Matrix()
625 | matrix.postRotate(degrees)
626 | bmResult = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true)
627 | return bmResult
628 | end
629 | bm=loadbitmap(图片路径)
630 | 缩放级别=2
631 | rotateToFit(bm,degrees)
632 | --非原创》》
633 |
634 | 《《获取运营商名称》》
635 | 《《import "android.content.Context"
636 | 运营商名称 = this.getSystemService(Context.TELEPHONY_SERVICE).getNetworkOperatorName()
637 | print(运营商名称)
638 | --添加权限 READ_PHONE_STATE》》
639 |
640 |
641 | 《《Drawable着色》》
642 | 《《function ToColor(path,color)
643 | local aa=BitmapDrawable(loadbitmap(tostring(path)))
644 | aa.setColorFilter(PorterDuffColorFilter(color,PorterDuff.Mode.SRC_ATOP))
645 | return aa
646 | end》》
647 |
648 |
649 |
650 |
651 | 《《保存图片到本地》》
652 | 《《function SavePicture(name,bm)
653 | if bm then
654 | import "java.io.FileOutputStream"
655 | import "java.io.File"
656 | import "android.graphics.Bitmap"
657 | name=tostring(name)
658 | f = File(name)
659 | out = FileOutputStream(f)
660 | bm.compress(Bitmap.CompressFormat.PNG,90, out)
661 | out.flush()
662 | out.close()
663 | return true
664 | else
665 | return false
666 | end
667 | end》》
668 |
669 |
670 |
671 |
672 | 《《调用应用商店搜索应用》》
673 | 《《import "android.content.Intent"
674 | import "android.net.Uri"
675 | intent = Intent("android.intent.action.VIEW")
676 | intent .setData(Uri.parse( "market://details?id="..activity.getPackageName()))
677 | this.startActivity(intent)》》
678 |
679 |
680 |
681 | 《《分享》》
682 | 《《--分享文件
683 | function Sharing(path)
684 | import "android.webkit.MimeTypeMap"
685 | import "android.content.Intent"
686 | import "android.net.Uri"
687 | import "java.io.File"
688 | FileName=tostring(File(path).Name)
689 | ExtensionName=FileName:match("%.(.+)")
690 | Mime=MimeTypeMap.getSingleton().getMimeTypeFromExtension(ExtensionName)
691 | intent = Intent();
692 | intent.setAction(Intent.ACTION_SEND);
693 | intent.setType(Mime);
694 | file = File(path);
695 | uri = Uri.fromFile(file);
696 | intent.putExtra(Intent.EXTRA_STREAM,uri);
697 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
698 | activity.startActivity(Intent.createChooser(intent, "分享到:"));
699 | end
700 |
701 | --分享文字
702 | text="分享的内容"
703 | intent=Intent(Intent.ACTION_SEND);
704 | intent.setType("text/plain");
705 | intent.putExtra(Intent.EXTRA_SUBJECT, "分享");
706 | intent.putExtra(Intent.EXTRA_TEXT, text);
707 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
708 | activity.startActivity(Intent.createChooser(intent,"分享到:")); 》》
709 |
710 |
711 | 《《调用其它程序打开文件》》
712 | 《《function OpenFile(path)
713 | import "android.webkit.MimeTypeMap"
714 | import "android.content.Intent"
715 | import "android.net.Uri"
716 | import "java.io.File"
717 | FileName=tostring(File(path).Name)
718 | ExtensionName=FileName:match("%.(.+)")
719 | Mime=MimeTypeMap.getSingleton().getMimeTypeFromExtension(ExtensionName)
720 | if Mime then
721 | intent = Intent();
722 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
723 | intent.setAction(Intent.ACTION_VIEW);
724 | intent.setDataAndType(Uri.fromFile(File(path)), Mime);
725 | activity.startActivity(intent);
726 | else
727 | Toastc("找不到可以用来打开此文件的程序")
728 | end
729 | end》》
730 |
731 |
732 | 《《图片圆角》》
733 | 《《function GetRoundedCornerBitmap(bitmap,roundPx)
734 | import "android.graphics.PorterDuffXfermode"
735 | import "android.graphics.Paint"
736 | import "android.graphics.RectF"
737 | import "android.graphics.Bitmap"
738 | import "android.graphics.PorterDuff$Mode"
739 | import "android.graphics.Rect"
740 | import "android.graphics.Canvas"
741 | import "android.util.Config"
742 | width = bitmap.getWidth()
743 | output = Bitmap.createBitmap(width, width,Bitmap.Config.ARGB_8888)
744 | canvas = Canvas(output);
745 | color = 0xff424242;
746 | paint = Paint()
747 | rect = Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
748 | rectF = RectF(rect);
749 | paint.setAntiAlias(true);
750 | canvas.drawARGB(0, 0, 0, 0);
751 | paint.setColor(color);
752 | canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
753 | paint.setXfermode(PorterDuffXfermode(Mode.SRC_IN));
754 | canvas.drawBitmap(bitmap, rect, rect, paint);
755 | return output;
756 | end
757 | import "android.graphics.drawable.BitmapDrawable"
758 | 圆角弧度=50
759 | bitmap=loadbitmap(picturePath)
760 | RoundPic=GetRoundedCornerBitmap(bitmap)》》
761 |
762 |
763 |
764 | 《《一键加群与QQ聊天》》
765 | 《《import "android.net.Uri"
766 | import "android.content.Intent"
767 | --加群
768 | url="mqqapi://card/show_pslcard?src_type=internal&version=1&uin=383792635&card_type=group&source=qrcode"
769 | activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
770 |
771 | --QQ聊天
772 | url="mqqwpa://im/chat?chat_type=wpa&uin=2113075983"
773 | activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))》》
774 |
775 |
776 |
777 |
778 |
779 |
780 | 《《发送短信》》
781 | 《《--后台发送短信
782 | require "import"
783 | import "android.telephony.*"
784 | SmsManager.getDefault().sendTextMessage(tostring(号码), nil, tostring(内容), nil, nil)
785 |
786 | --调用系统发送短信
787 | import "android.content.Intent"
788 | import "android.net.Uri"
789 | uri = Uri.parse("smsto:"..号码)
790 | intent = Intent(Intent.ACTION_SENDTO, uri)
791 | intent.putExtra("sms_body",内容)
792 | intent.setAction("android.intent.action.VIEW")
793 | activity.startActivity(intent)》》
794 |
795 |
796 | 《《判断数组中是否存在某个值》》
797 | 《《function Table_exists(tables,value)
798 | for index,content in pairs(tables) do
799 | if content:find(value) then
800 | return true
801 | end
802 | end
803 | end》》
804 |
805 |
806 | 《《字符串操作》》
807 | 《《strings="左中右"
808 |
809 | --取字符串左边
810 | 左=strings:match("(.+)中")
811 |
812 |
813 | --取字符串中间
814 | 中=strings:match("左(.-)右")
815 |
816 |
817 | --取字符串右边
818 | 右=strings:match("(.+)右")
819 |
820 | --替换
821 | string.gsub(原字符串,替换的字符串,替换成的字符串)
822 |
823 | --匹配子串位置
824 | 起始位置,结束位置=string.find(字符串,子串)
825 |
826 |
827 | --按位置捕获字符串
828 | string.sub(字符串,子串起始位置,子串结束位置)》》
829 |
830 |
831 | 《《剪切板操作》》
832 | 《《import "android.content.Context"
833 | --导入类
834 |
835 | a=activity.getSystemService(Context.CLIPBOARD_SERVICE).getText()
836 | --获取剪贴板
837 |
838 | activity.getSystemService(Context.CLIPBOARD_SERVICE).setText(edit.Text)
839 | --写入剪贴板》》
840 |
841 | 《《各种事件》》
842 | 《《function main(...)
843 | --...是newActivity传递过来的参数。
844 | print("入口函数",...)
845 | end
846 |
847 | function onCreate()
848 | print("窗口创建")
849 | end
850 |
851 | function onStart()
852 | print("活动开始")
853 | end
854 |
855 | function onResume()
856 | print("返回程序")
857 | end
858 |
859 | function onPause()
860 | print("活动暂停")
861 | end
862 |
863 | function onStop()
864 | print("活动停止")
865 | end
866 |
867 | function onDestroy()
868 | print("程序已退出")
869 | end
870 |
871 | function onResult(name,...)
872 | --name:返回的活动名称
873 | --...:返回的参数
874 | print("返回活动",name,...)
875 | end
876 |
877 | function onCreateOptionsMenu(menu)
878 | --menu:选项菜单。
879 | menu.add("菜单")
880 | end
881 |
882 | function onOptionsItemSelected(item)
883 | --item:选中的菜单项
884 | print(item.Title)
885 | end
886 |
887 | function onConfigurationChanged(config)
888 | --config:配置信息
889 | print("屏幕方向关闭")
890 | end
891 |
892 | function onKeyDown(keycode,event)
893 | --keycode:键值
894 | --event:事件
895 | print("按键按下",keycode)
896 | end
897 |
898 | function onKeyUp(keycode,event)
899 | --keycode:键值
900 | --event:事件
901 | print("按键抬起",keycode)
902 | end
903 |
904 | function onKeyLongPress(keycode,event)
905 | --keycode:键值
906 | --event:事件
907 | print("按键长按",keycode)
908 | end
909 |
910 | function onTouchEvent(event)
911 | --event:事件
912 | print("触摸事件",event)
913 | end
914 |
915 | function onKeyDown(c,e)
916 | if c==4 then
917 | --返回键事件
918 | end
919 | end
920 |
921 |
922 | id.onClick=function()
923 | --控件被单击
924 | end
925 |
926 | id.onLongClick=function()
927 | --控件被长按
928 | end
929 |
930 |
931 | id.onItemClick=function(p,v,i,s)
932 | --列表项目被单击
933 | 项目=v.Text
934 | return true
935 | end
936 |
937 | id.onItemLongClick=function(p,v,i,s)
938 | --列表项目被长按
939 | 项目=v.Text
940 | return true
941 | end
942 |
943 |
944 | id.onItemLongClick=function(p,v,i,s)
945 | --列表项目被长按
946 | 项目=v.Text
947 | return true
948 | end
949 |
950 | --Spinner的项目单击事件
951 | id.onItemSelected=function(l,v,p,i)
952 | 项目=v.Text
953 | end
954 |
955 | --ExpandableListView的父项目与子项目单击事件
956 | id.onGroupClick=function(l,v,p,s)
957 | print(v.Text..":GroupClick")
958 | end
959 |
960 | id.onChildClick=function(l,v,g,c)
961 | print(v.Text..":ChildClick")
962 | end》》
963 |
964 |
965 | 《《Shell执行》》
966 | 《《function exec(cmd)
967 | local p=io.popen(string.format('%s',cmd))
968 | local s=p:read("*a")
969 | p:close()
970 | return s
971 | end
972 |
973 | print(exec("echo ...."))
974 |
975 | 部分常用命令:
976 | --删除文件或文件夹
977 | rm -r /路径
978 |
979 | --复制文件或文件夹
980 | cp -r inpath outpath
981 |
982 | --移动文件或文件夹
983 | mv -r inpath outpath
984 |
985 | --挂载系统目录
986 | mount -o remount,rw path
987 |
988 | --修改系统文件权限
989 | chmod 755 /system/build.prop
990 |
991 | --重启
992 | reboot
993 |
994 | --关机
995 | reboot -p
996 |
997 | --重启至recovery
998 | reboot recovery》》
--------------------------------------------------------------------------------
/app/src/main/assets/文件操作.txt:
--------------------------------------------------------------------------------
1 | 《《创建新文件》》
2 | 《《--使用File类
3 | import "java.io.File"--导入File类
4 | File(文件路径).createNewFile()
5 |
6 | --使用io库
7 | io.open("/sdcard/aaaa", 'w')》》
8 |
9 | 《《创建新文件夹》》
10 | 《《--使用File类
11 | import "java.io.File"--导入File类
12 | File(文件夹路径).mkdir()
13 |
14 | --创建多级文件夹
15 | File(文件夹路径).mkdirs()
16 |
17 | --shell
18 | os.execute('mkdir '..文件夹路径)》》
19 |
20 | 《《重命名与移动文件》》
21 | 《《--Shell
22 | os.execute("mv "..oldname.." "..newname)
23 |
24 | --os
25 | os.rename (oldname, newname)
26 |
27 | --File
28 | import "java.io.File"--导入File类
29 | File(旧).renameTo(File(新))》》
30 |
31 |
32 | 《《追加更新文件》》
33 | 《《io.open(文件路径,"a+"):write("更新的内容"):close()》》
34 |
35 |
36 |
37 | 《《更新文件》》
38 | 《《io.open(文件路径,"w+"):write("更新的内容"):close()》》
39 |
40 | 《《写入文件》》
41 | 《《io.open(文件路径,"w"):write("内容"):close()》》
42 |
43 | 《《写入文件(自动创建父文件夹)》》
44 | 《《function 写入文件(路径,内容)
45 | import "java.io.File"
46 | f=File(tostring(File(tostring(路径)).getParentFile())).mkdirs()
47 | io.open(tostring(路径),"w"):write(tostring(内容)):close()
48 | end》》
49 |
50 |
51 |
52 | 《《读取文件》》
53 | 《《io.open(文件路径):read("*a")》》
54 |
55 |
56 |
57 | 《《按行读取文件》》
58 | 《《for c in io.lines(文件路径) do
59 | print(c)
60 | end》》
61 |
62 |
63 |
64 | 《《删除文件或文件夹》》
65 | 《《--使用File类
66 | import "java.io.File"--导入File类
67 | File(文件路径).delete()
68 | --使用os方法
69 | os.remove (filename)》》
70 |
71 |
72 | 《《复制文件》》
73 | 《《LuaUtil.copyDir(from,to)》》
74 |
75 |
76 |
77 |
78 | 《《递归删除文件夹或文件》》
79 | 《《--使用LuaUtil辅助库
80 | LuaUtil.rmDir(路径)
81 |
82 | --使用Shell
83 | os.execute("rm -r "..路径)》》
84 |
85 |
86 | 《《替换文件内字符串》》
87 | 《《function 替换文件字符串(路径,要替换的字符串,替换成的字符串)
88 | if 路径 then
89 | 路径=tostring(路径)
90 | 内容=io.open(路径):read("*a")
91 | io.open(路径,"w+"):write(tostring(内容:gsub(要替换的字符串,替换成的字符串))):close()
92 | else
93 | return false
94 | end
95 | end》》
96 | 《《获取文件列表》》
97 | 《《import("java.io.File")
98 | luajava.astable(File(文件夹路径).listFiles())》》
99 |
100 |
101 | 《《获取文件名称》》
102 | 《《import "java.io.File"--导入File类
103 | File(路径).getName()》》
104 |
105 | 《《获取文件大小》》
106 | 《《function GetFileSize(path)
107 | import "java.io.File"
108 | import "android.text.format.Formatter"
109 | size=File(tostring(path)).length()
110 | Sizes=Formatter.formatFileSize(activity, size)
111 | return Sizes
112 | end》》
113 |
114 |
115 | 《《获取文件或文件夹最后修改时间》》
116 | 《《function GetFilelastTime(path)
117 | f = File(path);
118 | cal = Calendar.getInstance();
119 | time = f.lastModified()
120 | cal.setTimeInMillis(time);
121 | return cal.getTime().toLocaleString()
122 | end》》
123 |
124 |
125 | 《《获取文件字节》》
126 | 《《import "java.io.File"--导入File类
127 | File(路径).length()》》
128 |
129 |
130 | 《《获取文件父文件夹路径》》
131 | 《《import "java.io.File"--导入File类
132 | File(path).getParentFile()》》
133 |
134 | 《《获取文件Mime类型》》
135 | 《《function GetFileMime(name)
136 | import "android.webkit.MimeTypeMap"
137 | ExtensionName=tostring(name):match("%.(.+)")
138 | Mime=MimeTypeMap.getSingleton().getMimeTypeFromExtension(ExtensionName)
139 | return tostring(Mime)
140 | end
141 | print(GetFileMime("/sdcard/a.png"))》》
142 |
143 |
144 | 《《判断路径是不是文件夹》》
145 | 《《import "java.io.File"--导入File类
146 | File(路径).isDirectory()
147 | --也可用来判断文件夹存不存在》》
148 |
149 |
150 |
151 | 《《判断路径是不是文件》》
152 | 《《import "java.io.File"--导入File类
153 | File(路径).isFile()
154 | --也可用来判断文件存不存在》》
155 |
156 |
157 | 《《判断文件或文件夹存不存在》》
158 | 《《import "java.io.File"--导入File类
159 | File(路径).exists()
160 |
161 | --使用io
162 | function file_exists(path)
163 | local f=io.open(path,'r')
164 | if f~=nil then io.close(f) return true else return false end
165 | end》》
166 |
167 |
168 |
169 | 《《判断是不是系统隐藏文件》》
170 | 《《import "java.io.File"--导入File类
171 | File(路径).isHidden()》》
172 |
--------------------------------------------------------------------------------
/app/src/main/assets/笔记.txt:
--------------------------------------------------------------------------------
1 | 《《打印》》
2 | 《《print(打印内容)》》
3 | 《《控件被单击》》
4 | 《《function 控件ID.onClick()
5 | --事件
6 | end
7 |
8 | 控件ID.onClick=function()
9 | --事件
10 | end》》
11 | 《《控件被长按》》
12 | 《《控件ID.onLongClick=function()
13 | --事件
14 | end
15 |
16 | function 控件ID.onLongClick()
17 | --事件
18 | end》》
19 | 《《控件可视,不可视或隐藏》》
20 | 《《--控件可视
21 | 控件ID.setVisibility(View.VISIBLE)
22 | --控件不可视
23 | 控件ID.setVisibility(View.INVISIBLE)
24 | --控件隐藏
25 | 控件ID.setVisibility(View.GONE)》》
26 | 《《提示框》》
27 | 《《import "android.content.DialogInterface"
28 | local dl=AlertDialog.Builder(activity)
29 | .setTitle("提示框标题")
30 | .setMessage("提示框内容")
31 | .setPositiveButton("按钮标题",DialogInterface
32 | .OnClickListener{
33 | onClick=function(v)
34 | --事件
35 | end
36 | })
37 | .setNegativeButton("按钮标题",nil)
38 | .create()
39 | dl.show()》》
40 | 《《读写文件》》
41 | 《《--读文件
42 | local file=io.input("地址")
43 | local str=io.read("*a")
44 | io.close()
45 | print(str)
46 | --写文件
47 | local file=io.output("地址")
48 | io.write(写入内容)
49 | io.flush()
50 | io.close()》》
51 | 《《加载框示例》》
52 | 《《local dl=ProgressDialog.show(activity,nil,'登录中')
53 | dl.show()
54 | local a=0
55 | local tt=Ticker()
56 | tt.start()
57 | tt.onTick=function()
58 | a=a+1
59 | if a==3 then
60 | dl.dismiss()
61 | tt.stop()
62 | end
63 | end》》
64 | 《《标题栏菜单按钮》》
65 | 《《tittle={"分享","帮助","皮肤","退出"}
66 | function onCreateOptionsMenu(menu)
67 | for k,v in ipairs(tittle) do
68 | if tittle[v] then
69 | local m=menu.addSubMenu(v)
70 | for k,v in ipairs(tittle[v]) do
71 | m.add(v)
72 | end
73 | else
74 | local m=menu.add(v)
75 | m.setShowAsActionFlags(1)
76 | end
77 | end
78 | end
79 | function onMenuItemSelected(id,tittle)
80 | if y[tittle.getTitle()] then
81 | y[tittle.getTitle()]()
82 | end
83 | end
84 |
85 | y={}
86 | y["帮助"]=function()
87 | --事件
88 | end
89 |
90 | --菜单
91 | function onCreateOptionsMenu(menu)
92 | menu.add("打开").onMenuItemClick=function(a)
93 |
94 | end
95 | menu.add("新建").onMenuItemClick=function(a)
96 |
97 | end
98 | end》》
99 | 《《关闭对话框》》
100 | 《《--将dl.show赋值
101 | dialog=dl.show()
102 | --在某按钮点击后关闭这个对话框
103 | function zc.onClick()
104 | dialog.dismiss()
105 | end》》
106 | 《《判断是否有网络》》
107 | 《《local wl=activity.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE).getActiveNetworkInfo();
108 | if wl== nil then
109 | print("无法连接到服务器")
110 | end》》
111 | 《《沉浸状态栏》》
112 | 《《--这个需要系统SDK21以上才能用
113 | if Build.VERSION.SDK_INT >= 21 then
114 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS).setStatusBarColor(0xff4285f4);
115 | end
116 | --这个需要系统SDK19以上才能用
117 | if Build.VERSION.SDK_INT >= 19 then
118 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
119 | end》》
120 | 《《复制文本到剪贴板》》
121 | 《《--先导入包
122 | import "android.content.*"
123 | activity.getSystemService(Context.CLIPBOARD_SERVICE).setText(文本)》》
124 | 《《安卓跳转动画》》
125 | 《《android.R.anim.accelerate_decelerate_interpolator
126 | android.R.anim.accelerate_interpolator
127 | android.R.anim.anticipate_interpolator
128 | android.R.anim.anticipate_overshoot_interpolator
129 | android.R.anim.bounce_interpolator
130 | android.R.anim.cycle_interpolator
131 | android.R.anim.decelerate_interpolatoandroid.R.anim.r
132 | android.R.anim.fade_in
133 | android.R.anim.fade_out
134 | android.R.anim.linear_interpolator
135 | android.R.anim.overshoot_interpolator
136 | android.R.anim.slide_in_left
137 | android.R.anim.slide_out_right》》
138 | 《《TextView文本可选择复制》》
139 | 《《--代码中设置
140 | t.TextIsSelectable=true
141 | --布局表中设置
142 | textIsSelectable=true》》
143 | 《《取随机数》》
144 | 《《math.random(最小值,最大值)》》
145 | 《《延迟》》
146 | 《《--这个会卡进程,配合线程使用
147 | Thread.sleep(延迟时间)
148 | --这个不会卡进程
149 | --500指延迟500毫秒
150 | task(500‚function()
151 | --延迟之后执行的事件
152 | end)》》
153 | 《《定时器》》
154 | 《《--timer定时器
155 | t=timer(function()
156 | --事件
157 | end,延迟,间隔,初始化)
158 | --暂停timer定时器
159 | t.Enable=false
160 | --启动timer定时器
161 | t.Enable=true
162 |
163 | --Ticker定时器
164 | ti=Ticker()
165 | ti.Period=间隔
166 | ti.onTick=function()
167 | --事件
168 | end
169 | --启动Ticker定时器
170 | ti.start()
171 | --停止Ticker定时器
172 | ti.stop()》》
173 | 《《获取本地时间》》
174 | 《《--格式的时间
175 | os.date("%Y-%m-%d %H:%M:%S")
176 | --本地时间总和
177 | os.clock()
178 | 《《EditText文本被改变事件
179 | 控件ID.addTextChangedListener{
180 | onTextChanged=function(s)
181 | --事件
182 | end
183 | }》》
184 | 《《字符串操作》》
185 | 《《--字符串转大写
186 | string.upper(字符串)
187 | --字符串转小写
188 | string.lower(字符串)
189 | --字符串替换
190 | string.gsub(字符串,被替换的字符,替换的字符,替换次数)》》
191 | 《《设置控件大小》》
192 | 《《--设置宽度
193 | linearParams = 控件ID.getLayoutParams()
194 | linearParams.width =宽度
195 | 控件ID.setLayoutParams(linearParams)
196 | --同理设置高度
197 | linearParams = 控件ID.getLayoutParams()
198 | linearParams.height =高度
199 | 控件ID.setLayoutParams(linearParams)》》
200 | 《《载入窗口传参》》
201 | 《《activity.newActivity("窗口名",{参数})
202 |
203 | --渐变动画效果的,中间是安卓跳转动画代码
204 | activity.newActivity("窗口名",android.R.anim.fade_in,android.R.anim.fade_out,{参数})》》
205 | 《《EditText只能输数字》》
206 | 《《import "android.text.InputType"
207 | import "android.text.method.DigitsKeyListener"
208 | 控件ID.setInputType(InputType.TYPE_CLASS_NUMBER)
209 | 控件ID.setKeyListener(DigitsKeyListener.getInstance("0123456789"))》》
210 | 《《窗口全屏》》
211 | 《《activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)》》
212 | 《《关闭当前窗口》》
213 | 《《activity.finish()》》
214 | 《《按两次返回键退出》》
215 | 《《参数=0
216 | function onKeyDown(code,event)
217 | if string.find(tostring(event),"KEYCODE_BACK") ~= nil then
218 | if 参数+2 > tonumber(os.time()) then
219 | activity.finish()
220 | else
221 | Toast.makeText(activity,"再按一次返回键退出" , Toast.LENGTH_SHORT )
222 | .show()
223 | 参数=tonumber(os.time())
224 | end
225 | return true
226 | end
227 | end》》
228 | 《《取字符串中间》》
229 | 《《string.match("左测试测试右","左(.-)右")》》
230 | 《《判断文件是否存在》》
231 | 《《--先导入io包
232 | import "java.io.*"
233 | file,err=io.open("路径")
234 | print(err)
235 | if err==nil then
236 | print("存在")
237 | else
238 | print("不存在")
239 | end》》
240 | 《《判断文件夹是否存在》》
241 | 《《--先导入io包
242 | import "java.io.*"
243 | if File(文件夹路径).isDirectory()then
244 | print("存在")
245 | else
246 | print("不存在")
247 | end》》
248 | 《《窗口回调事件》》
249 | 《《function onActivityResult()
250 | --事件
251 | end》》
252 | 《《隐藏标题栏》》
253 | 《《activity.ActionBar.hide()》》
254 | 《《自定义布局对话框》》
255 | 《《local dl=AlertDialog.Builder(activity)
256 | .setTitle("自定义布局对话框")
257 | .setView(loadlayout(layout))
258 | dl.show()》》
259 | 《《列表下滑到最底事件》》
260 | 《《list.setOnScrollListener{
261 | onScrollStateChanged=function(l,s)
262 | if list.getLastVisiblePosition()==list.getCount()-1 then
263 | --事件
264 | end
265 | end}》》
266 | 《《标题栏返回按钮》》
267 | 《《activity.getActionBar().setDisplayHomeAsUpEnabled(true) 》》
268 | 《《列表长按事件》》
269 | 《《ID.setOnItemLongClickListener(AdapterView.OnItemLongClickListener{
270 | onItemLongClick=function(parent, v, pos,id)
271 | --事件
272 | end
273 | })》》
274 | 《《列表点击事件》》
275 | 《《ID.setOnItemClickListener(AdapterView.OnItemClickListener{
276 | onItemClick=function(parent, v, pos,id)
277 | --事件
278 | end
279 | })》》
280 | 《《关于V4的圆形下拉刷新》》
281 | 《《--设置下拉刷新监听事件
282 | swipeRefreshLayout.setOnRefreshListener(this);
283 | --设置进度条的颜色
284 | swipeRefreshLayout.setColorSchemeColors(Color.RED, Color.BLUE, Color.GREEN);
285 | --设置圆形进度条大小
286 | swipeRefreshLayout.setSize(SwipeRefreshLayout.LARGE);
287 | --设置进度条背景颜色
288 | swipeRefreshLayout.setProgressBackgroundColorSchemeColor(Color.DKGRAY);
289 | --设置下拉多少距离之后开始刷新数据
290 | swipeRefreshLayout.setDistanceToTriggerSync(50);》》
291 | 《《活动中的回调》》
292 | 《《function main(...)
293 | --...是newActivity传递过来的参数。
294 | print("入口函数",...)
295 | end
296 |
297 | function onCreate()
298 | print("窗口创建")
299 | end
300 |
301 | function onStart()
302 | print("活动开始")
303 | end
304 |
305 | function onResume()
306 | print("返回程序")
307 | end
308 |
309 | function onPause()
310 | print("活动暂停")
311 | end
312 |
313 | function onStop()
314 | print("活动停止")
315 | end
316 |
317 | function onDestroy()
318 | print("程序已退出")
319 | end
320 |
321 | function onResult(name,...)
322 | --name:返回的活动名称
323 | --...:返回的参数
324 | print("返回活动",name,...)
325 | end
326 |
327 | function onCreateOptionsMenu(menu)
328 | --menu:选项菜单。
329 | menu.add("菜单")
330 | end
331 |
332 | function onOptionsItemSelected(item)
333 | --item:选中的菜单项
334 | print(item.Title)
335 | end
336 |
337 | function onConfigurationChanged(config)
338 | --config:配置信息
339 | print("屏幕方向关闭")
340 | end
341 |
342 | function onKeyDown(keycode,event)
343 | --keycode:键值
344 | --event:事件
345 | print("按键按下",keycode)
346 | end
347 |
348 | function onKeyUp(keycode,event)
349 | --keycode:键值
350 | --event:事件
351 | print("按键抬起",keycode)
352 | end
353 |
354 | function onKeyLongPress(keycode,event)
355 | --keycode:键值
356 | --event:事件
357 | print("按键长按",keycode)
358 | end
359 |
360 | function onTouchEvent(event)
361 | --event:事件
362 | print("触摸事件",event)
363 | end》》
364 | 《《对话框Dialog》》
365 | 《《--简单对话框
366 | AlertDialog.Builder(this).setTitle("标题")
367 | .setMessage("简单消息框")
368 | .setPositiveButton("确定",nil)
369 | .show();
370 |
371 | --带有三个按钮的对话框
372 | AlertDialog.Builder(this)
373 | .setTitle("确认")
374 | .setMessage("确定吗?")
375 | .setPositiveButton("是",nil)
376 | .setNegativeButton("否",nil)
377 | .setNeutralButton("不知道",nil)
378 | .show();
379 |
380 | --带输入框的
381 | AlertDialog.Builder(this)
382 | .setTitle("请输入")
383 | .setIcon(android.R.drawable.ic_dialog_info)
384 | .setView(EditText(this))
385 | .setPositiveButton("确定", nil)
386 | .setNegativeButton("取消", nil)
387 | .show();
388 |
389 | --单选的
390 | AlertDialog.Builder(this)
391 | .setTitle("请选择")
392 | .setIcon(android.R.drawable.ic_dialog_info)
393 | .setSingleChoiceItems({"选项1","选项2","选项3","选项4"}, 0,
394 | DialogInterface.OnClickListener() {
395 | onClick(dialog,which) {
396 | dialog.dismiss();
397 | }
398 | }
399 | )
400 | .setNegativeButton("取消", null)
401 | .show();
402 |
403 | --多选的
404 | AlertDialog.Builder(this)
405 | .setTitle("多选框")
406 | .setMultiChoiceItems({"选项1","选项2","选项3","选项4"}, null, null)
407 | .setPositiveButton("确定", null)
408 | .setNegativeButton("取消", null)
409 | .show();
410 |
411 | --列表的
412 | AlertDialog.Builder(this)
413 | .setTitle("列表框")
414 | .setItems({"列表项1","列表项2","列表项3"},nil)
415 | .setNegativeButton("确定",nil)
416 | .show();
417 |
418 | --图片的
419 | img = ImageView(this);
420 | img.setImageResource(R.drawable.icon);
421 | AlertDialog.Builder(this)
422 | .setTitle("图片框")
423 | .setView(img)
424 | .setPositiveButton("确定",nil)
425 | .show();》》
426 | 《《删除ListView中某项》》
427 | 《《adp.remove(pos)》》
428 | 《《打开某APP》》
429 | 《《--导入包
430 | import "android.content.*"
431 |
432 | intent = Intent();
433 | componentName = ComponentName("com.androlua","com.androlua.Welcome");
434 | intent.setComponent(componentName);
435 | activity.startActivity(intent);》》
436 | 《《设置横屏竖屏》》
437 | 《《--横屏
438 | activity.setRequestedOrientation(0);
439 | --竖屏
440 | activity.setRequestedOrientation(1); 》》
441 | 《《设置控件图片》》
442 | 《《--设置的图片也可以输入路径
443 | ID.setImageBitmap(loadbitmap("图片.png"))》》
444 | 《《禁用编辑框》》
445 | 《《--代码中设置
446 | editText.setFocusable(false);
447 | --布局表中设置
448 | Focusable=false;》》
449 | 《《隐藏滑条》》
450 | 《《--横向
451 | horizontalScrollBarEnabled=false;
452 | --竖向
453 | VerticalScrollBarEnabled=false;》》
454 | 《《图片着色》》
455 | 《《--代码中设置
456 | ID.setColorFilter(0xffff0000)
457 | --布局表中设置
458 | ColorFilter="#ffff0000";》》
459 | 《《获取IMEI号》》
460 | 《《import "android.content.*"
461 | --导入包
462 |
463 | imei=activity.getSystemService(Context.TELEPHONY_SERVICE).getDeviceId();
464 | print(imei)
465 |
466 | --别忘了添加权限"READ_PHONE_STATE" 》》
467 | 《《分享文字》》
468 | 《《import "android.content.*"
469 |
470 | text="分享的内容"
471 | intent=Intent(Intent.ACTION_SEND);
472 | intent.setType("text/plain");
473 | intent.putExtra(Intent.EXTRA_SUBJECT, "分享");
474 | intent.putExtra(Intent.EXTRA_TEXT, text);
475 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
476 | activity.startActivity(Intent.createChooser(intent,"分享到:")); 》》
477 | 《《发送短信》》
478 | 《《--导入包
479 | import "android.content.*"
480 | import "android.net.*"
481 |
482 | uri = Uri.parse("smsto:15800001234");
483 | intent = Intent(Intent.ACTION_SENDTO, uri);
484 | intent.putExtra("sms_body","你好")
485 | intent.setAction("android.intent.action.VIEW");
486 | activity.startActivity(intent); 》》
487 | 《《拔号》》
488 | 《《import "android.content.*"
489 | import "android.net.*"
490 | --导入包
491 | uri = Uri.parse("tel:15800001234");
492 | intent = Intent(Intent.ACTION_CALL, uri);
493 | intent.setAction("android.intent.action.VIEW");
494 | activity.startActivity(intent);
495 | --记得添加打电话权限 》》
496 | 《《安装APK》》
497 | 《《import "android.content.*"
498 | import "android.net.*"
499 |
500 | intent = Intent(Intent.ACTION_VIEW);
501 | intent.setDataAndType(Uri.parse("file:///sdcard/jc.apk"), "application/vnd.android.package-archive");
502 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
503 | activity.startActivity(intent); 》》
504 | 《《振动》》
505 | 《《import "android.content.Context"
506 | --导入包
507 | vibrator = activity.getSystemService(Context.VIBRATOR_SERVICE)
508 | vibrator.vibrate( long{100,800} ,-1)
509 | --{等待时间,振动时间,等待时间,振动时间,•••,•••,•••,•••••}
510 | --{0,1000,500,1000,500,1000}
511 | --别忘了申明权限》》
512 | 《《获取剪贴板内容》》
513 | 《《import"android.content.*"
514 | --导入包
515 | a=activity.getSystemService(Context.CLIPBOARD_SERVICE).getText()》》
516 | 《《压缩成ZIP》》
517 | 《《ZipUtil.zip("文件或文件夹路径","压缩到的路径")》》
518 | 《《ZIP解压》》
519 | 《《ZipUtil.unzip("ZIP路径","解压到的路径")
520 |
521 | --另一种Java方法
522 | import "java.io.FileOutputStream"
523 | import "java.util.zip.ZipFile"
524 | import "java.io.File"
525 |
526 | zipfile = "/sdcard/压缩包.zip"--压缩文件路径和文件名
527 | sdpath = "/sdcard/文件.lua"--解压后路径和文件名
528 | zipfilepath = "内容.lua"--需要解压的文件名
529 |
530 | function unzip(zippath , outfilepath , filename)
531 |
532 | local time=os.clock()
533 | task(function(zippath,outfilepath,filename)
534 | require "import"
535 | import "java.util.zip.*"
536 | import "java.io.*"
537 | local file = File(zippath)
538 | local outFile = File(outfilepath)
539 | local zipFile = ZipFile(file)
540 | local entry = zipFile.getEntry(filename)
541 | local input = zipFile.getInputStream(entry)
542 | local output = FileOutputStream(outFile)
543 | local byte=byte[entry.getSize()]
544 | local temp=input.read(byte)
545 | while temp ~= -1 do
546 | output.write(byte)
547 | temp=input.read(byte)
548 | end
549 | input.close()
550 | output.close()
551 | end,zippath,outfilepath,filename,
552 | function()
553 | print("解压完成,耗时 "..os.clock()-time.." s")
554 | end)
555 |
556 | end
557 |
558 | unzip(zipfile,sdpath,zipfilepath)》》
559 | 《《删除文件夹》》
560 | 《《--shell命令的方法
561 | os.execute("rm-r 路径")》》
562 | 《《重命名文件夹》》
563 | 《《--shell命令的方法
564 | os.execute("mv 路径新路径")》》
565 | 《《创建文件夹》》
566 | 《《--shell命令的方法
567 | os.execute("mkdir 路径")》》
568 | 《《删除文件》》
569 | 《《os.remove("路径")》》
570 | 《《设置标题栏标题》》
571 | 《《--标题
572 | activity.setTitle('标题')
573 | --小标题
574 | activity.getActionBar().setSubtitle('小标题')》》
575 | 《《获取Lua文件的执行路径》》
576 | 《《activity.getLuaDir()》》
577 | 《《获取本应用包名》》
578 | 《《activity.getPackageName()》》
579 | 《《布局设置点击效果》》
580 | 《《--5.0或以上可以实现点击水波纹效果
581 | --在布局加入:
582 |
583 | style="?android:attr/buttonBarButtonStyle";》》
584 | 《《判断某APP是否安装》》
585 | 《《if pcall(function() activity.getPackageManager().getPackageInfo("包名",0) end) then
586 | print("安装了")
587 | else
588 | print("没安装")
589 | end》》
590 | 《《调用系统下载》》
591 | 《《--导入包
592 | import "android.content.Context"
593 | import "android.net.Uri"
594 |
595 | downloadManager=activity.getSystemService(Context.DOWNLOAD_SERVICE);
596 | url=Uri.parse("绝对下载链接");
597 | request=DownloadManager.Request(url);
598 | request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE|DownloadManager.Request.NETWORK_WIFI);
599 | request.setDestinationInExternalPublicDir("目录名,可以是Download","下载的文件名");
600 | request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
601 | downloadManager.enqueue(request);》》
602 | 《《动画结束回调》》
603 | 《《--导入包
604 | import "android.view.animation.*"
605 | import "android.view.animation.Animation$AnimationListener"
606 | --控件动画
607 | 控件.startAnimation(AlphaAnimation(1,0).setDuration(400).setFillAfter(true).setAnimationListener(AnimationListener{
608 | onAnimationEnd=function()
609 | print"动画结束")
610 | end}))》》
611 | 《《关于侧滑》》
612 | 《《--侧滑布局是 DrawerLayout;
613 | --关闭侧滑
614 | ID.closeDrawer(3)
615 | --打开侧滑
616 | ID.openDrawer(3)》》
617 | 《《关于输入法影响布局的问题》》
618 | 《《--使弹出的输入法不影响布局
619 | activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
620 | --使弹出的输入法影响布局
621 | activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);》》
622 | 《《TextView设置字体样式》》
623 | 《《--首先要导入包
624 | import "android.graphics.*"
625 | --设置中划线
626 | 控件id.getPaint().setFlags(Paint. STRIKE_THRU_TEXT_FLAG)
627 | --下划线
628 | 控件id.getPaint().setFlags(Paint. UNDERLINE_TEXT_FLAG )
629 | --加粗
630 | 控件id.getPaint().setFakeBoldText(true)
631 | --斜体
632 | 控件id.getPaint().setTextSkewX(0.2)
633 |
634 | --设置TypeFace
635 | import "android.graphics.Typeface"
636 | id.getPaint().setTypeface(字体)
637 | --字体可以为以下
638 | Typeface.DEFAULT --默认字体
639 | Typeface.DEFAULT_BOLD --加粗字体
640 | Typeface.MONOSPACE --monospace字体
641 | Typeface.SANS_SERIF --sans字体
642 | Typeface.SERIF --serif字体》》
643 | 《《强制结束自身并清除自身数据》》
644 | 《《 os.execute("pm clear "..activity.getPackageName())》》
645 | 《《递归搜索文件实例》》
646 | 《《require "import"
647 |
648 | function find(catalog,name)
649 | local n=0
650 | local t=os.clock()
651 | local ret={}
652 | require "import"
653 | import "java.io.File"
654 | import "java.lang.String"
655 | function FindFile(catalog,name)
656 | local name=tostring(name)
657 | local ls=catalog.listFiles() or File{}
658 | for 次数=0,#ls-1 do
659 | --local 目录=tostring(ls[次数])
660 | local f=ls[次数]
661 | if f.isDirectory() then--如果是文件夹则继续匹配
662 | FindFile(f,name)
663 | else--如果是文件则
664 | n=n+1
665 | if n%1000==0 then
666 | --print(n,os.clock()-t)
667 | end
668 | local nm=f.Name
669 | if string.find(nm,name) then
670 | --thread(insert,目录)
671 | table.insert(ret,nm)
672 | print(nm)
673 | end
674 | end
675 | luajava.clear(f)
676 | end
677 | end
678 | FindFile(catalog,name)
679 | print("ok",n,#ret)
680 | end
681 |
682 | import "java.io.File"
683 |
684 | catalog=File("sdcard/")
685 | name=".j?pn?g"
686 | --task(find,catalog,name,print)
687 | thread(find,catalog,name)》》
688 | 《《获取ListView垂直坐标》》
689 | 《《function getScrollY()
690 | c = ls.getChildAt(0);
691 | local firstVisiblePosition = ls.getFirstVisiblePosition();
692 | local top = c.getTop();
693 | return -top + firstVisiblePosition * c.getHeight() ;
694 | end》》
695 | 《《申请root权限》》
696 | 《《--shell命令的方法
697 | os.execute("su")》》
698 | 《《传感器》》
699 | 《《传感器 = activity.getSystemService(Context.SENSOR_SERVICE)
700 |
701 | local 加速度传感器 = 传感器.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
702 | 传感器.registerListener(SensorEventListener({
703 | onSensorChanged=function(event)
704 | x轴 = event.values[0]
705 | y轴 = event.values[1]
706 | z轴 = event.values[2]
707 | end,nil}), 加速度传感器, SensorManager.SENSOR_DELAY_NORMAL)
708 |
709 | local 光线传感器 = 传感器.getDefaultSensor(Sensor.TYPE_LIGHT)
710 | 传感器.registerListener(SensorEventListener({
711 | onSensorChanged=function(event)
712 | 光线 = event.values[0]
713 | end,nil}), 光线传感器, SensorManager.SENSOR_DELAY_NORMAL)
714 |
715 | local 距离传感器 = 传感器.getDefaultSensor(Sensor.TYPE_PROXIMITY)
716 | 传感器.registerListener(SensorEventListener({
717 | onSensorChanged=function(event)
718 | 距离 = event.values[0]
719 | end,nil}), 距离传感器, SensorManager.SENSOR_DELAY_NORMAL)
720 |
721 | local 磁场传感器 = 传感器.getDefaultSensor(Sensor.TYPE_ORIENTATION)
722 | 传感器.registerListener(SensorEventListener({
723 | onSensorChanged=function(event)
724 | 磁场 = event.values[0]
725 | end,nil}), 磁场传感器, SensorManager.SENSOR_DELAY_NORMAL)
726 |
727 | local 温度传感器 = 传感器.getDefaultSensor(Sensor.TYPE_TEMPERATURE)
728 | 传感器.registerListener(SensorEventListener({
729 | onSensorChanged=function(event)
730 | 温度 = event.values[0]
731 | end,nil}), 温度传感器, SensorManager.SENSOR_DELAY_NORMAL)
732 |
733 | local 陀螺仪传感器 = 传感器.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
734 | 传感器.registerListener(SensorEventListener({
735 | onSensorChanged=function(event)
736 | 陀螺仪 = event.values[0]
737 | end,nil}), 陀螺仪传感器, SensorManager.SENSOR_DELAY_NORMAL)
738 |
739 | local 重力传感器 = 传感器.getDefaultSensor(Sensor.TYPE_GRAVITY)
740 | 传感器.registerListener(SensorEventListener({
741 | onSensorChanged=function(event)
742 | 重力 = event.values[0]
743 | end,nil}), 重力传感器, SensorManager.SENSOR_DELAY_NORMAL)
744 |
745 | local 压力传感器 = 传感器.getDefaultSensor(Sensor.TYPE_PRESSURE)
746 | 传感器.registerListener(SensorEventListener({
747 | onSensorChanged=function(event)
748 | 压力 = event.values[0]
749 | end,nil}), 压力传感器, SensorManager.SENSOR_DELAY_NORMAL)》》
750 | 《《获取控件宽高》》
751 | 《《--导入包
752 | import "android.content.Context"
753 |
754 | function getwh(view)
755 | view.measure(View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED),View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED));
756 | height =view.getMeasuredHeight();
757 | width =view.getMeasuredWidth();
758 | return width,height
759 | end
760 |
761 | print(getwh(控件ID))》》
762 | 《《播放音频》》
763 | 《《--导入包
764 | import "android.media.MediaPlayer"
765 |
766 | local 音频播放器=MediaPlayer()
767 | function 播放音频(路径)
768 | 音频播放器.reset()
769 | .setDataSource(路径)
770 | .prepare()
771 | .start()
772 | .setOnCompletionListener({
773 | onCompletion=function()
774 | print("播放完毕")
775 | end})
776 | end》》
777 | 《《控件旋转》》
778 | 《《--Z轴上的旋转角度
779 | View.getRotation()
780 |
781 | --X轴上的旋转角度
782 | View.getRotationX()
783 |
784 | --Y轴上的旋转角度
785 | View.getRotationY()
786 |
787 | --设置Z轴上的旋转角度
788 | View.setRotation(r)
789 |
790 | --设置X轴上的旋转角度
791 | View.setRotationX(r)
792 |
793 | --设置Y轴上的旋转角度
794 | View.setRotationY(r)
795 |
796 | --设置旋转中心点的X坐标
797 | View.setPivotX(p)
798 |
799 | --设置旋转中心点的Y坐标
800 | View.setPivotX(p)
801 |
802 | --设置摄像机的与旋转目标在Z轴上距离
803 | View.setCameraDistance(d)》》
--------------------------------------------------------------------------------
/app/src/main/assets/网络操作.txt:
--------------------------------------------------------------------------------
1 | 《《自带Http模块》》
2 | 《《获取内容 get函数
3 | Http.get(url,cookie,charset,header,callback)
4 | url 网络请求的链接网址
5 | cookie 使用的cookie,也就是服务器的身份识别信息
6 | charset 内容编码
7 | header 请求头
8 | callback 请求完成后执行的函数
9 |
10 | 除了url和callback其他参数都不是必须的
11 |
12 | 回调函数接受四个参数值分别是
13 | code 响应代码,2xx表示成功,4xx表示请求错误,5xx表示服务器错误,-1表示出错
14 | content 内容,如果code是-1,则为出错信息
15 | cookie 服务器返回的用户身份识别信息
16 | header 服务器返回的头信息
17 |
18 | 向服务器发送数据 post函数
19 | Http.post(url,data,cookie,charset,header,callback)
20 | 除了增加了一个data外,其他参数和get完全相同
21 | data 向服务器发送的数据
22 |
23 | 下载文件 download函数
24 | Http.download(url,path,cookie,header,callback)
25 | 参数中没有编码参数,其他同get,
26 | path 文件保存路径
27 |
28 | 需要特别注意一点,只支持同时有127个网络请求,否则会出错
29 |
30 |
31 | Http其实是对Http.HttpTask的封装,Http.HttpTask使用的更加通用和灵活的形式
32 | 参数格式如下
33 | Http.HttpTask( url, String method, cookie, charset, header, callback)
34 | 所有参数都是必选,没有则传入nil
35 |
36 | url 请求的网址
37 | method 请求方法可以是get,post,put,delete等
38 | cookie 身份验证信息
39 | charset 内容编码
40 | header 请求头
41 | callback 回调函数
42 |
43 | 该函数返回的是一个HttpTask对象,
44 | 需要调用execute方法才可以执行,
45 | t=Http.HttpTask(xxx)
46 | t.execute{data}
47 |
48 | 注意调用的括号是花括号,内容可以是字符串或者byte数组,
49 | 使用这个形式可以自己封装异步上传函数》》
50 |
51 | 《《TrafficStats类》》
52 | 《《import "android.net.TrafficStats"
53 | getMobileRxBytes() --获取通过Mobile连接收到的字节总数,不包含WiFi
54 | getMobileRxPackets() --获取Mobile连接收到的数据包总数
55 | getMobileTxBytes() --Mobile发送的总字节数
56 | getMobileTxPackets() --Mobile发送的总数据包数
57 | getTotalRxBytes() --获取总的接受字节数,包含Mobile和WiFi等
58 | getTotalRxPackets() --总的接受数据包数,包含Mobile和WiFi等
59 | getTotalTxBytes() --总的发送字节数,包含Mobile和WiFi等
60 | getTotalTxPackets() --发送的总数据包数,包含Mobile和WiFi等
61 | getUidRxBytes(int uid) --获取某个网络UID的接受字节数
62 | getUidTxBytes(int uid) --获取某个网络UID的发送字节数
63 | --例:TrafficStats.getTotalRxBytes()》》
64 |
65 | 《《开启关闭WiFi》》
66 | 《《import "android.content.Context"
67 | wifi = activity.Context.getSystemService(Context.WIFI_SERVICE)
68 | wifi.setWifiEnabled(true)--关闭则false》》
69 |
70 | 《《断开网络》》
71 | 《《import "android.content.Context"
72 | wifi = activity.Context.getSystemService(Context.WIFI_SERVICE)
73 | wifi.disconnect()》》
74 |
75 |
76 |
77 | 《《WiFi是否打开》》
78 | 《《import "android.content.Context"
79 | wifi = activity.Context.getSystemService(Context.WIFI_SERVICE)
80 | wi = wifi.isWifiEnabled()》》
81 |
82 | 《《WiFi是否连接》》
83 | 《《connManager = activity.getSystemService(Context.CONNECTIVITY_SERVICE)
84 | mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
85 | if tostring(mWifi):find("none)") then
86 | --未连接
87 | else
88 | --连接
89 | end》》
90 |
91 | 《《数据网络是否连接》》
92 | 《《manager = activity.getSystemService(Context.CONNECTIVITY_SERVICE);
93 | gprs = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();
94 | if tostring(gprs)== "CONNECTED" then
95 | print"当前数据网络"
96 | end》》
97 |
98 |
99 | 《《获取WiFi信息》》
100 | 《《import "android.content.Context"
101 | wifi = activity.Context.getSystemService(Context.WIFI_SERVICE)
102 | wifi.getConfiguredNetworks()》》
103 |
104 |
105 |
106 | 《《获取WiFi状态》》
107 | 《《import "android.content.Context"
108 | wifi = activity.Context.getSystemService(Context.WIFI_SERVICE)
109 | print(wifi.getWifiState())》》
110 |
111 |
112 |
113 |
114 | 《《IP地址》》
115 | 《《--查看某网站IP地址
116 | address=InetAddress.getByName("www.10010.com");
117 |
118 | --查看本机IP地址
119 | address=InetAddress.getLocalHost();
120 |
121 | --查看IP地址
122 | wifi = activity.Context.getSystemService(Context.WIFI_SERVICE).getDhcpInfo()
123 | string.match(tostring(wifi),"ipaddr(.-)gate")》》
124 |
125 |
126 | 《《获取Dns》》
127 | 《《import "android.content.Context"
128 |
129 | --获取Dns1
130 | wifi = activity.Context.getSystemService(Context.WIFI_SERVICE).getDhcpInfo()
131 | print(string.match(tostring(wifi),"dns1 (.-) dns2"))
132 |
133 | --获取Dns2
134 | wifi = activity.Context.getSystemService(Context.WIFI_SERVICE).getDhcpInfo()
135 | dns2 = string.match(tostring(wifi),"dns2 (.-) D")》》
136 |
137 |
138 |
139 |
140 | 《《获取网络名称》》
141 | 《《wifiManager=activity.Context.getSystemService(Context.WIFI_SERVICE);
142 | wifiInfo=wifiManager.getConnectionInfo();
143 | print(wifiInfo.getSSID())》》
144 |
145 |
146 | 《《获取WiFi加密类型》》
147 | 《《wifi = activity.Context.getSystemService(Context.WIFI_SERVICE).getConfiguredNetworks()
148 | print(string.match(tostring(wifi),[[KeyMgmt: (.-) P]]))》》
149 |
150 |
151 | 《《获取网络信号强度》》
152 | 《《wifiManager=activity.Context.getSystemService(Context.WIFI_SERVICE);
153 | wifiInfo=wifiManager.getConnectionInfo();
154 | print(wifiInfo.getRssi())》》
155 |
156 | 《《获取SSID是否被隐藏》》
157 | 《《wifiManager=activity.Context.getSystemService(Context.WIFI_SERVICE);
158 | wifiInfo=wifiManager.getConnectionInfo();
159 | print(wifiInfo.getHiddenSSID())》》
160 |
161 |
162 | 《《获取Mac地址》》
163 | 《《wifiManager=activity.Context.getSystemService(Context.WIFI_SERVICE);
164 | wifiInfo=wifiManager.getConnectionInfo();
165 | print( wifiInfo.getMacAddress())》》
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/CodeActivity.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.content.ClipboardManager;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.content.SharedPreferences;
7 | import android.os.Bundle;
8 | import android.preference.PreferenceManager;
9 | import android.support.design.widget.Snackbar;
10 | import android.support.v7.app.ActionBar;
11 | import android.view.Menu;
12 | import android.view.MenuItem;
13 |
14 | import com.sf.LuaEditor.CodeEditText;
15 |
16 |
17 | public class CodeActivity extends MySwipeBackActivity {
18 |
19 | private Context context;
20 | private CodeEditText editor;
21 | private String title;
22 | private String content;
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 | SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
27 | if (sp.getBoolean("nightMode", false)) {
28 | setTheme(R.style.DarkAppTheme);
29 | }
30 | super.onCreate(savedInstanceState);
31 | context = this;
32 | setContentView(R.layout.activity_code);
33 | Intent intent = getIntent();
34 | title = intent.getStringExtra("title");
35 | content = intent.getStringExtra("content");
36 |
37 | ActionBar actionBar = getSupportActionBar();
38 | actionBar.setTitle(title);
39 | actionBar.setDisplayHomeAsUpEnabled(true);
40 |
41 | editor = (CodeEditText) findViewById(R.id.edit_code);
42 | if (sp.getBoolean("autoFormat", true)) {
43 | editor.setText(editor.format(content));
44 | } else {
45 | editor.setText(content);
46 | }
47 | }
48 |
49 | @Override
50 | public boolean onCreateOptionsMenu(Menu menu) {
51 | menu.add("复制").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
52 | @Override
53 | public boolean onMenuItemClick(MenuItem item) {
54 | ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
55 | cmb.setText(title + "\n" + content);
56 | Snackbar.make(editor, "已复制全部内容", Snackbar.LENGTH_SHORT).setAction("确定", null).show();
57 | return true;
58 | }
59 | });
60 | menu.add("分享").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
61 | @Override
62 | public boolean onMenuItemClick(MenuItem item) {
63 | Intent intent = new Intent(Intent.ACTION_SEND);
64 | intent.setType("text/plain");
65 | intent.putExtra(Intent.EXTRA_TEXT, title + "\n" + content);
66 | context.startActivity(Intent.createChooser(intent, "分享"));
67 | return true;
68 | }
69 | });
70 | return true;
71 | }
72 |
73 | public static void actionStart(Context context, String title, String content) {
74 | Intent intent = new Intent(context, CodeActivity.class);
75 | intent.putExtra("title", title);
76 | intent.putExtra("content", content);
77 | context.startActivity(intent);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/DataManager.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.content.Context;
4 |
5 | import java.io.InputStream;
6 | import java.util.ArrayList;
7 | import java.util.List;
8 | import java.util.regex.Matcher;
9 | import java.util.regex.Pattern;
10 |
11 | /**
12 | * Created by user on 2017/7/22.
13 | */
14 |
15 | public class DataManager {
16 |
17 | public static String[] fileArray = {"Lua教程.txt", "AndroLua帮助.txt", "实用代码.txt", "网络操作.txt", "文件操作.txt", "用户界面.txt", "基础代码.txt", "Intent类.txt", "笔记.txt"};
18 |
19 | public static List getData(Context context, String[] fileArray) {
20 | StringBuffer sb = new StringBuffer();
21 |
22 | for (String name : fileArray) {
23 | String str = "";
24 | try {
25 | InputStream in = context.getResources().getAssets().open(name);
26 | byte[] buffer = new byte[in.available()];
27 | in.read(buffer);
28 | str = new String(buffer, "utf8");
29 | } catch (Exception e) {
30 | ExceptionsHandle.show(context, e.toString());
31 | continue;
32 | }
33 | sb.append(str);
34 | }
35 |
36 | List list = new ArrayList<>();
37 | Pattern pattern = Pattern.compile("《《(.*?)》》", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
38 | Matcher matcher = pattern.matcher(sb.toString());
39 | while (matcher.find()) {
40 | try {
41 | String title = matcher.group(1);
42 | matcher.find();
43 | String content = matcher.group(1);
44 | Data data = new Data(title, content);
45 | list.add(data);
46 | } catch (Exception e) {
47 | ExceptionsHandle.show(context, e.toString());
48 | continue;
49 | }
50 | }
51 | return list;
52 | }
53 |
54 | public static List getAll(Context context) {
55 | return getData(context, fileArray);
56 | }
57 | }
58 |
59 | class Data {
60 | String title;
61 | String content;
62 |
63 | public Data(String title, String content) {
64 | this.title = title;
65 | this.content = content;
66 | }
67 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/ExceptionsHandle.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.content.Context;
4 | import android.content.DialogInterface;
5 | import android.support.v7.app.AlertDialog;
6 |
7 | /**
8 | * Created by user on 2017/7/21.
9 | */
10 |
11 | public class ExceptionsHandle {
12 | public static void show(Context context, String error) {
13 | AlertDialog.Builder builder = new AlertDialog.Builder(context);
14 | builder.setTitle("程序抛出异常");
15 | builder.setMessage(error + "\n\n请截图发送给开发者");
16 | builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
17 | @Override
18 | public void onClick(DialogInterface dialog, int which) {
19 | dialog.dismiss();
20 | }
21 | });
22 | builder.create().show();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.SharedPreferences;
6 | import android.os.Bundle;
7 | import android.preference.PreferenceManager;
8 | import android.support.design.widget.FloatingActionButton;
9 | import android.support.design.widget.TabLayout;
10 | import android.support.v4.view.ViewPager;
11 | import android.support.v4.widget.SwipeRefreshLayout;
12 | import android.support.v7.app.AppCompatActivity;
13 | import android.support.v7.widget.LinearLayoutManager;
14 | import android.support.v7.widget.RecyclerView;
15 | import android.support.v7.widget.StaggeredGridLayoutManager;
16 | import android.support.v7.widget.Toolbar;
17 | import android.support.v7.widget.helper.ItemTouchHelper;
18 | import android.view.LayoutInflater;
19 | import android.view.View;
20 | import android.view.Menu;
21 | import android.view.MenuItem;
22 |
23 | import java.util.ArrayList;
24 | import java.util.Collections;
25 | import java.util.List;
26 |
27 | public class MainActivity extends AppCompatActivity {
28 |
29 | private View page1;
30 | private View page2;
31 | private List pageList;
32 | private MainPagerAdapter pagerAdapter;
33 | private ViewPager viewPager;
34 | private SwipeRefreshLayout swipeRefresh;
35 | private SharedPreferences sp;
36 | public static AppCompatActivity context;
37 |
38 | @Override
39 | protected void onCreate(Bundle savedInstanceState) {
40 | sp = PreferenceManager.getDefaultSharedPreferences(this);
41 | if (sp.getBoolean("nightMode", false)) {
42 | setTheme(R.style.DarkAppTheme_NoActionBar);
43 | }
44 | super.onCreate(savedInstanceState);
45 | context = this;
46 | setContentView(R.layout.activity_main);
47 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
48 | if (!sp.getBoolean("nightMode", false)) {
49 | toolbar.setPopupTheme(R.style.AppTheme_PopupOverlay);
50 | }
51 | setSupportActionBar(toolbar);
52 |
53 | FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab_main);
54 | fab.setOnClickListener(new View.OnClickListener() {
55 | @Override
56 | public void onClick(View view) {
57 | SearchActivity.actionStart(view.getContext());
58 | }
59 | });
60 | initSwipeRefresh();
61 | initPages();
62 | initTabs();
63 | initRecyclerView();
64 | }
65 |
66 | private void initSwipeRefresh() {
67 | swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.swipeRefresh);
68 | if (sp.getBoolean("nightMode", false)) {
69 | swipeRefresh.setColorSchemeResources(R.color.darkColorAccent);
70 | } else {
71 | swipeRefresh.setColorSchemeResources(R.color.colorPrimary);
72 | }
73 | swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
74 | @Override
75 | public void onRefresh() {
76 | swipeRefresh.setRefreshing(false);
77 | }
78 | });
79 | }
80 |
81 | private void initTabs() {
82 | TabLayout tabs = (TabLayout) findViewById(R.id.main_tabs);
83 | tabs.setupWithViewPager(viewPager);
84 | tabs.getTabAt(0).setText("教程");
85 | tabs.getTabAt(1).setText("更多");
86 | }
87 |
88 | private void initRecyclerView() {
89 | RecyclerView recyclerView1 = (RecyclerView) page1.findViewById(R.id.page1_rv);
90 | LinearLayoutManager layoutManager1 = new LinearLayoutManager(this);
91 | recyclerView1.setLayoutManager(layoutManager1);
92 | String[] fileArray1 = {"Lua教程.txt"};
93 | RecyclerAdapter adapter1 = new RecyclerAdapter(R.layout.page1_item, DataManager.getData(this, fileArray1));
94 | recyclerView1.setAdapter(adapter1);
95 |
96 | final RecyclerView recyclerView2 = (RecyclerView) page2.findViewById(R.id.page2_rv);
97 | StaggeredGridLayoutManager layoutManager2 = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
98 | recyclerView2.setLayoutManager(layoutManager2);
99 | final RecyclerAdapter adapter2 = new RecyclerAdapter(R.layout.page2_item, getPageData());
100 | recyclerView2.setAdapter(adapter2);
101 |
102 | final ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
103 | @Override
104 | public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
105 | final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN |
106 | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
107 | final int swipeFlags = 0;
108 | return makeMovementFlags(dragFlags, swipeFlags);
109 | }
110 |
111 | @Override
112 | public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
113 | //得到当拖拽的viewHolder的Position
114 | int fromPosition = viewHolder.getAdapterPosition();
115 | //拿到当前拖拽到的item的viewHolder
116 | int toPosition = target.getAdapterPosition();
117 | if (fromPosition < toPosition) {
118 | for (int i = fromPosition; i < toPosition; i++) {
119 | Collections.swap(adapter2.getList(), i, i + 1);
120 | }
121 | } else {
122 | for (int i = fromPosition; i > toPosition; i--) {
123 | Collections.swap(adapter2.getList(), i, i - 1);
124 | }
125 | }
126 | adapter2.notifyItemMoved(fromPosition, toPosition);
127 | return true;
128 | }
129 |
130 | @Override
131 | public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
132 |
133 | }
134 | });
135 |
136 | itemTouchHelper.attachToRecyclerView(recyclerView2);
137 | }
138 |
139 | private List getPageData() {
140 | List list = new ArrayList<>();
141 | list.add(new Data("Lua参考手册", "———菜鸟教程提供"));
142 | list.add(new Data("AndroLua帮助", "———nirenr提供"));
143 | list.add(new Data("实用代码", "———寒歌提供"));
144 | list.add(new Data("网络操作", "———寒歌提供"));
145 | list.add(new Data("文件操作", "———寒歌提供"));
146 | list.add(new Data("用户界面", "———寒歌提供"));
147 | list.add(new Data("基础代码", "———寒歌提供"));
148 | list.add(new Data("Intent类", "———寒歌提供"));
149 | list.add(new Data("笔记", "———烧风提供"));
150 | return list;
151 | }
152 |
153 | private void initPages() {
154 | LayoutInflater inflater = getLayoutInflater();
155 | page1 = inflater.inflate(R.layout.page1, null);
156 | page2 = inflater.inflate(R.layout.page2, null);
157 | pageList = new ArrayList<>();
158 | pageList.add(page1);
159 | pageList.add(page2);
160 |
161 | viewPager = (ViewPager) findViewById(R.id.mViewPager);
162 | pagerAdapter = new MainPagerAdapter(pageList);
163 | viewPager.setAdapter(pagerAdapter);
164 | }
165 |
166 | @Override
167 | public boolean onCreateOptionsMenu(Menu menu) {
168 | getMenuInflater().inflate(R.menu.menu_main, menu);
169 | return true;
170 | }
171 |
172 | @Override
173 | public boolean onOptionsItemSelected(MenuItem item) {
174 | switch (item.getItemId()) {
175 | case R.id.action_settings:
176 | SettingsActivity.actionStart(this);
177 | break;
178 | case R.id.action_finish:
179 | finish();
180 | break;
181 | }
182 | return true;
183 | }
184 |
185 | public static void actionStart(Context context) {
186 | Intent intent = new Intent(context, MainActivity.class);
187 | context.startActivity(intent);
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/MainPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.support.v4.view.PagerAdapter;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import android.widget.GridView;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * Created by user on 2017/7/19.
12 | */
13 |
14 | public class MainPagerAdapter extends PagerAdapter {
15 | private List pageList;
16 |
17 | @Override
18 | public boolean isViewFromObject(View view, Object object) {
19 | return view == object;
20 | }
21 |
22 | public MainPagerAdapter(List pageList) {
23 | super();
24 | this.pageList = pageList;
25 | }
26 |
27 | @Override
28 | public int getCount() {
29 | return pageList.size();
30 | }
31 |
32 | @Override
33 | public Object instantiateItem(ViewGroup container, int position) {
34 | View view = pageList.get(position);
35 | container.addView(view);
36 | return view;
37 | }
38 |
39 | @Override
40 | public void destroyItem(ViewGroup container, int position, Object object) {
41 | container.removeView(pageList.get(position));
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/MyPreferenceActivity.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.content.res.Configuration;
4 | import android.os.Bundle;
5 | import android.preference.PreferenceActivity;
6 | import android.support.v7.app.ActionBar;
7 | import android.support.v7.app.AppCompatDelegate;
8 | import android.view.KeyEvent;
9 | import android.view.MenuInflater;
10 | import android.view.MenuItem;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 |
14 | import me.imid.swipebacklayout.lib.SwipeBackLayout;
15 | import me.imid.swipebacklayout.lib.Utils;
16 | import me.imid.swipebacklayout.lib.app.SwipeBackActivityBase;
17 | import me.imid.swipebacklayout.lib.app.SwipeBackActivityHelper;
18 |
19 | public abstract class MyPreferenceActivity extends PreferenceActivity implements SwipeBackActivityBase {
20 |
21 | private AppCompatDelegate mDelegate;
22 | private SwipeBackActivityHelper mHelper;
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 | getDelegate().installViewFactory();
27 | getDelegate().onCreate(savedInstanceState);
28 | super.onCreate(savedInstanceState);
29 | mHelper = new SwipeBackActivityHelper(this);
30 | mHelper.onActivityCreate();
31 | setupActionBar();
32 | }
33 |
34 | @Override
35 | protected void onPostCreate(Bundle savedInstanceState) {
36 | super.onPostCreate(savedInstanceState);
37 | mHelper.onPostCreate();
38 | getDelegate().onPostCreate(savedInstanceState);
39 | }
40 |
41 | public ActionBar getSupportActionBar() {
42 | return getDelegate().getSupportActionBar();
43 | }
44 |
45 | @Override
46 | public MenuInflater getMenuInflater() {
47 | return getDelegate().getMenuInflater();
48 | }
49 |
50 | @Override
51 | public void setContentView(int layoutResID) {
52 | getDelegate().setContentView(layoutResID);
53 | }
54 |
55 | @Override
56 | public void setContentView(View view) {
57 | getDelegate().setContentView(view);
58 | }
59 |
60 | @Override
61 | public void setContentView(View view, ViewGroup.LayoutParams params) {
62 | getDelegate().setContentView(view, params);
63 | }
64 |
65 | @Override
66 | public void addContentView(View view, ViewGroup.LayoutParams params) {
67 | getDelegate().addContentView(view, params);
68 | }
69 |
70 | @Override
71 | protected void onPostResume() {
72 | super.onPostResume();
73 | getDelegate().onPostResume();
74 | }
75 |
76 | @Override
77 | protected void onTitleChanged(CharSequence title, int color) {
78 | super.onTitleChanged(title, color);
79 | getDelegate().setTitle(title);
80 | }
81 |
82 | @Override
83 | public void onConfigurationChanged(Configuration newConfig) {
84 | super.onConfigurationChanged(newConfig);
85 | getDelegate().onConfigurationChanged(newConfig);
86 | }
87 |
88 | @Override
89 | protected void onStop() {
90 | super.onStop();
91 | getDelegate().onStop();
92 | }
93 |
94 | @Override
95 | protected void onDestroy() {
96 | super.onDestroy();
97 | getDelegate().onDestroy();
98 | }
99 |
100 | public void invalidateOptionsMenu() {
101 | getDelegate().invalidateOptionsMenu();
102 | }
103 |
104 | private AppCompatDelegate getDelegate() {
105 | if (mDelegate == null) {
106 | mDelegate = AppCompatDelegate.create(this, null);
107 | }
108 | return mDelegate;
109 | }
110 |
111 | private void setupActionBar() {
112 | ActionBar actionBar = getSupportActionBar();
113 | actionBar.setDisplayHomeAsUpEnabled(true);
114 | }
115 |
116 | public boolean onOptionsItemSelected(MenuItem item) {
117 | switch (item.getItemId()) {
118 | case android.R.id.home:
119 | scrollToFinishActivity();
120 | break;
121 | }
122 | return true;
123 | }
124 |
125 |
126 | @Override
127 | public View findViewById(int id) {
128 | View v = super.findViewById(id);
129 | if (v == null && mHelper != null) return mHelper.findViewById(id);
130 | return v;
131 | }
132 |
133 | @Override
134 | public SwipeBackLayout getSwipeBackLayout() {
135 | return mHelper.getSwipeBackLayout();
136 | }
137 |
138 | @Override
139 | public void setSwipeBackEnable(boolean enable) {
140 | getSwipeBackLayout().setEnableGesture(enable);
141 | }
142 |
143 | @Override
144 | public void scrollToFinishActivity() {
145 | Utils.convertActivityToTranslucent(this);
146 | getSwipeBackLayout().scrollToFinishActivity();
147 | }
148 |
149 | public boolean onKeyUp(int keyCode, KeyEvent event) {
150 | if (keyCode == KeyEvent.KEYCODE_BACK) {
151 | scrollToFinishActivity();
152 | }
153 | return false;
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/MySwipeBackActivity.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.os.Bundle;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.view.KeyEvent;
6 | import android.view.MenuItem;
7 | import android.view.View;
8 |
9 | import me.imid.swipebacklayout.lib.SwipeBackLayout;
10 | import me.imid.swipebacklayout.lib.Utils;
11 | import me.imid.swipebacklayout.lib.app.SwipeBackActivityBase;
12 | import me.imid.swipebacklayout.lib.app.SwipeBackActivityHelper;
13 |
14 | /**
15 | * Created by user on 2017/7/21.
16 | */
17 |
18 | public class MySwipeBackActivity extends AppCompatActivity implements SwipeBackActivityBase {
19 | private SwipeBackActivityHelper mHelper;
20 |
21 | @Override
22 | protected void onCreate(Bundle savedInstanceState) {
23 | super.onCreate(savedInstanceState);
24 | mHelper = new SwipeBackActivityHelper(this);
25 | mHelper.onActivityCreate();
26 | }
27 |
28 | public boolean onOptionsItemSelected(MenuItem item) {
29 | switch (item.getItemId()) {
30 | case android.R.id.home:
31 | scrollToFinishActivity();
32 | break;
33 | }
34 | return true;
35 | }
36 |
37 | @Override
38 | protected void onPostCreate(Bundle savedInstanceState) {
39 | super.onPostCreate(savedInstanceState);
40 | mHelper.onPostCreate();
41 | }
42 |
43 | @Override
44 | public View findViewById(int id) {
45 | View v = super.findViewById(id);
46 | if (v == null && mHelper != null) return mHelper.findViewById(id);
47 | return v;
48 | }
49 |
50 | @Override
51 | public SwipeBackLayout getSwipeBackLayout() {
52 | return mHelper.getSwipeBackLayout();
53 | }
54 |
55 | @Override
56 | public void setSwipeBackEnable(boolean enable) {
57 | getSwipeBackLayout().setEnableGesture(enable);
58 | }
59 |
60 | @Override
61 | public void scrollToFinishActivity() {
62 | Utils.convertActivityToTranslucent(this);
63 | getSwipeBackLayout().scrollToFinishActivity();
64 | }
65 |
66 | public boolean onKeyUp(int keyCode, KeyEvent event) {
67 | if (keyCode == KeyEvent.KEYCODE_BACK) {
68 | scrollToFinishActivity();
69 | }
70 | return false;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/MySwipeRefreshLayout.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.content.Context;
4 | import android.support.v4.widget.SwipeRefreshLayout;
5 | import android.util.AttributeSet;
6 | import android.view.MotionEvent;
7 |
8 | /**
9 | * Created by user on 2017/7/21.
10 | */
11 |
12 | public class MySwipeRefreshLayout extends SwipeRefreshLayout {
13 |
14 | public MySwipeRefreshLayout(Context context, AttributeSet attrs) {
15 | super(context, attrs);
16 | }
17 |
18 | public boolean onInterceptTouchEvent(MotionEvent ev) {
19 | return false;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/PreviewActivity.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.content.ClipboardManager;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.content.SharedPreferences;
7 | import android.os.Bundle;
8 | import android.preference.PreferenceManager;
9 | import android.support.design.widget.Snackbar;
10 | import android.support.v7.app.ActionBar;
11 | import android.view.Menu;
12 | import android.view.MenuItem;
13 |
14 | import com.sf.LuaEditor.CodeEditText;
15 | import com.sf.LuaEditor.ShaderEditor;
16 |
17 |
18 | public class PreviewActivity extends MySwipeBackActivity {
19 |
20 | private Context context;
21 | private String text;
22 | private String title;
23 | private ShaderEditor content;
24 |
25 | @Override
26 | protected void onCreate(Bundle savedInstanceState) {
27 | SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
28 | if (sp.getBoolean("nightMode", false)) {
29 | setTheme(R.style.DarkAppTheme);
30 | }
31 | super.onCreate(savedInstanceState);
32 | context = this;
33 | setContentView(R.layout.activity_preview);
34 | setupActionBar();
35 | content = (ShaderEditor) findViewById(R.id.content_preview);
36 | Intent intent = getIntent();
37 | title = intent.getStringExtra("title");
38 | setTitle(title);
39 | text = intent.getStringExtra("content");
40 |
41 | if (sp.getBoolean("autoFormat", true)) {
42 | content.setText(content.format(text));
43 | } else {
44 | content.setText(text);
45 | }
46 | }
47 |
48 | @Override
49 | public boolean onCreateOptionsMenu(Menu menu) {
50 | menu.add("复制").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
51 | @Override
52 | public boolean onMenuItemClick(MenuItem item) {
53 | ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
54 | cmb.setText(title + "\n" + text);
55 | Snackbar.make(content, "已复制全部内容", Snackbar.LENGTH_SHORT).setAction("确定", null).show();
56 | return true;
57 | }
58 | });
59 | menu.add("分享").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
60 | @Override
61 | public boolean onMenuItemClick(MenuItem item) {
62 | Intent intent = new Intent(Intent.ACTION_SEND);
63 | intent.setType("text/plain");
64 | intent.putExtra(Intent.EXTRA_TEXT, title + "\n" + text);
65 | context.startActivity(Intent.createChooser(intent, "分享"));
66 | return true;
67 | }
68 | });
69 | return true;
70 | }
71 |
72 | private void setupActionBar() {
73 | ActionBar actionBar = getSupportActionBar();
74 | actionBar.setDisplayHomeAsUpEnabled(true);
75 | }
76 |
77 | public static void actionStart(Context context, String title, String content) {
78 | Intent intent = new Intent(context, PreviewActivity.class);
79 | intent.putExtra("title", title);
80 | intent.putExtra("content", content);
81 | context.startActivity(intent);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/RecyclerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.content.ClipboardManager;
4 | import android.content.Context;
5 | import android.content.DialogInterface;
6 | import android.content.Intent;
7 | import android.content.SharedPreferences;
8 | import android.graphics.Color;
9 | import android.preference.PreferenceManager;
10 | import android.support.design.widget.Snackbar;
11 | import android.support.v7.app.AlertDialog;
12 | import android.support.v7.widget.CardView;
13 | import android.support.v7.widget.RecyclerView;
14 | import android.view.LayoutInflater;
15 | import android.view.View;
16 | import android.view.ViewGroup;
17 | import android.widget.ImageView;
18 | import android.widget.TextView;
19 |
20 | import java.util.List;
21 |
22 | /**
23 | * Created by user on 2017/7/19.
24 | */
25 |
26 | public class RecyclerAdapter extends RecyclerView.Adapter {
27 |
28 | private List list;
29 | private int layoutId;
30 |
31 | static class ViewHolder extends RecyclerView.ViewHolder {
32 | private TextView title;
33 | private TextView content;
34 | private CardView cardView;
35 |
36 | public ViewHolder(View v, int layoutId) {
37 | super(v);
38 | cardView = (CardView) v.findViewById(R.id.cardview);
39 | title = (TextView) v.findViewById(R.id.title);
40 | content = (TextView) v.findViewById(R.id.content);
41 | SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(v.getContext());
42 | Boolean nightMode = sp.getBoolean("nightMode", false);
43 | if (nightMode) {
44 | View line = v.findViewById(R.id.lineView);
45 | line.setBackgroundColor(Color.parseColor("#616161"));
46 | title.setTextColor(Color.parseColor("#f5f5f5"));
47 | content.setTextColor(Color.parseColor("#e0e0e0"));
48 | }
49 |
50 | if (layoutId == R.layout.page2_item) {
51 | ImageView image = (ImageView) v.findViewById(R.id.image);
52 | if (nightMode) {
53 | image.setColorFilter(Color.parseColor("#e0e0e0"));
54 | } else {
55 | image.setColorFilter(Color.parseColor("#424242"));
56 | }
57 | }
58 | }
59 | }
60 |
61 | public List getList() {
62 | return list;
63 | }
64 |
65 | public RecyclerAdapter(int layoutId, List list) {
66 | this.list = list;
67 | this.layoutId = layoutId;
68 | }
69 |
70 | @Override
71 | public int getItemCount() {
72 | return list.size();
73 | }
74 |
75 | @Override
76 | public void onBindViewHolder(final ViewHolder holder, int position) {
77 | final Data data = list.get(position);
78 | holder.title.setText(data.title);
79 | holder.content.setText(data.content);
80 |
81 | if (layoutId == R.layout.page1_item) {
82 | holder.cardView.setOnClickListener(new View.OnClickListener() {
83 | @Override
84 | public void onClick(View v) {
85 | PreviewActivity.actionStart(v.getContext(), data.title, data.content);
86 | }
87 | });
88 | holder.cardView.setOnLongClickListener(new View.OnLongClickListener() {
89 | @Override
90 | public boolean onLongClick(View v) {
91 | showListDialog(v, data);
92 | return false;
93 | }
94 | });
95 | } else {
96 | holder.cardView.setOnClickListener(new View.OnClickListener() {
97 | @Override
98 | public void onClick(View v) {
99 | if (data.title.equals("Lua参考手册")) {
100 | WebViewActivity.actionStart(v.getContext(),"file:///android_asset/LuaManual/manual.html");
101 | return;
102 | }
103 | ShowActivity.actionStart(v.getContext(), data.title);
104 | }
105 | });
106 | }
107 | }
108 |
109 | private void showListDialog(final View view, final Data data) {
110 | final String[] items = {"复制全部内容", "分享全部内容"};
111 | AlertDialog.Builder listDialog = new AlertDialog.Builder(view.getContext());
112 | listDialog.setTitle("选择操作");
113 | listDialog.setItems(items, new DialogInterface.OnClickListener() {
114 | @Override
115 | public void onClick(DialogInterface dialog, int which) {
116 | switch (which) {
117 | case 0:
118 | ClipboardManager cmb = (ClipboardManager) view.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
119 | cmb.setText(data.title + "\n" + data.content);
120 | Snackbar.make(view, "已复制全部内容", Snackbar.LENGTH_SHORT).setAction("确定", null).show();
121 | break;
122 | case 1:
123 | Intent intent = new Intent(Intent.ACTION_SEND);
124 | intent.setType("text/plain");
125 | intent.putExtra(Intent.EXTRA_TEXT, data.title + "\n" + data.content);
126 | view.getContext().startActivity(Intent.createChooser(intent, "分享"));
127 | break;
128 | }
129 | }
130 | });
131 | listDialog.show();
132 | }
133 |
134 | @Override
135 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
136 | View view = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
137 | ViewHolder holder = new ViewHolder(view, layoutId);
138 | return holder;
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/ScrollingFABBehavior.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.content.Context;
4 | import android.support.design.widget.AppBarLayout;
5 | import android.support.design.widget.CoordinatorLayout;
6 | import android.support.design.widget.FloatingActionButton;
7 | import android.support.v7.widget.Toolbar;
8 | import android.util.AttributeSet;
9 | import android.view.View;
10 |
11 |
12 | /**
13 | * Created by user on 2017/7/21.
14 | */
15 |
16 | public class ScrollingFABBehavior extends CoordinatorLayout.Behavior {
17 | private int toolBarHeight = 0;
18 |
19 | public ScrollingFABBehavior(Context context, AttributeSet attrs) {
20 | super(context, attrs);
21 | }
22 |
23 | @Override
24 | public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton fab, View dependency) {
25 | return dependency instanceof AppBarLayout;
26 | }
27 |
28 | @Override
29 | public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton fab, View dependency) {
30 | if (toolBarHeight == 0) {
31 | Toolbar toolbar = (Toolbar) parent.findViewById(R.id.toolbar);
32 | toolBarHeight = toolbar.getHeight();
33 | }
34 |
35 | if (dependency instanceof AppBarLayout) {
36 | CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
37 | int fabBottomMargin = lp.bottomMargin;
38 | int distanceToScroll = fab.getHeight() + fabBottomMargin;
39 | float ty = dependency.getY();
40 | float ratio = ty / (float) toolBarHeight;
41 | fab.setTranslationY(-distanceToScroll * ratio);
42 | }
43 | return true;
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/SearchActivity.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.SharedPreferences;
6 | import android.preference.PreferenceManager;
7 | import android.support.design.widget.FloatingActionButton;
8 | import android.os.Bundle;
9 | import android.support.v7.app.ActionBar;
10 | import android.support.v7.widget.LinearLayoutManager;
11 | import android.support.v7.widget.RecyclerView;
12 | import android.support.v7.widget.Toolbar;
13 | import android.text.Editable;
14 | import android.text.TextWatcher;
15 | import android.view.KeyEvent;
16 | import android.view.View;
17 | import android.widget.EditText;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 | import java.util.regex.Pattern;
22 |
23 |
24 | public class SearchActivity extends MySwipeBackActivity {
25 |
26 | private SearchAdapter adapter;
27 | private RecyclerView recyclerView;
28 | private List data;
29 |
30 | @Override
31 | protected void onCreate(Bundle savedInstanceState) {
32 | SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
33 | if (sp.getBoolean("nightMode", false)) {
34 | setTheme(R.style.DarkAppTheme_Translucent);
35 | }
36 | super.onCreate(savedInstanceState);
37 | setContentView(R.layout.activity_search);
38 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
39 | setSupportActionBar(toolbar);
40 | ActionBar actionBar = getSupportActionBar();
41 | actionBar.setDisplayHomeAsUpEnabled(true);
42 |
43 | FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab_search);
44 | fab.setOnClickListener(new View.OnClickListener() {
45 | @Override
46 | public void onClick(View view) {
47 | scrollToFinishActivity();
48 | }
49 | });
50 | data = DataManager.getAll(this);
51 | initRecyclerView();
52 | initEditText();
53 | }
54 |
55 | private void initEditText() {
56 | EditText search = (EditText) findViewById(R.id.edit_search);
57 | search.addTextChangedListener(new TextWatcher() {
58 | @Override
59 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
60 | }
61 |
62 | @Override
63 | public void onTextChanged(CharSequence s, int start, int before, int count) {
64 | if (s.toString().equals("")) {
65 | adapter.removeAll();
66 | adapter.notifyDataSetChanged();
67 | } else {
68 | List dataList = new ArrayList<>();
69 | Pattern p = Pattern.compile(s.toString());
70 | for (Data d : data) {
71 | String title = d.title;
72 | String content = d.content;
73 | if (p.matcher(title).find() || p.matcher(content).find()) {
74 | dataList.add(d);
75 | }
76 | }
77 | adapter.setData(dataList);
78 | }
79 | }
80 |
81 | @Override
82 | public void afterTextChanged(Editable s) {
83 | }
84 | });
85 | }
86 |
87 | private void initRecyclerView() {
88 | recyclerView = (RecyclerView) findViewById(R.id.search_rv);
89 | LinearLayoutManager layoutManager = new LinearLayoutManager(this);
90 | recyclerView.setLayoutManager(layoutManager);
91 | adapter = new SearchAdapter();
92 | recyclerView.setAdapter(adapter);
93 | }
94 |
95 | public static void actionStart(Context context) {
96 | Intent intent = new Intent(context, SearchActivity.class);
97 | context.startActivity(intent);
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/SearchAdapter.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.content.ClipboardManager;
4 | import android.content.Context;
5 | import android.content.DialogInterface;
6 | import android.content.Intent;
7 | import android.content.SharedPreferences;
8 | import android.graphics.Color;
9 | import android.preference.PreferenceManager;
10 | import android.support.design.widget.Snackbar;
11 | import android.support.v7.app.AlertDialog;
12 | import android.support.v7.widget.CardView;
13 | import android.support.v7.widget.RecyclerView;
14 | import android.view.LayoutInflater;
15 | import android.view.View;
16 | import android.view.ViewGroup;
17 | import android.widget.TextView;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 | /**
23 | * Created by user on 2017/7/22.
24 | */
25 |
26 | public class SearchAdapter extends RecyclerView.Adapter {
27 | private List list = new ArrayList<>();
28 |
29 | static class ViewHolder extends RecyclerView.ViewHolder {
30 | private TextView title;
31 | private TextView content;
32 | private CardView cardView;
33 |
34 | public ViewHolder(View v) {
35 | super(v);
36 | cardView = (CardView) v.findViewById(R.id.search_cardview);
37 | title = (TextView) v.findViewById(R.id.search_title);
38 | content = (TextView) v.findViewById(R.id.search_content);
39 | SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(v.getContext());
40 | Boolean nightMode = sp.getBoolean("nightMode", false);
41 | if (nightMode) {
42 | View line = v.findViewById(R.id.lineView);
43 | line.setBackgroundColor(Color.parseColor("#616161"));
44 | title.setTextColor(Color.parseColor("#f5f5f5"));
45 | content.setTextColor(Color.parseColor("#e0e0e0"));
46 | }
47 | }
48 | }
49 |
50 | public void removeAll() {
51 | list.clear();
52 | notifyDataSetChanged();
53 | }
54 |
55 | public void setData(List list) {
56 | this.list = list;
57 | notifyDataSetChanged();
58 | }
59 |
60 | @Override
61 | public int getItemCount() {
62 | return list.size();
63 | }
64 |
65 | @Override
66 | public void onBindViewHolder(final SearchAdapter.ViewHolder holder, int position) {
67 | final Data data = list.get(position);
68 | holder.title.setText(data.title);
69 | holder.content.setText(data.content);
70 | holder.cardView.setOnClickListener(new View.OnClickListener() {
71 | @Override
72 | public void onClick(View v) {
73 | CodeActivity.actionStart(v.getContext(), data.title, data.content);
74 | }
75 | });
76 | holder.cardView.setOnLongClickListener(new View.OnLongClickListener() {
77 | @Override
78 | public boolean onLongClick(View v) {
79 | showListDialog(v, data);
80 | return false;
81 | }
82 | });
83 | }
84 |
85 | private void showListDialog(final View view, final Data data) {
86 | final String[] items = {"复制全部内容", "分享全部内容"};
87 | AlertDialog.Builder listDialog = new AlertDialog.Builder(view.getContext());
88 | listDialog.setTitle("选择操作");
89 | listDialog.setItems(items, new DialogInterface.OnClickListener() {
90 | @Override
91 | public void onClick(DialogInterface dialog, int which) {
92 | switch (which) {
93 | case 0:
94 | ClipboardManager cmb = (ClipboardManager) view.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
95 | cmb.setText(data.title + "\n" + data.content);
96 | Snackbar.make(view, "已复制全部内容", Snackbar.LENGTH_SHORT).setAction("确定", null).show();
97 | break;
98 | case 1:
99 | Intent intent = new Intent(Intent.ACTION_SEND);
100 | intent.setType("text/plain");
101 | intent.putExtra(Intent.EXTRA_TEXT, data.title + "\n" + data.content);
102 | view.getContext().startActivity(Intent.createChooser(intent, "分享"));
103 | break;
104 | }
105 | }
106 | });
107 | listDialog.show();
108 | }
109 |
110 | @Override
111 | public SearchAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
112 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.search_item, parent, false);
113 | SearchAdapter.ViewHolder holder = new SearchAdapter.ViewHolder(view);
114 | return holder;
115 | }
116 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/SettingsActivity.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 |
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.content.SharedPreferences;
7 | import android.os.Bundle;
8 | import android.preference.EditTextPreference;
9 | import android.preference.Preference;
10 | import android.preference.PreferenceManager;
11 | import android.preference.SwitchPreference;
12 | import android.widget.Toast;
13 |
14 |
15 | public class SettingsActivity extends MyPreferenceActivity {
16 |
17 | private SwitchPreference nightMode;
18 | private SwitchPreference heightLight;
19 | private EditTextPreference delay;
20 | private Context context;
21 |
22 | @Override
23 | protected void onCreate(Bundle savedInstanceState) {
24 | SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
25 | if (sp.getBoolean("nightMode", false)) {
26 | setTheme(R.style.DarkAppTheme);
27 | }
28 | super.onCreate(savedInstanceState);
29 | context = this;
30 | addPreferencesFromResource(R.xml.pref_main);
31 | initPreference();
32 |
33 | delay.setEnabled(sp.getBoolean("heightLight", false));
34 | delay.setSummary(sp.getString("delay", "10") + " 毫秒");
35 | }
36 |
37 | private void initPreference() {
38 | nightMode = (SwitchPreference) findPreference("nightMode");
39 | nightMode.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
40 | @Override
41 | public boolean onPreferenceChange(Preference preference, Object newValue) {
42 | finish();
43 | overridePendingTransition(0, 0);
44 | MainActivity.context.finish();
45 | MainActivity.actionStart(context);
46 | actionStart(context);
47 | overridePendingTransition(0, 0);
48 | return true;
49 | }
50 | });
51 | heightLight = (SwitchPreference) findPreference("heightLight");
52 | heightLight.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
53 | @Override
54 | public boolean onPreferenceChange(Preference preference, Object newValue) {
55 | delay.setEnabled((Boolean) newValue);
56 | return true;
57 | }
58 | });
59 | delay = (EditTextPreference) findPreference("delay");
60 | delay.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
61 | @Override
62 | public boolean onPreferenceChange(Preference preference, Object newValue) {
63 | if ((newValue + "").length() > 10) {
64 | Toast.makeText(delay.getContext(), "你输入的值太大", Toast.LENGTH_SHORT).show();
65 | return false;
66 | }
67 | delay.setSummary(newValue + " 毫秒");
68 | return true;
69 | }
70 | });
71 | }
72 |
73 | public static void actionStart(Context context) {
74 | Intent intent = new Intent(context, SettingsActivity.class);
75 | context.startActivity(intent);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/ShowActivity.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.SharedPreferences;
6 | import android.os.Bundle;
7 | import android.preference.PreferenceManager;
8 | import android.support.v7.app.ActionBar;
9 | import android.support.v7.widget.LinearLayoutManager;
10 | import android.support.v7.widget.RecyclerView;
11 | import android.support.v7.widget.Toolbar;
12 |
13 | public class ShowActivity extends MySwipeBackActivity {
14 |
15 | private ShowAdapter adapter;
16 | private RecyclerView recyclerView;
17 | private String title;
18 |
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
22 | if (sp.getBoolean("nightMode", false)) {
23 | setTheme(R.style.DarkAppTheme_SwipeBack);
24 | }
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_show);
27 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_show);
28 | setSupportActionBar(toolbar);
29 | Intent intent = getIntent();
30 | title = intent.getStringExtra("name");
31 | ActionBar actionBar = getSupportActionBar();
32 | actionBar.setTitle(title);
33 | actionBar.setDisplayHomeAsUpEnabled(true);
34 | initRecyclerView();
35 | }
36 |
37 | private void initRecyclerView() {
38 | recyclerView = (RecyclerView) findViewById(R.id.show_rv);
39 | LinearLayoutManager layoutManager = new LinearLayoutManager(this);
40 | recyclerView.setLayoutManager(layoutManager);
41 | String[] array = {title + ".txt"};
42 | adapter = new ShowAdapter(DataManager.getData(this, array));
43 | recyclerView.setAdapter(adapter);
44 | }
45 |
46 | public static void actionStart(Context context, String name) {
47 | Intent intent = new Intent(context, ShowActivity.class);
48 | intent.putExtra("name", name);
49 | context.startActivity(intent);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/ShowAdapter.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.content.ClipboardManager;
4 | import android.content.Context;
5 | import android.content.DialogInterface;
6 | import android.content.Intent;
7 | import android.content.SharedPreferences;
8 | import android.graphics.Color;
9 | import android.preference.PreferenceManager;
10 | import android.support.design.widget.Snackbar;
11 | import android.support.v7.app.AlertDialog;
12 | import android.support.v7.widget.CardView;
13 | import android.support.v7.widget.RecyclerView;
14 | import android.view.LayoutInflater;
15 | import android.view.View;
16 | import android.view.ViewGroup;
17 | import android.widget.TextView;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 | /**
23 | * Created by user on 2017/7/22.
24 | */
25 |
26 | public class ShowAdapter extends RecyclerView.Adapter {
27 | private List list = new ArrayList<>();
28 |
29 | static class ViewHolder extends RecyclerView.ViewHolder {
30 | private TextView title;
31 | private TextView content;
32 | private CardView cardView;
33 |
34 | public ViewHolder(View v) {
35 | super(v);
36 | cardView = (CardView) v.findViewById(R.id.cardview);
37 | title = (TextView) v.findViewById(R.id.title);
38 | content = (TextView) v.findViewById(R.id.content);
39 | SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(v.getContext());
40 | Boolean nightMode = sp.getBoolean("nightMode", false);
41 | if (nightMode) {
42 | View line = v.findViewById(R.id.lineView);
43 | line.setBackgroundColor(Color.parseColor("#616161"));
44 | title.setTextColor(Color.parseColor("#f5f5f5"));
45 | content.setTextColor(Color.parseColor("#e0e0e0"));
46 | }
47 | }
48 | }
49 |
50 | public ShowAdapter(List list) {
51 | this.list = list;
52 | }
53 |
54 | public void setData(List list) {
55 | this.list = list;
56 | notifyDataSetChanged();
57 | }
58 |
59 | @Override
60 | public int getItemCount() {
61 | return list.size();
62 | }
63 |
64 | @Override
65 | public void onBindViewHolder(final ShowAdapter.ViewHolder holder, int position) {
66 | final Data data = list.get(position);
67 | holder.title.setText(++position + "," + data.title);
68 | holder.content.setText(data.content);
69 | holder.cardView.setOnClickListener(new View.OnClickListener() {
70 | @Override
71 | public void onClick(View v) {
72 | CodeActivity.actionStart(v.getContext(), data.title, data.content);
73 | }
74 | });
75 | holder.cardView.setOnLongClickListener(new View.OnLongClickListener() {
76 | @Override
77 | public boolean onLongClick(View v) {
78 | showListDialog(v, data);
79 | return false;
80 | }
81 | });
82 | }
83 |
84 | private void showListDialog(final View view, final Data data) {
85 | final String[] items = {"复制全部内容", "分享全部内容"};
86 | AlertDialog.Builder listDialog = new AlertDialog.Builder(view.getContext());
87 | listDialog.setTitle("选择操作");
88 | listDialog.setItems(items, new DialogInterface.OnClickListener() {
89 | @Override
90 | public void onClick(DialogInterface dialog, int which) {
91 | switch (which) {
92 | case 0:
93 | ClipboardManager cmb = (ClipboardManager) view.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
94 | cmb.setText(data.title + "\n" + data.content);
95 | Snackbar.make(view, "已复制全部内容", Snackbar.LENGTH_SHORT).setAction("确定", null).show();
96 | break;
97 | case 1:
98 | Intent intent = new Intent(Intent.ACTION_SEND);
99 | intent.setType("text/plain");
100 | intent.putExtra(Intent.EXTRA_TEXT, data.title + "\n" + data.content);
101 | view.getContext().startActivity(Intent.createChooser(intent, "分享"));
102 | break;
103 | }
104 | }
105 | });
106 | listDialog.show();
107 | }
108 |
109 | @Override
110 | public ShowAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
111 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.show_item, parent, false);
112 | ShowAdapter.ViewHolder holder = new ShowAdapter.ViewHolder(view);
113 | return holder;
114 | }
115 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/ALuaGuide/WebViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.SharedPreferences;
6 | import android.preference.PreferenceManager;
7 | import android.support.v7.app.ActionBar;
8 | import android.os.Bundle;
9 | import android.webkit.WebSettings;
10 | import android.webkit.WebView;
11 | import android.webkit.WebViewClient;
12 |
13 |
14 | public class WebViewActivity extends MySwipeBackActivity {
15 |
16 | private WebView webView;
17 |
18 | @Override
19 | protected void onCreate(Bundle savedInstanceState) {
20 | SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
21 | if (sp.getBoolean("nightMode", false)) {
22 | setTheme(R.style.DarkAppTheme);
23 | }
24 | super.onCreate(savedInstanceState);
25 | setupActionBar();
26 | setContentView(R.layout.activity_lua_manual);
27 | initWebView();
28 | }
29 |
30 | private void initWebView() {
31 | webView = (WebView) findViewById(R.id.webView);
32 | WebSettings settings = webView.getSettings();
33 | settings.setUseWideViewPort(true);
34 | settings.setLoadWithOverviewMode(true);
35 | settings.setBuiltInZoomControls(true);
36 | settings.setDisplayZoomControls(false);
37 | webView.loadUrl(getIntent().getStringExtra("url"));
38 | webView.setWebViewClient(new WebViewClient() {
39 | @Override
40 | public boolean shouldOverrideUrlLoading(WebView view, String url) {
41 | actionStart(WebViewActivity.this, url);
42 | return true;
43 | }
44 | });
45 | }
46 |
47 | private void setupActionBar() {
48 | ActionBar actionBar = getSupportActionBar();
49 | actionBar.setDisplayHomeAsUpEnabled(true);
50 | }
51 |
52 | public static void actionStart(Context context, String url) {
53 | Intent intent = new Intent(context, WebViewActivity.class);
54 | intent.putExtra("url", url);
55 | context.startActivity(intent);
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/LuaEditor/CodeEditText.java:
--------------------------------------------------------------------------------
1 | package com.sf.LuaEditor;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.graphics.Typeface;
9 | import android.preference.PreferenceManager;
10 | import android.text.Layout;
11 | import android.util.AttributeSet;
12 | import android.util.TypedValue;
13 | import android.view.ViewTreeObserver;
14 |
15 |
16 | public class CodeEditText extends ShaderEditor {
17 | private Context context;
18 | private transient Paint paint = new Paint();
19 | private Layout layout;
20 |
21 | public CodeEditText(Context context, AttributeSet attrs) {
22 | super(context, attrs);
23 | this.context = context;
24 | paint.setStyle(Paint.Style.FILL);
25 | paint.setAntiAlias(true);
26 | paint.setTypeface(Typeface.MONOSPACE);
27 | SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
28 | if (sp.getBoolean("nightMode", false)) {
29 | paint.setColor(Color.parseColor("#eeeeee"));
30 | } else {
31 | paint.setColor(Color.parseColor("#424242"));
32 | }
33 | paint.setTextSize(getPixels(14));
34 | getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
35 | @Override
36 | public void onGlobalLayout() {
37 | layout = getLayout();
38 | }
39 | });
40 | }
41 |
42 | private int getDigitCount() {
43 | int count = 0;
44 | int len = getLineCount();
45 | while (len > 0) {
46 | count++;
47 | len /= 10;
48 | }
49 | return count;
50 | }
51 |
52 | @Override
53 | protected void onDraw(Canvas canvas) {
54 | int padding = (int) getPixels(getDigitCount() * 10 + 10);
55 | setPadding(padding, 0, 0, 0);
56 |
57 |
58 | int scrollY = getScrollY();
59 | int firstLine = layout.getLineForVertical(scrollY), lastLine;
60 |
61 | try {
62 | lastLine = layout.getLineForVertical(scrollY + (getHeight() - getExtendedPaddingTop() - getExtendedPaddingBottom()));
63 | } catch (NullPointerException npe) {
64 | lastLine = layout.getLineForVertical(scrollY + (getHeight() - getPaddingTop() - getPaddingBottom()));
65 | }
66 |
67 | int positionY = getBaseline() + (layout.getLineBaseline(firstLine) - layout.getLineBaseline(0));
68 | drawLineNumber(canvas, layout, positionY, firstLine);
69 | for (int i = firstLine + 1; i <= lastLine; i++) {
70 | positionY += layout.getLineBaseline(i) - layout.getLineBaseline(i - 1);
71 | drawLineNumber(canvas, layout, positionY, i);
72 | }
73 |
74 | super.onDraw(canvas);
75 |
76 | }
77 |
78 | private void drawLineNumber(Canvas canvas, Layout layout, int positionY, int line) {
79 | int positionX = (int) layout.getLineLeft(line);
80 | canvas.drawText(String.valueOf(line + 1), positionX + getPixels(2), positionY, paint);
81 |
82 | }
83 |
84 | private float getPixels(int dp) {
85 | return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
86 | }
87 |
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/LuaEditor/LuaTokenTypes.java:
--------------------------------------------------------------------------------
1 | package com.sf.LuaEditor;
2 |
3 | /**
4 | * Created by zy on 2015/8/26.
5 | */
6 | public enum LuaTokenTypes {
7 | WRONG,
8 | NL_BEFORE_LONGSTRING,
9 | WS,
10 | NEWLINE,
11 | SHEBANG,
12 | LONGCOMMENT,
13 | SHORTCOMMENT,
14 | LUADOC_COMMENT,
15 | LONGCOMMENT_BEGIN,
16 | LONGCOMMENT_END,
17 | NAME,
18 | NUMBER,
19 | STRING,
20 | LONGSTRING,
21 | LONGSTRING_BEGIN,
22 | LONGSTRING_END,
23 | UNTERMINATED_STRING,
24 | DIV,
25 | MULT,
26 | LPAREN,
27 | RPAREN,
28 | LBRACK,
29 | RBRACK,
30 | LCURLY,
31 | RCURLY,
32 | COLON,
33 | COMMA,
34 | DOT,
35 | ASSIGN,
36 | SEMI,
37 | EQ,
38 | NE,
39 | PLUS,
40 | MINUS,
41 | GE,
42 | GT,
43 | EXP,
44 | LE,
45 | LT,
46 | ELLIPSIS,
47 | CONCAT,
48 | GETN,
49 | MOD,
50 |
51 | IF,
52 | ELSE,
53 | ELSEIF,
54 | WHILE,
55 | WITH,
56 | THEN,
57 | FOR,
58 | IN,
59 | RETURN,
60 | BREAK,
61 | CONTINUE,
62 | TRUE,
63 | FALSE,
64 | NIL,
65 | FUNCTION,
66 | DO,
67 | NOT,
68 | AND,
69 | OR,
70 | LOCAL,
71 | REPEAT,
72 | UNTIL,
73 | END
74 | }
75 |
--------------------------------------------------------------------------------
/app/src/main/java/com/sf/LuaEditor/ShaderEditor.java:
--------------------------------------------------------------------------------
1 | package com.sf.LuaEditor;
2 |
3 |
4 | import android.content.Context;
5 | import android.content.SharedPreferences;
6 | import android.graphics.Canvas;
7 | import android.graphics.Color;
8 | import android.graphics.Paint;
9 | import android.graphics.Typeface;
10 | import android.os.Handler;
11 | import android.preference.PreferenceManager;
12 | import android.support.v4.content.ContextCompat;
13 | import android.text.*;
14 | import android.text.style.ForegroundColorSpan;
15 | import android.text.style.ReplacementSpan;
16 | import android.text.style.StyleSpan;
17 | import android.util.AttributeSet;
18 |
19 | import com.sf.ALuaGuide.ExceptionsHandle;
20 | import com.sf.ALuaGuide.R;
21 |
22 | import java.io.IOException;
23 | import java.util.regex.Matcher;
24 | import java.util.regex.Pattern;
25 |
26 | public class ShaderEditor extends android.support.v7.widget.AppCompatEditText {
27 | private static final Pattern PATTERN_NUMBERS = Pattern.compile(
28 | "\\b(\\d*[.]?\\d+)\\b");
29 |
30 | private static final Pattern PATTERN_KEYWORDS = Pattern.compile(
31 | "\\b(" +
32 | "and|break|do|else|elseif|end|false|for|function|goto|if|" +
33 | "in|local|nil|not|or|repeat|return|then|true|until|while" +
34 | ")\\b");
35 |
36 | private static final Pattern PATTERN_BUILTINS = Pattern.compile(
37 | "\\b(pcall|print|rawequal|rawget|rawlen|rawset|require|select|self|" +
38 |
39 | "TextView|EditText|Button|ImageButton|ImageView|CheckBox|RadioButton|ToggleButton|" +
40 | "Switch|ListView|GridView|PageView|ExpandableListView|Spinner|SeekBar|ScrollView|" +
41 | "ProgressBar|RatingBar|DatePicker|TimePicker|NumberPicker|LinearLayout|HorizontalScrollView|" +
42 | "AbsoluteLayout|FrameLayout|RelativeLayout|CardView|RadioGroup|GridLayout|" +
43 |
44 | "getmetatable|ipairs|load|loadfile|loadstring|module|next|pairs|" +
45 | "setmetatable|tointeger|tonumber|tostring|type|unpack|xpcall|" +
46 | "TextView|assert|collectgarbage|dofile|error|findtable|" +
47 | "coroutine|debug|io|luajava|math|os|package|string|table|utf8|" +
48 | "setmetatable|setupvalue|setuservalue|traceback|upvalueid|upvaluejoin|sethook|" +
49 | "close|flush|input|lines|open|output|popen|read|stderr|stdin|stdout|tmpfile|type|" +
50 | "loaded|luapath|new|newInstance|package|tostring|abs|acos|asin|atan|ceil|cos|" +
51 | "pow|rad|random|randomseed|sin|sinh|sqrt|tan|tanh|tointeger|type|ult|task|thread|timer|" +
52 | "clock|date|difftime|execute|exit|getenv|remove|rename|setlocale|time|tmpname|" +
53 | "byte|char|dump|find|format|gfind|gmatch|gsub|len|lower|match|pack|packsize|rep|" +
54 | "activity|call|compile|dump|each|enum|import|loadbitmap|loadlayout|loadmenu|set|" +
55 | "setlocal|write)\\b");
56 | private static final Pattern PATTERN_COMMENTS = Pattern.compile(
57 | "--\\[\\[(?:.|[\\n\\r])*?\\]\\]|--.*");
58 |
59 | private static final Pattern OPERATORS = Pattern.compile("[\\p{P}+~$`^=]");
60 |
61 | private final Handler updateHandler = new Handler();
62 | private OnTextChangedListener onTextChangedListener;
63 | private int updateDelay;
64 | private boolean dirty = false;
65 | private boolean modified = true;
66 | private int colorNumber;
67 | private int colorKeyword;
68 | private int colorBuiltin;
69 | private int colorComment;
70 | private final Runnable updateRunnable =
71 | new Runnable() {
72 | @Override
73 | public void run() {
74 | Editable e = getText();
75 |
76 | if (onTextChangedListener != null)
77 | onTextChangedListener.onTextChanged(
78 | e.toString());
79 |
80 | highlightWithoutChange(e);
81 | }
82 | };
83 | private int tabWidth = 0;
84 | private Context context;
85 |
86 | public ShaderEditor(Context context, AttributeSet attrs) {
87 | super(context, attrs);
88 | init(context);
89 | }
90 |
91 | private static void clearSpans(Editable e) {
92 | {
93 | ForegroundColorSpan spans[] = e.getSpans(
94 | 0,
95 | e.length(),
96 | ForegroundColorSpan.class);
97 |
98 | for (int n = spans.length; n-- > 0; )
99 | e.removeSpan(spans[n]);
100 | }
101 |
102 | {
103 | StyleSpan spans[] = e.getSpans(
104 | 0,
105 | e.length(),
106 | StyleSpan.class);
107 |
108 | for (int n = spans.length; n-- > 0; )
109 | e.removeSpan(spans[n]);
110 | }
111 | }
112 |
113 | public boolean isModified() {
114 | return dirty;
115 | }
116 |
117 | private void init(Context context) {
118 | this.context = context;
119 | SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
120 | if (sp.getBoolean("nightMode", false)) {
121 | setTextColor(Color.parseColor("#e0e0e0"));
122 | } else {
123 | setTextColor(Color.parseColor("#424242"));
124 | }
125 | this.updateDelay = Integer.parseInt(sp.getString("delay", "10"));
126 |
127 | setFilters(new InputFilter[]{
128 | new InputFilter() {
129 | @Override
130 | public CharSequence filter(
131 | CharSequence source,
132 | int start,
133 | int end,
134 | Spanned dest,
135 | int dstart,
136 | int dend) {
137 | if (modified &&
138 | end - start == 1 &&
139 | start < source.length() &&
140 | dstart < dest.length()) {
141 | char c = source.charAt(start);
142 |
143 | if (c == '\n')
144 | return autoIndent(
145 | source,
146 | dest,
147 | dstart,
148 | dend);
149 | }
150 |
151 | return source;
152 | }
153 | }});
154 |
155 | if (sp.getBoolean("heightLight", true)) {
156 |
157 | addTextChangedListener(
158 | new TextWatcher() {
159 | private int start = 0;
160 | private int count = 0;
161 |
162 | @Override
163 | public void onTextChanged(CharSequence s, int start, int before, int count) {
164 | this.start = start;
165 | this.count = count;
166 | }
167 |
168 | @Override
169 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
170 | }
171 |
172 | @Override
173 | public void afterTextChanged(Editable e) {
174 | cancelUpdate();
175 | convertTabs(e, start, count);
176 |
177 | if (!modified)
178 | return;
179 |
180 | dirty = true;
181 | updateHandler.postDelayed(
182 | updateRunnable,
183 | updateDelay);
184 | }
185 | });
186 | }
187 |
188 | setSyntaxColors(context);
189 | }
190 |
191 | private void setSyntaxColors(Context context) {
192 | colorNumber = ContextCompat.getColor(
193 | context,
194 | R.color.syntax_number);
195 | colorKeyword = ContextCompat.getColor(
196 | context,
197 | R.color.syntax_keyword);
198 | colorBuiltin = ContextCompat.getColor(
199 | context,
200 | R.color.syntax_builtin);
201 | colorComment = ContextCompat.getColor(
202 | context,
203 | R.color.syntax_comment);
204 |
205 | }
206 |
207 | private void cancelUpdate() {
208 | updateHandler.removeCallbacks(updateRunnable);
209 | }
210 |
211 | private void highlightWithoutChange(Editable e) {
212 | modified = false;
213 | highlight(e);
214 | modified = true;
215 | }
216 |
217 | private Editable highlight(Editable e) {
218 | try {
219 | clearSpans(e);
220 |
221 | if (e.length() == 0)
222 | return e;
223 |
224 | for (Matcher m = OPERATORS.matcher(e); m.find(); )
225 | e.setSpan(new ForegroundColorSpan(Color.parseColor("#673ab7")), m.start(), m.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
226 |
227 | for (Matcher m = PATTERN_NUMBERS.matcher(e); m.find(); )
228 | e.setSpan(new ForegroundColorSpan(colorNumber), m.start(), m.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
229 |
230 | for (Matcher m = PATTERN_KEYWORDS.matcher(e); m.find(); ) {
231 | e.setSpan(new ForegroundColorSpan(colorKeyword), m.start(), m.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
232 | e.setSpan(new StyleSpan(Typeface.BOLD), m.start(), m.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
233 | }
234 |
235 | for (Matcher m = PATTERN_BUILTINS.matcher(e); m.find(); )
236 | e.setSpan(new ForegroundColorSpan(colorBuiltin), m.start(), m.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
237 |
238 | for (Matcher m = Pattern.compile("\\\"(.*?)\\\"|\\\'(.*?)\\\'|\\[\\[(.*?)\\]\\]").matcher(e); m.find(); ) {
239 | e.setSpan(new ForegroundColorSpan(Color.parseColor("#26a69a")), m.start(), m.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
240 | }
241 |
242 | for (Matcher m = PATTERN_COMMENTS.matcher(e); m.find(); ) {
243 | e.setSpan(new ForegroundColorSpan(colorComment), m.start(), m.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
244 | e.setSpan(new StyleSpan(Typeface.ITALIC), m.start(), m.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
245 | }
246 |
247 | } catch (IllegalStateException error) {
248 | ExceptionsHandle.show(context, error.toString());
249 | }
250 | return e;
251 | }
252 |
253 | private CharSequence autoIndent(
254 | CharSequence source,
255 | Spanned dest,
256 | int dstart,
257 | int dend) {
258 | String indent = "";
259 | int istart = dstart - 1;
260 |
261 | boolean dataBefore = false;
262 | int pt = 0;
263 |
264 | for (; istart > -1; --istart) {
265 | char c = dest.charAt(istart);
266 |
267 | if (c == '\n')
268 | break;
269 |
270 | if (c != ' ' &&
271 | c != '\t') {
272 | if (!dataBefore) {
273 | if (c == '{' ||
274 | c == '+' ||
275 | c == '-' ||
276 | c == '*' ||
277 | c == '/' ||
278 | c == '%' ||
279 | c == '^' ||
280 | c == '=')
281 | pt--;
282 |
283 | dataBefore = true;
284 | }
285 |
286 | if (c == '(')
287 | --pt;
288 | else if (c == ')')
289 | ++pt;
290 | }
291 | }
292 |
293 | if (istart > -1) {
294 | char charAtCursor = dest.charAt(dstart);
295 | int iend;
296 |
297 | for (iend = ++istart;
298 | iend < dend;
299 | ++iend) {
300 | char c = dest.charAt(iend);
301 |
302 | if (charAtCursor != '\n' &&
303 | c == '/' &&
304 | iend + 1 < dend &&
305 | dest.charAt(iend) == c) {
306 | iend += 2;
307 | break;
308 | }
309 |
310 | if (c != ' ' &&
311 | c != '\t')
312 | break;
313 | }
314 |
315 | indent += dest.subSequence(istart, iend);
316 | }
317 |
318 | if (pt < 0)
319 | indent += "\t";
320 |
321 | return source + indent;
322 | }
323 |
324 | private void convertTabs(Editable e, int start, int count) {
325 | if (tabWidth < 1)
326 | return;
327 |
328 | String s = e.toString();
329 |
330 | for (int stop = start + count;
331 | (start = s.indexOf("\t", start)) > -1 && start < stop;
332 | ++start)
333 | e.setSpan(
334 | new TabWidthSpan(),
335 | start,
336 | start + 1,
337 | Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
338 | }
339 |
340 | public interface OnTextChangedListener {
341 | void onTextChanged(String text);
342 | }
343 |
344 | private class TabWidthSpan extends ReplacementSpan {
345 | @Override
346 | public int getSize(
347 | Paint paint,
348 | CharSequence text,
349 | int start,
350 | int end,
351 | Paint.FontMetricsInt fm) {
352 | return tabWidth;
353 | }
354 |
355 | @Override
356 | public void draw(
357 | Canvas canvas,
358 | CharSequence text,
359 | int start,
360 | int end,
361 | float x,
362 | int top,
363 | int y,
364 | int bottom,
365 | Paint paint) {
366 | }
367 | }
368 |
369 | public StringBuilder format(String text) {
370 | int width = 2;
371 | StringBuilder builder = new StringBuilder();
372 | boolean isNewLine = true;
373 | LuaLexer lexer = new LuaLexer(text);
374 | try {
375 | int idt = 0;
376 |
377 | while (true) {
378 | LuaTokenTypes type = lexer.advance();
379 | if (type == null)
380 | break;
381 | if (type == LuaTokenTypes.NEWLINE) {
382 | isNewLine = true;
383 | builder.append('\n');
384 | idt = Math.max(0, idt);
385 |
386 | } else if (isNewLine) {
387 | if (type == LuaTokenTypes.WS) {
388 |
389 | } else if (type == LuaTokenTypes.ELSE) {
390 | idt--;
391 | builder.append(createIntdent(idt * width));
392 | builder.append(lexer.yytext());
393 | idt++;
394 | isNewLine = false;
395 | } else if (type == LuaTokenTypes.ELSEIF || type == LuaTokenTypes.END || type == LuaTokenTypes.UNTIL || type == LuaTokenTypes.RCURLY) {
396 | idt--;
397 | builder.append(createIntdent(idt * width));
398 | builder.append(lexer.yytext());
399 |
400 | isNewLine = false;
401 | } else {
402 | builder.append(createIntdent(idt * width));
403 | builder.append(lexer.yytext());
404 | idt += indent(type);
405 | isNewLine = false;
406 | }
407 | } else if (type == LuaTokenTypes.WS) {
408 | builder.append(' ');
409 | } else {
410 | builder.append(lexer.yytext());
411 | idt += indent(type);
412 | }
413 |
414 | }
415 | } catch (IOException e) {
416 | ExceptionsHandle.show(context, e.toString());
417 | }
418 | return builder;
419 | }
420 |
421 | private static int indent(LuaTokenTypes t) {
422 | switch (t) {
423 | case DO:
424 | case FUNCTION:
425 | case THEN:
426 | case REPEAT:
427 | case LCURLY:
428 | return 1;
429 | case UNTIL:
430 | case ELSEIF:
431 | case END:
432 | case RCURLY:
433 | return -1;
434 | default:
435 | return 0;
436 | }
437 | }
438 |
439 | private static char[] createIntdent(int n) {
440 | if (n < 0)
441 | return new char[0];
442 | char[] idts = new char[n];
443 | for (int i = 0; i < n; i++)
444 | idts[i] = ' ';
445 | return idts;
446 | }
447 | }
448 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_book.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HK-SHAO/ALuaGuide/26822e92d4a0f150d0355af883542ed33fea5f6d/app/src/main/res/drawable/ic_book.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HK-SHAO/ALuaGuide/26822e92d4a0f150d0355af883542ed33fea5f6d/app/src/main/res/drawable/ic_close.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HK-SHAO/ALuaGuide/26822e92d4a0f150d0355af883542ed33fea5f6d/app/src/main/res/drawable/ic_search.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/touch_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
10 |
11 |
12 | -
13 |
14 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_code.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
12 |
13 |
17 |
18 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_lua_manual.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
12 |
13 |
19 |
20 |
25 |
26 |
27 |
28 |
29 |
30 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_preview.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_search.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
20 |
21 |
22 |
23 |
32 |
33 |
34 |
35 |
40 |
41 |
42 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_show.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/page1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/page1_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
19 |
20 |
29 |
30 |
36 |
37 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/page2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/page2_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
18 |
19 |
25 |
26 |
35 |
36 |
42 |
43 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/search_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
26 |
27 |
33 |
34 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/show_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
18 |
19 |
28 |
29 |
35 |
36 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HK-SHAO/ALuaGuide/26822e92d4a0f150d0355af883542ed33fea5f6d/app/src/main/res/mipmap/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #2196f3
4 | #2196f3
5 | #f06292
6 | #f5f5f5
7 | #0000
8 |
9 | #212121
10 | #212121
11 | #64b5f6
12 |
13 | #1976d2
14 | #ef5350
15 | #42a5f5
16 | #9e9e9e
17 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 16dp
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ALua手册
3 | 设置
4 |
5 |
6 |
7 |
8 | General
9 |
10 | Enable social recommendations
11 | Recommendations for people to contact
12 | based on your message history
13 |
14 |
15 | Display name
16 | John Smith
17 |
18 | Add friends to messages
19 |
20 | - Always
21 | - When possible
22 | - Never
23 |
24 |
25 | - 1
26 | - 0
27 | - -1
28 |
29 |
30 |
31 | Data & sync
32 |
33 | Sync frequency
34 |
35 | - 15 minutes
36 | - 30 minutes
37 | - 1 hour
38 | - 3 hours
39 | - 6 hours
40 | - Never
41 |
42 |
43 | - 15
44 | - 30
45 | - 60
46 | - 180
47 | - 360
48 | - -1
49 |
50 |
51 |
52 | - Entry 1
53 | - Entry 2
54 | - Entry 3
55 |
56 |
57 |
58 | - 1
59 | - 2
60 | - 3
61 |
62 |
63 |
64 |
65 | System sync settings
66 |
67 |
68 | Notifications
69 |
70 | New message notifications
71 |
72 | Ringtone
73 | Silent
74 |
75 | Vibrate
76 |
77 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
18 |
19 |
23 |
24 |
28 |
29 |
34 |
35 |
40 |
41 |
48 |
49 |
56 |
57 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/pref_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
13 |
14 |
15 |
16 |
17 |
22 |
26 |
31 |
37 |
38 |
39 |
40 |
43 |
44 |
45 |
48 |
51 |
52 |
55 |
56 |
59 |
60 |
--------------------------------------------------------------------------------
/app/src/test/java/com/sf/ALuaGuide/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.sf.ALuaGuide;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.3.3'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HK-SHAO/ALuaGuide/26822e92d4a0f150d0355af883542ed33fea5f6d/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Jul 19 10:30:14 CST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------