├── .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 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 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 | ![](https://i.loli.net/2017/07/27/5979ba177ba1b.png) 11 | ![](https://i.loli.net/2017/07/27/5979ba1902470.png) 12 | ![](https://i.loli.net/2017/07/27/5979ba1902fdd.png) 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 | 53 | 最后修改时间: 54 | 2015年1月14日23:07 55 | 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 | 5 | 10 | 11 | 16 | 17 | 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 |