add: tutorial tab

This commit is contained in:
hyb1996
2017-08-22 18:11:14 +08:00
parent 602b84fc92
commit 42f6802598
21 changed files with 858 additions and 305 deletions

View File

@@ -2,6 +2,7 @@
<profile version="1.0"> <profile version="1.0">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<inspection_tool class="AndroidLintContentDescription" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="AndroidLintContentDescription" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AndroidLintRtlHardcoded" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
<option name="TOP_LEVEL_CLASS_OPTIONS"> <option name="TOP_LEVEL_CLASS_OPTIONS">
<value> <value>

View File

@@ -21,17 +21,17 @@ events.onKeyDown("menu", function(event){
``` ```
### events.emitter() ## events.emitter()
返回一个新的EventEmitter。 返回一个新的EventEmitter。
### events.observeKey() ## events.observeKey()
启用按键监听例如音量键、Home键。 启用按键监听例如音量键、Home键。
在安卓4.3以上才能使用。 在安卓4.3以上才能使用。
### events.onKeyDown(keyName, listener) ## events.onKeyDown(keyName, listener)
* keyName \<String\> 要监听的按键名称 * keyName \<String\> 要监听的按键名称
* listener \<Function\> 参数为一个[KeyEvent](#KeyEvent) * listener \<Function\> 参数为一个[KeyEvent](#KeyEvent)
@@ -42,51 +42,51 @@ events.onKeyDown("menu", function(event){
* back 返回键 * back 返回键
* menu 菜单键 * menu 菜单键
### events.onKeyUp(keyName, listener) ## events.onKeyUp(keyName, listener)
* keyName \<String\> 要监听的按键名称 * keyName \<String\> 要监听的按键名称
* listener \<Function\> 参数为一个[KeyEvent](#KeyEvent) * listener \<Function\> 参数为一个[KeyEvent](#KeyEvent)
注册一个按键监听函数当有keyName对应的按键弹起时会调用该函数。 注册一个按键监听函数当有keyName对应的按键弹起时会调用该函数。
### events.onceKeyDown(keyName, listener) ## events.onceKeyDown(keyName, listener)
* keyName \<String\> 要监听的按键名称 * keyName \<String\> 要监听的按键名称
* listener \<Function\> 参数为一个[KeyEvent](#KeyEvent) * listener \<Function\> 参数为一个[KeyEvent](#KeyEvent)
注册一个按键监听函数当有keyName对应的按键被按下时会调用该函数之后会注销该按键监听。也就是listener只会被调用一次。 注册一个按键监听函数当有keyName对应的按键被按下时会调用该函数之后会注销该按键监听。也就是listener只会被调用一次。
### events.onceKeyUp(keyName, listener) ## events.onceKeyUp(keyName, listener)
* keyName \<String\> 要监听的按键名称 * keyName \<String\> 要监听的按键名称
* listener \<Function\> 参数为一个[KeyEvent](#KeyEvent) * listener \<Function\> 参数为一个[KeyEvent](#KeyEvent)
注册一个按键监听函数当有keyName对应的按键弹起时会调用该函数之后会注销该按键监听。也就是listener只会被调用一次。 注册一个按键监听函数当有keyName对应的按键弹起时会调用该函数之后会注销该按键监听。也就是listener只会被调用一次。
### events.removeAllKeyDownListeners(keyName) ## events.removeAllKeyDownListeners(keyName)
* keyName \<String\> 按键名称 * keyName \<String\> 按键名称
删除该按键的KeyDown事件的所有监听。 删除该按键的KeyDown事件的所有监听。
### events.removeAllKeyUpListeners(keyName) ## events.removeAllKeyUpListeners(keyName)
* keyName \<String\> 按键名称 * keyName \<String\> 按键名称
删除该按键的KeyUp事件的所有监听。 删除该按键的KeyUp事件的所有监听。
### events.observeTouch() ## events.observeTouch()
启用屏幕触摸监听。需要root权限 启用屏幕触摸监听。需要root权限
### events.setTouchEventTimeout(timeout) ## events.setTouchEventTimeout(timeout)
* timeout \<Number\> 两个触摸事件的最小间隔。单位毫秒。默认为10毫秒。 * timeout \<Number\> 两个触摸事件的最小间隔。单位毫秒。默认为10毫秒。
设置两个触摸事件分发的最小时间间隔。 设置两个触摸事件分发的最小时间间隔。
例如间隔为10毫秒的话前一个触摸事件发生并被注册的监听器处理后至少要过10毫秒才能分发和处理下一个触摸事件这10毫秒之间的触摸将会被忽略。 例如间隔为10毫秒的话前一个触摸事件发生并被注册的监听器处理后至少要过10毫秒才能分发和处理下一个触摸事件这10毫秒之间的触摸将会被忽略。
### events.getTouchEventTimeout() ## events.getTouchEventTimeout()
返回触摸事件的最小时间间隔。 返回触摸事件的最小时间间隔。
### events.onTouch(listener) ## events.onTouch(listener)
* listener \<Function\> 参数为Point的函数 * listener \<Function\> 参数为Point的函数
注册一个触摸监听函数。相当于`on("touch", listener)` 注册一个触摸监听函数。相当于`on("touch", listener)`
@@ -100,11 +100,11 @@ events.onTouch(function(p){
events.loop(); events.loop();
``` ```
### events.removeAllTouchListeners() ## events.removeAllTouchListeners()
删除所有事件监听函数。 删除所有事件监听函数。
### 事件: 'key' ## 事件: 'key'
* keyCode \<Number\> 键值 * keyCode \<Number\> 键值
* event \<KeyEvent\> 事件 * event \<KeyEvent\> 事件
@@ -124,7 +124,7 @@ events.loop();
* KeyEvent.KEYCODE_VOLUME_UP 音量上键 * KeyEvent.KEYCODE_VOLUME_UP 音量上键
* KeyEvent.KEYCODE_VOLUME_DOWN 音量下键 * KeyEvent.KEYCODE_VOLUME_DOWN 音量下键
### 事件: 'key_down' ## 事件: 'key_down'
* keyCode \<Number\> 键值 * keyCode \<Number\> 键值
* event \<KeyEvent\> 事件 * event \<KeyEvent\> 事件
@@ -138,7 +138,7 @@ events.on("key_down", function(keyCode, event){
events.loop(); events.loop();
``` ```
### 事件: 'key_up' ## 事件: 'key_up'
* keyCode \<Number\> 键值 * keyCode \<Number\> 键值
* event \<KeyEvent\> 事件 * event \<KeyEvent\> 事件
@@ -153,7 +153,7 @@ events.loop();
``` ```
### obverseNotification() ## obverseNotification()
开启通知(包括Toast)监听。 开启通知(包括Toast)监听。
``` ```
events.obverseNotification(); events.obverseNotification();
@@ -165,12 +165,12 @@ events.onToast(function(toast){
}); });
``` ```
### 事件: 'toast' ## 事件: 'toast'
* toast \<Object\> * toast \<Object\>
* getText() 获取Toast的文本内容 * getText() 获取Toast的文本内容
* getPackageName() 获取发出Toast的应用包名 * getPackageName() 获取发出Toast的应用包名
### 事件: 'notification' ## 事件: 'notification'
* notification \<Object\> 通知 * notification \<Object\> 通知
``` ```
@@ -184,7 +184,7 @@ events.on("notification", function(notification){
# EventEmitter # EventEmitter
### EventEmitter.defaultMaxListeners ## EventEmitter.defaultMaxListeners
每个事件默认可以注册最多 10 个监听器。 单个 EventEmitter 实例的限制可以使用 emitter.setMaxListeners(n) 方法改变。 所有 EventEmitter 实例的默认值可以使用 EventEmitter.defaultMaxListeners 属性改变。 每个事件默认可以注册最多 10 个监听器。 单个 EventEmitter 实例的限制可以使用 emitter.setMaxListeners(n) 方法改变。 所有 EventEmitter 实例的默认值可以使用 EventEmitter.defaultMaxListeners 属性改变。
@@ -199,19 +199,20 @@ emitter.once('event', () => {
}); });
``` ```
## EventEmitter.addListener(eventName, listener) ## EventEmitter.addListener(eventName, listener)
* eventName \<any\> * eventName {any}
* listener \<Function\> * listener {Function}
emitter.on(eventName, listener) 的别名。 emitter.on(eventName, listener) 的别名。
### EventEmitter.emit(eventName\[, ...args\]) ## EventEmitter.emit(eventName\[, ...args\])
* eventName <any> * eventName {any}
* args <any> * args {any}
按监听器的注册顺序,同步地调用每个注册到名为 eventName 事件的监听器,并传入提供的参数。 按监听器的注册顺序,同步地调用每个注册到名为 eventName 事件的监听器,并传入提供的参数。
如果事件有监听器,则返回 true ,否则返回 false。 如果事件有监听器,则返回 true ,否则返回 false。
### EventEmitter.eventNames() ## EventEmitter.eventNames()
返回一个列出触发器已注册监听器的事件的数组。 数组中的值为字符串或符号。 返回一个列出触发器已注册监听器的事件的数组。 数组中的值为字符串或符号。
``` ```
@@ -225,17 +226,17 @@ myEE.on(sym, () => {});
console.log(myEE.eventNames()); console.log(myEE.eventNames());
// 打印: [ 'foo', 'bar', Symbol(symbol) ] // 打印: [ 'foo', 'bar', Symbol(symbol) ]
``` ```
### EventEmitter.getMaxListeners()# ## EventEmitter.getMaxListeners()
返回 EventEmitter 当前的最大监听器限制值,该值可以通过 emitter.setMaxListeners(n) 设置或默认为 EventEmitter.defaultMaxListeners。 返回 EventEmitter 当前的最大监听器限制值,该值可以通过 emitter.setMaxListeners(n) 设置或默认为 EventEmitter.defaultMaxListeners。
### EventEmitter.listenerCount(eventName) ## EventEmitter.listenerCount(eventName)
* eventName <any> 正在被监听的事件名 * eventName {any} 正在被监听的事件名
返回正在监听名为 eventName 的事件的监听器的数量。 返回正在监听名为 eventName 的事件的监听器的数量。
### EventEmitter.listeners(eventName) ## EventEmitter.listeners(eventName)
* eventName <any> * eventName {any}
返回名为 eventName 的事件的监听器数组的副本。 返回名为 eventName 的事件的监听器数组的副本。
``` ```
@@ -246,9 +247,9 @@ console.log(util.inspect(server.listeners('connection')));
// 打印: [ [Function] ] // 打印: [ [Function] ]
``` ```
### EventEmitter.on(eventName, listener) ## EventEmitter.on(eventName, listener)
* eventName <any> 事件名 * eventName {any} 事件名
* listener <Function> 回调函数 * listener {Function} 回调函数
添加 listener 函数到名为 eventName 的事件的监听器数组的末尾。 不会检查 listener 是否已被添加。 多次调用并传入相同的 eventName 和 listener 会导致 listener 被添加与调用多次。 添加 listener 函数到名为 eventName 的事件的监听器数组的末尾。 不会检查 listener 是否已被添加。 多次调用并传入相同的 eventName 和 listener 会导致 listener 被添加与调用多次。
``` ```
@@ -270,9 +271,9 @@ myEE.emit('foo');
``` ```
### EventEmitter.once(eventName, listener)# ## EventEmitter.once(eventName, listener)#
* eventName <any> 事件名 * `eventName` {any} 事件名
* listener <Function> 回调函数 * `listener` {Function} 回调函数
添加一个单次 listener 函数到名为 eventName 的事件。 下次触发 eventName 事件时,监听器会被移除,然后调用。 添加一个单次 listener 函数到名为 eventName 的事件。 下次触发 eventName 事件时,监听器会被移除,然后调用。
``` ```
@@ -293,9 +294,9 @@ myEE.emit('foo');
// a // a
``` ```
### EventEmitter.prependListener(eventName, listener) ## EventEmitter.prependListener(eventName, listener)
* eventName <any> 事件名 * `eventName` {any} 事件名
* listener <Function> 回调函数 * `listener` {Function} 回调函数
添加 listener 函数到名为 eventName 的事件的监听器数组的开头。 不会检查 listener 是否已被添加。 多次调用并传入相同的 eventName 和 listener 会导致 listener 被添加与调用多次。 添加 listener 函数到名为 eventName 的事件的监听器数组的开头。 不会检查 listener 是否已被添加。 多次调用并传入相同的 eventName 和 listener 会导致 listener 被添加与调用多次。
``` ```
@@ -305,9 +306,9 @@ server.prependListener('connection', (stream) => {
``` ```
返回一个 EventEmitter 引用,可以链式调用。 返回一个 EventEmitter 引用,可以链式调用。
### EventEmitter.prependOnceListener(eventName, listener) ## EventEmitter.prependOnceListener(eventName, listener)
* eventName <any> 事件名 * `eventName` {any} 事件名
* listener <Function> 回调函数 * `listener` {Function} 回调函数
添加一个单次 listener 函数到名为 eventName 的事件的监听器数组的开头。 下次触发 eventName 事件时,监听器会被移除,然后调用。 添加一个单次 listener 函数到名为 eventName 的事件的监听器数组的开头。 下次触发 eventName 事件时,监听器会被移除,然后调用。
``` ```
@@ -317,8 +318,8 @@ server.prependOnceListener('connection', (stream) => {
``` ```
返回一个 EventEmitter 引用,可以链式调用。 返回一个 EventEmitter 引用,可以链式调用。
### EventEmitter.removeAllListeners(\[eventName\]) ## EventEmitter.removeAllListeners(\[eventName\])
* eventName <any> * `eventName` {any}
移除全部或指定 eventName 的监听器。 移除全部或指定 eventName 的监听器。
@@ -326,9 +327,9 @@ server.prependOnceListener('connection', (stream) => {
返回一个 EventEmitter 引用,可以链式调用。 返回一个 EventEmitter 引用,可以链式调用。
### EventEmitter.removeListener(eventName, listener) ## EventEmitter.removeListener(eventName, listener)
* eventName <any> * `eventName` {any}
* listener <Function> * `listener` {Function}
从名为 eventName 的事件的监听器数组中移除指定的 listener。 从名为 eventName 的事件的监听器数组中移除指定的 listener。
``` ```
@@ -376,8 +377,8 @@ myEmitter.emit('event');
返回一个 EventEmitter 引用,可以链式调用。 返回一个 EventEmitter 引用,可以链式调用。
### EventEmitter.setMaxListeners(n) ## EventEmitter.setMaxListeners(n)
* n <integer> * n {number}
默认情况下,如果为特定事件添加了超过 10 个监听器,则 EventEmitter 会打印一个警告。 此限制有助于寻找内存泄露。 但是,并不是所有的事件都要被限为 10 个。 emitter.setMaxListeners() 方法允许修改指定的 EventEmitter 实例的限制。 值设为 Infinity或 0表明不限制监听器的数量。 默认情况下,如果为特定事件添加了超过 10 个监听器,则 EventEmitter 会打印一个警告。 此限制有助于寻找内存泄露。 但是,并不是所有的事件都要被限为 10 个。 emitter.setMaxListeners() 方法允许修改指定的 EventEmitter 实例的限制。 值设为 Infinity或 0表明不限制监听器的数量。
@@ -385,29 +386,29 @@ myEmitter.emit('event');
# KeyEvent # KeyEvent
### KeyEvent.getAction() ## KeyEvent.getAction()
返回事件的动作。包括: 返回事件的动作。包括:
* KeyEvent.ACTION_DOWN 按下事件 * `KeyEvent.ACTION_DOWN` 按下事件
* KeyEvent.ACTION_UP 弹起事件 * `KeyEvent.ACTION_UP` 弹起事件
### KeyEvent.getKeyCode() ## KeyEvent.getKeyCode()
返回按键的键值。包括: 返回按键的键值。包括:
* KeyEvent.KEYCODE_HOME 主页键 * `KeyEvent.KEYCODE_HOME` 主页键
* KeyEvent.KEYCODE_BACK 返回键 * `KeyEvent.KEYCODE_BACK` 返回键
* KeyEvent.KEYCODE_MENU 菜单键 * `KeyEvent.KEYCODE_MENU` 菜单键
* KeyEvent.KEYCODE_VOLUME_UP 音量上键 * `KeyEvent.KEYCODE_VOLUME_UP` 音量上键
* KeyEvent.KEYCODE_VOLUME_DOWN 音量下键 * `KeyEvent.KEYCODE_VOLUME_DOWN` 音量下键
### KeyEvent.getEventTime() ## KeyEvent.getEventTime()
返回事件发生的时间戳。 返回事件发生的时间戳。返回值的类型是number。
### KeyEvent.getDownTime() ## KeyEvent.getDownTime()
返回最近一次按下事件的时间戳。如果本身是按下事件则与getEventTime()相同。 返回最近一次按下事件的时间戳。如果本身是按下事件则与getEventTime()相同。
### KeyEvent.keyCodeToString(keyCode) ## KeyEvent.keyCodeToString(keyCode)
把键值转换为字符串。例如KEYCODE_HOME转换为"KEYCODE_HOME"。 把键值转换为字符串。例如`KEYCODE_HOME`转换为`"KEYCODE_HOME"`

View File

@@ -26,7 +26,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
* Created by Stardust on 2017/1/23. * Created by Stardust on 2017/1/23.
*/ */
public abstract class BaseActivity extends AppCompatActivity { public abstract class BaseActivity extends AppCompatActivity implements BackPressedHandler.HostActivity {
protected static final int PERMISSION_REQUEST_CODE = 11186; protected static final int PERMISSION_REQUEST_CODE = 11186;
@@ -123,4 +123,9 @@ public abstract class BaseActivity extends AppCompatActivity {
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults); super.onRequestPermissionsResult(requestCode, permissions, grantResults);
} }
@Override
public BackPressedHandler.Observer getBackPressedObserver() {
return mBackPressObserver;
}
} }

View File

@@ -106,9 +106,9 @@ public class EditActivity extends Editor920Activity implements OnActivityResultD
@ViewById(R.id.content_view) @ViewById(R.id.content_view)
View mView; View mView;
private String mName; private String mName;
private File mFile;
private EditorDelegate mEditorDelegate;
private SparseArray<ToolbarMenuItem> mMenuMap; private SparseArray<ToolbarMenuItem> mMenuMap;
private EditorDelegate mEditorDelegate;
private File mFile;
private boolean mReadOnly = false; private boolean mReadOnly = false;
private OnActivityResultDelegate.Mediator mActivityResultMediator = new OnActivityResultDelegate.Mediator(); private OnActivityResultDelegate.Mediator mActivityResultMediator = new OnActivityResultDelegate.Mediator();
private BroadcastReceiver mOnRunFinishedReceiver = new BroadcastReceiver() { private BroadcastReceiver mOnRunFinishedReceiver = new BroadcastReceiver() {

View File

@@ -0,0 +1,117 @@
package com.stardust.scriptdroid.ui.edit;
import android.content.Context;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import com.jecelyin.editor.v2.common.Command;
import com.jecelyin.editor.v2.core.widget.TextView;
import com.jecelyin.editor.v2.ui.EditorDelegate;
import com.jecelyin.editor.v2.view.EditorView;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.ui.edit.completion.InputMethodEnhanceBar;
import com.stardust.scriptdroid.ui.edit.editor920.Editor920Utils;
import org.androidannotations.annotations.EViewGroup;
import java.io.File;
/**
* Created by Stardust on 2017/8/21.
*/
@EViewGroup(R.layout.script_edit_view)
public class ScriptEditView extends FrameLayout {
private class InputMethodEnhanceBarBridge implements InputMethodEnhanceBar.EditTextBridge {
private TextView mTextView;
public InputMethodEnhanceBarBridge(TextView textView) {
mTextView = textView;
}
@Override
public void appendText(CharSequence text) {
insertText(text);
}
@Override
public void backspace(int count) {
}
@Override
public TextView getEditText() {
return mTextView;
}
}
private EditorDelegate mEditorDelegate;
private File mFile;
private boolean mReadOnly = false;
public ScriptEditView(@NonNull Context context) {
super(context);
}
public ScriptEditView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public ScriptEditView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public boolean isReadOnly() {
return mReadOnly;
}
public void setReadOnly(boolean readOnly) {
mReadOnly = readOnly;
}
public void setFile(File file) {
mFile = file;
mEditorDelegate = new EditorDelegate(0, mFile, 0, "utf-8");
setUpEditor();
}
public void setContent(String name, String str) {
mEditorDelegate = new EditorDelegate(0, name, str);
}
public void insertText(CharSequence text) {
Command c = new Command(Command.CommandEnum.INSERT_TEXT);
c.object = text;
mEditorDelegate.doCommand(c);
}
private void setUpEditor() {
final EditorView editorView = (EditorView) findViewById(R.id.editor);
mEditorDelegate.setEditorView(editorView);
if (mFile == null)
Editor920Utils.setLang(mEditorDelegate, "JavaScript");
editorView.getEditText().setReadOnly(mReadOnly);
editorView.getEditText().setHorizontallyScrolling(true);
setUpInputMethodEnhanceBar(editorView);
}
private void setUpInputMethodEnhanceBar(final EditorView editorView) {
InputMethodEnhanceBar inputMethodEnhanceBar = (InputMethodEnhanceBar) findViewById(R.id.input_method_enhance_bar);
if (mReadOnly) {
inputMethodEnhanceBar.setVisibility(View.GONE);
} else {
inputMethodEnhanceBar.setEditTextBridge(new InputMethodEnhanceBarBridge(editorView.getEditText()));
}
}
}

View File

@@ -32,6 +32,9 @@ import com.stardust.scriptdroid.external.floatingwindow.HoverMenuManger;
import com.stardust.scriptdroid.script.ScriptFile; import com.stardust.scriptdroid.script.ScriptFile;
import com.stardust.scriptdroid.script.StorageFileProvider; import com.stardust.scriptdroid.script.StorageFileProvider;
import com.stardust.scriptdroid.ui.common.ScriptOperations; import com.stardust.scriptdroid.ui.common.ScriptOperations;
import com.stardust.scriptdroid.ui.main.community.CommunityFragment;
import com.stardust.scriptdroid.ui.main.doc.OnlineDocsFragment;
import com.stardust.scriptdroid.ui.main.doc.OnlineDocsFragment_;
import com.stardust.scriptdroid.ui.main.script_list.MyScriptListFragment_; import com.stardust.scriptdroid.ui.main.script_list.MyScriptListFragment_;
import com.stardust.scriptdroid.ui.main.task.TaskManagerFragment_; import com.stardust.scriptdroid.ui.main.task.TaskManagerFragment_;
import com.stardust.util.DeveloperUtils; import com.stardust.util.DeveloperUtils;
@@ -62,17 +65,6 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
public static final String MESSAGE_CLEAR_BACKGROUND_SETTINGS = "MESSAGE_CLEAR_BACKGROUND_SETTINGS"; public static final String MESSAGE_CLEAR_BACKGROUND_SETTINGS = "MESSAGE_CLEAR_BACKGROUND_SETTINGS";
private static final String LOG_TAG = "MainActivity"; private static final String LOG_TAG = "MainActivity";
private static final String EXTRA_ACTION = "EXTRA_ACTION";
private static final String ACTION_ON_RECORD_STOP = "ACTION_ON_RECORD_STOP";
private static final String ACTION_IMPORT_SCRIPT = "ACTION_IMPORT_SCRIPT";
private static final String ARGUMENT_SCRIPT = "ARGUMENT_SCRIPT";
private static final String ARGUMENT_PATH = "ARGUMENT_PATH";
private static final String ACTION_IMPORT_SAMPLE = "I cannot find the way back to you...Eating...17.4.29";
private static final String ARGUMENT_SAMPLE = "Take a chance on me...ok...?";
private static final String ARGUMENT_INPUT_STREAM = "17.7.12, Hi...could we start all over again...";
private static final String ACTION_ON_ROOT_RECORD_STOP = "ACTION_ON_ROOT_RECORD_STOP";
@ViewById(R.id.drawer_layout) @ViewById(R.id.drawer_layout)
DrawerLayout mDrawerLayout; DrawerLayout mDrawerLayout;
@@ -183,9 +175,10 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
private void setUpTabViewPager() { private void setUpTabViewPager() {
TabLayout tabLayout = $(R.id.tab); TabLayout tabLayout = $(R.id.tab);
mPagerAdapter = new FragmentPagerAdapterBuilder(this) mPagerAdapter = new FragmentPagerAdapterBuilder(this)
.add(new MyScriptListFragment_(), R.string.text_my_script) .add(new MyScriptListFragment_(), R.string.text_script)
.add(new SampleScriptListFragment(), R.string.text_sample_script) .add(new OnlineDocsFragment_(), R.string.text_tutorial)
.add(new TaskManagerFragment_(), R.string.text_task_manage) .add(new CommunityFragment(), R.string.text_community)
.add(new TaskManagerFragment_(), R.string.text_manage)
.build(); .build();
mViewPager.setAdapter(mPagerAdapter); mViewPager.setAdapter(mPagerAdapter);
tabLayout.setupWithViewPager(mViewPager); tabLayout.setupWithViewPager(mViewPager);

View File

@@ -0,0 +1,10 @@
package com.stardust.scriptdroid.ui.main.community;
import android.support.v4.app.Fragment;
/**
* Created by Stardust on 2017/8/22.
*/
public class CommunityFragment extends Fragment {
}

View File

@@ -0,0 +1,56 @@
package com.stardust.scriptdroid.ui.main.doc;
import android.app.Activity;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.webkit.WebView;
import com.stardust.scriptdroid.R;
import com.stardust.util.BackPressedHandler;
import com.stardust.widget.EWebView;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EFragment;
import org.androidannotations.annotations.ViewById;
/**
* Created by Stardust on 2017/8/22.
*/
@EFragment(R.layout.fragment_online_docs)
public class OnlineDocsFragment extends Fragment implements BackPressedHandler {
@ViewById(R.id.eweb_view)
EWebView mEWebView;
WebView mWebView;
@Override
public void onAttach(Context context) {
super.onAttach(context);
((BackPressedHandler.HostActivity) getActivity())
.getBackPressedObserver()
.registerHandler(this);
}
@AfterViews
void setUpViews() {
mWebView = mEWebView.getWebView();
mWebView.loadUrl("https://hyb1996.github.io/AutoJs-Docs/");
}
@Override
public void onDetach() {
super.onDetach();
((BackPressedHandler.HostActivity) getActivity())
.getBackPressedObserver()
.unregisterHandler(this);
}
@Override
public boolean onBackPressed(Activity activity) {
if (mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return false;
}
}

View File

@@ -1,30 +1,19 @@
package com.stardust.scriptdroid.ui.main.script_list; package com.stardust.scriptdroid.ui.main.script_list;
import android.graphics.drawable.GradientDrawable;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.afollestad.materialdialogs.DialogAction; import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.scriptdroid.script.ScriptFile;
import com.stardust.pio.PFile; import com.stardust.pio.PFile;
import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.script.ScriptFile;
import com.stardust.scriptdroid.script.Scripts; import com.stardust.scriptdroid.script.Scripts;
import com.stardust.scriptdroid.script.StorageFileProvider; import com.stardust.scriptdroid.script.StorageFileProvider;
import com.stardust.scriptdroid.tool.SimpleObserver;
import com.stardust.scriptdroid.ui.common.ScriptLoopDialog; import com.stardust.scriptdroid.ui.common.ScriptLoopDialog;
import com.stardust.widget.AutoAdapter; import com.stardust.scriptdroid.ui.edit.ScriptEditView;
import com.stardust.widget.BindableViewHolder;
import com.stardust.widget.ViewHolderSupplier;
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EFragment; import org.androidannotations.annotations.EFragment;
@@ -32,22 +21,11 @@ import org.androidannotations.annotations.ViewById;
import org.reactivestreams.Publisher; import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber; import org.reactivestreams.Subscriber;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.Callable;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
import butterknife.Optional; import butterknife.Optional;
import io.reactivex.Observable; import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer; import io.reactivex.functions.Consumer;
import io.reactivex.functions.Predicate;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
/** /**
@@ -56,76 +34,18 @@ import io.reactivex.schedulers.Schedulers;
@EFragment(R.layout.fragment_my_script_list) @EFragment(R.layout.fragment_my_script_list)
public class MyScriptListFragment extends Fragment { public class MyScriptListFragment extends Fragment {
public static final String MESSAGE_SCRIPT_FILE_ADDED = "MESSAGE_SCRIPT_FILE_ADDED";
private static final String TAG = "MyScriptListFragment"; private static final String TAG = "MyScriptListFragment";
private static ScriptFile sCurrentDirectory = StorageFileProvider.DEFAULT_DIRECTORY; private static ScriptFile sCurrentDirectory = StorageFileProvider.DEFAULT_DIRECTORY;
@ViewById(R.id.script_file_list) @ViewById(R.id.script_file_list)
RecyclerView mScriptFileList; ScriptListView mScriptFileList;
@ViewById(R.id.swipe_refresh_layout)
SwipeRefreshLayout mSwipeRefreshLayout;
private ScriptListAdapter mScriptListAdapter = new ScriptListAdapter();
private ScriptFile mSelectedScriptFile; private ScriptFile mSelectedScriptFile;
private ArrayList<ScriptFile> mScriptFiles = new ArrayList<>();
private ArrayList<ScriptFile> mDirectories = new ArrayList<>();
@AfterViews @AfterViews
void setUpViews() { void setUpViews() {
initScriptListRecyclerView();
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
loadScriptList();
}
});
}
private void initScriptListRecyclerView() {
mScriptFileList.setAdapter(mScriptListAdapter);
GridLayoutManager manager = new GridLayoutManager(getContext(), 2);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
//For directories
if (position >= 1 && position <= mDirectories.size()) {
return 1;
}
//For files and category
return 2;
}
});
mScriptFileList.setLayoutManager(manager);
loadScriptList();
}
private void loadScriptList() {
mScriptFiles.clear();
mDirectories.clear();
StorageFileProvider.getDefault().getInitialDirectoryScriptFiles()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SimpleObserver<ScriptFile>() {
@Override
public void onNext(@io.reactivex.annotations.NonNull ScriptFile file) {
if (file.isFile()) {
mScriptFiles.add(file);
} else {
mDirectories.add(file);
}
}
@Override
public void onComplete() {
mScriptListAdapter.notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(false);
}
});
} }
@@ -165,12 +85,7 @@ public class MyScriptListFragment extends Fragment {
private void onScriptFileOperated() { private void onScriptFileOperated() {
mSelectedScriptFile = null; mSelectedScriptFile = null;
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(false);
}
});
} }
@Optional @Optional
@@ -224,123 +139,5 @@ public class MyScriptListFragment extends Fragment {
}); });
} }
private class ScriptListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int VIEW_TYPE_FILE = 0;
private final int VIEW_TYPE_DIRECTORY = 1;
//category是类别也即"文件", "文件夹"那两个
private final int VIEW_TYPE_CATEGORY = 2;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
if (viewType == VIEW_TYPE_FILE) {
return new ScriptFileViewHolder(inflater.inflate(R.layout.script_file_list_file, parent, false));
} else if (viewType == VIEW_TYPE_DIRECTORY) {
return new DirectoryViewHolder(inflater.inflate(R.layout.script_file_list_directory, parent, false));
} else {
return new CategoryViewHolder(inflater.inflate(R.layout.script_file_list_category, parent, false));
}
}
@SuppressWarnings("unchecked")
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
BindableViewHolder bindableViewHolder = (BindableViewHolder) holder;
if (position == 0 || position == mDirectories.size() + 1) {
bindableViewHolder.bind(position == 0, position);
return;
}
if (position <= mDirectories.size()) {
bindableViewHolder.bind(mDirectories.get(position - 1), position);
return;
}
bindableViewHolder.bind(mScriptFiles.get(position - mDirectories.size() - 2), position);
}
@Override
public int getItemViewType(int position) {
if (position == 0 || position == mDirectories.size() + 1) {
return VIEW_TYPE_CATEGORY;
}
if (position <= mDirectories.size()) {
return VIEW_TYPE_DIRECTORY;
}
return VIEW_TYPE_FILE;
}
@Override
public int getItemCount() {
return mScriptFiles.size() + mDirectories.size() + 2;
}
}
static class ScriptFileViewHolder extends BindableViewHolder<ScriptFile> {
private static final DateFormat DATE_FORMAT = SimpleDateFormat.getDateTimeInstance();
@BindView(R.id.name)
TextView mName;
@BindView(R.id.first_char)
TextView mFirstChar;
@BindView(R.id.desc)
TextView mDesc;
GradientDrawable mFirstCharBackground;
public ScriptFileViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
mFirstCharBackground = (GradientDrawable) mFirstChar.getBackground();
}
@Override
public void bind(ScriptFile file, int position) {
mName.setText(file.getSimplifiedName());
mDesc.setText(PFile.getHumanReadableSize(file.length()));
if (file.getType() == ScriptFile.TYPE_JAVA_SCRIPT) {
mFirstChar.setText("J");
//什么?裸写颜色代码?!不影响代码可读性和重构成本的情况下,这样子修改起来方便多啦
mFirstCharBackground.setColor(0xFF99CC99);
} else {
mFirstChar.setText("R");
mFirstCharBackground.setColor(0xFFFD999A);
}
}
}
static class DirectoryViewHolder extends BindableViewHolder<ScriptFile> {
@BindView(R.id.name)
TextView mName;
public DirectoryViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
@Override
public void bind(ScriptFile data, int position) {
mName.setText(data.getSimplifiedName());
}
}
static class CategoryViewHolder extends BindableViewHolder<Boolean> {
@BindView(R.id.title)
TextView mTitle;
public CategoryViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
@Override
public void bind(Boolean isDirCategory, int position) {
mTitle.setText(isDirCategory ? R.string.text_directory : R.string.text_file);
}
}
} }

View File

@@ -0,0 +1,280 @@
package com.stardust.scriptdroid.ui.main.script_list;
import android.content.Context;
import android.graphics.drawable.GradientDrawable;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.stardust.pio.PFile;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.script.ScriptFile;
import com.stardust.scriptdroid.script.Scripts;
import com.stardust.scriptdroid.script.StorageFileProvider;
import com.stardust.scriptdroid.tool.SimpleObserver;
import com.stardust.widget.BindableViewHolder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
/**
* Created by Stardust on 2017/8/21.
*/
public class ScriptListView extends SwipeRefreshLayout implements SwipeRefreshLayout.OnRefreshListener {
public interface OnScriptFileClickListener {
void onScriptFileClick(View view, ScriptFile file);
}
private RecyclerView mScriptListView;
private ScriptListAdapter mScriptListAdapter = new ScriptListAdapter();
private ArrayList<ScriptFile> mScriptFiles = new ArrayList<>();
private ArrayList<ScriptFile> mDirectories = new ArrayList<>();
private ScriptFile mCurrentDirectory;
private OnScriptFileClickListener mOnScriptFileClickListener;
public ScriptListView(Context context) {
super(context);
init();
}
public ScriptListView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public ScriptFile getCurrentDirectory() {
return mCurrentDirectory;
}
public void setCurrentDirectory(ScriptFile currentDirectory) {
mCurrentDirectory = currentDirectory;
loadScriptList();
}
public void setOnScriptFileClickListener(OnScriptFileClickListener onScriptFileClickListener) {
mOnScriptFileClickListener = onScriptFileClickListener;
}
private void init() {
setOnRefreshListener(this);
mScriptListView = new RecyclerView(getContext());
addView(mScriptListView);
initScriptListRecyclerView();
setCurrentDirectory(StorageFileProvider.getDefault().getInitialDirectory());
}
private void initScriptListRecyclerView() {
mScriptListView.setAdapter(mScriptListAdapter);
GridLayoutManager manager = new GridLayoutManager(getContext(), 2);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
//For directories
if (position >= 1 && position <= mDirectories.size()) {
return 1;
}
//For files and category
return 2;
}
});
mScriptListView.setLayoutManager(manager);
}
private void loadScriptList() {
mScriptFiles.clear();
mDirectories.clear();
StorageFileProvider.getDefault().getDirectoryScriptFiles(mCurrentDirectory)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SimpleObserver<ScriptFile>() {
@Override
public void onNext(@io.reactivex.annotations.NonNull ScriptFile file) {
if (file.isFile()) {
mScriptFiles.add(file);
} else {
mDirectories.add(file);
}
}
@Override
public void onComplete() {
mScriptListAdapter.notifyDataSetChanged();
setRefreshing(false);
}
});
}
@Override
public void onRefresh() {
loadScriptList();
}
private class ScriptListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int VIEW_TYPE_FILE = 0;
private final int VIEW_TYPE_DIRECTORY = 1;
//category是类别也即"文件", "文件夹"那两个
private final int VIEW_TYPE_CATEGORY = 2;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
if (viewType == VIEW_TYPE_FILE) {
return new ScriptFileViewHolder(inflater.inflate(R.layout.script_file_list_file, parent, false));
} else if (viewType == VIEW_TYPE_DIRECTORY) {
return new DirectoryViewHolder(inflater.inflate(R.layout.script_file_list_directory, parent, false));
} else {
return new CategoryViewHolder(inflater.inflate(R.layout.script_file_list_category, parent, false));
}
}
@SuppressWarnings("unchecked")
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
BindableViewHolder bindableViewHolder = (BindableViewHolder) holder;
if (position == 0 || position == mDirectories.size() + 1) {
bindableViewHolder.bind(position == 0, position);
return;
}
if (position <= mDirectories.size()) {
bindableViewHolder.bind(mDirectories.get(position - 1), position);
return;
}
bindableViewHolder.bind(mScriptFiles.get(position - mDirectories.size() - 2), position);
}
@Override
public int getItemViewType(int position) {
if (position == 0 || position == mDirectories.size() + 1) {
return VIEW_TYPE_CATEGORY;
}
if (position <= mDirectories.size()) {
return VIEW_TYPE_DIRECTORY;
}
return VIEW_TYPE_FILE;
}
@Override
public int getItemCount() {
return mScriptFiles.size() + mDirectories.size() + 2;
}
}
class ScriptFileViewHolder extends BindableViewHolder<ScriptFile> {
@BindView(R.id.name)
TextView mName;
@BindView(R.id.first_char)
TextView mFirstChar;
@BindView(R.id.desc)
TextView mDesc;
GradientDrawable mFirstCharBackground;
private ScriptFile mScriptFile;
ScriptFileViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
mFirstCharBackground = (GradientDrawable) mFirstChar.getBackground();
}
@Override
public void bind(ScriptFile file, int position) {
mScriptFile = file;
mName.setText(file.getSimplifiedName());
mDesc.setText(PFile.getHumanReadableSize(file.length()));
if (file.getType() == ScriptFile.TYPE_JAVA_SCRIPT) {
mFirstChar.setText("J");
//什么?裸写颜色代码?!不影响代码可读性和重构成本的情况下,这样子修改起来方便多啦
mFirstCharBackground.setColor(0xFF99CC99);
} else {
mFirstChar.setText("R");
mFirstCharBackground.setColor(0xFFFD999A);
}
}
@OnClick(R.id.item)
void onItemClick() {
if(mOnScriptFileClickListener != null){
mOnScriptFileClickListener.onScriptFileClick(itemView, mScriptFile);
}
}
@OnClick(R.id.run)
void run() {
Scripts.run(mScriptFile);
}
@OnClick(R.id.edit)
void edit() {
Scripts.edit(mScriptFile);
}
@OnClick(R.id.more)
void showOptionMenu() {
}
}
class DirectoryViewHolder extends BindableViewHolder<ScriptFile> {
@BindView(R.id.name)
TextView mName;
private ScriptFile mScriptFile;
DirectoryViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
@Override
public void bind(ScriptFile data, int position) {
mName.setText(data.getSimplifiedName());
mScriptFile = data;
}
@OnClick(R.id.item)
void onItemClick() {
setCurrentDirectory(mScriptFile);
}
@OnClick(R.id.more)
void showOptionMenu() {
}
}
class CategoryViewHolder extends BindableViewHolder<Boolean> {
@BindView(R.id.title)
TextView mTitle;
CategoryViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
@Override
public void bind(Boolean isDirCategory, int position) {
mTitle.setText(isDirCategory ? R.string.text_directory : R.string.text_file);
}
}
}

View File

@@ -0,0 +1,86 @@
package com.stardust.widget;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.support.design.widget.AppBarLayout;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.Window;
import com.stardust.util.ViewUtil;
/**
* Created by Stardust on 2017/8/22.
*/
public class AppWithStatusBarLayout extends AppBarLayout {
public AppWithStatusBarLayout(Context context) {
super(context);
}
public AppWithStatusBarLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
if (visibility == VISIBLE) {
setPadding();
}
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setPadding();
}
private void setPadding() {
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
setPadding(getPaddingLeft(), getStatusBarHeight(), getPaddingRight(), getPaddingBottom());
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
}
private int getStatusBarHeight() {
Rect rect = new Rect();
Window window = getWindow();
if (window == null) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources().getDisplayMetrics());
}
window.getDecorView().getWindowVisibleDisplayFrame(rect);
return rect.top;
}
@Nullable
private Window getWindow() {
return getWindowForContext(getContext());
}
@Nullable
private Window getWindowForContext(Context context) {
if (context instanceof Activity) {
return ((Activity) context).getWindow();
}
if (context instanceof ContextWrapper) {
return getWindowForContext(((ContextWrapper) context).getBaseContext());
}
return null;
}
}

View File

@@ -0,0 +1,109 @@
package com.stardust.widget;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import com.stardust.scriptdroid.R;
import org.androidannotations.annotations.ViewById;
/**
* Created by Stardust on 2017/8/22.
*/
public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefreshListener {
private WebView mWebView;
private ProgressBar mProgressBar;
SwipeRefreshLayout mSwipeRefreshLayout;
public EWebView(Context context) {
super(context);
init();
}
public EWebView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
inflate(getContext(), R.layout.ewebview, this);
mWebView = (WebView) findViewById(R.id.web_view);
mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
mSwipeRefreshLayout.setOnRefreshListener(this);
setUpWebView();
}
private void setUpWebView() {
WebSettings settings = mWebView.getSettings();
settings.setUseWideViewPort(true);
settings.setBuiltInZoomControls(true);
settings.setSupportZoom(true);
settings.setLoadWithOverviewMode(true);
settings.setJavaScriptEnabled(true);
mWebView.setWebViewClient(new MyWebViewClient());
mWebView.setWebChromeClient(new MyWebChromeClient());
}
public WebView getWebView() {
return mWebView;
}
@Override
public void onRefresh() {
mWebView.reload();
}
private class MyWebChromeClient extends WebChromeClient {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
mProgressBar.setProgress(newProgress);
}
}
private class MyWebViewClient extends WebViewClient {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
mProgressBar.setProgress(0);
mProgressBar.setVisibility(VISIBLE);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
mProgressBar.setVisibility(GONE);
mSwipeRefreshLayout.setRefreshing(false);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
view.loadUrl(request.getUrl().toString());
return true;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
}

View File

@@ -12,11 +12,10 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout <com.stardust.widget.AppWithStatusBarLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="#5cab7d" android:background="#5cab7d"
android:paddingTop="24px"
android:theme="@style/AppTheme.AppBarOverlay"> android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar <android.support.v7.widget.Toolbar
@@ -34,7 +33,7 @@
app:tabGravity="fill" app:tabGravity="fill"
app:tabIndicatorColor="@android:color/white" app:tabIndicatorColor="@android:color/white"
app:tabMode="scrollable"/> app:tabMode="scrollable"/>
</android.support.design.widget.AppBarLayout> </com.stardust.widget.AppWithStatusBarLayout>
<android.support.v4.view.ViewPager <android.support.v4.view.ViewPager

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="2dp"
android:visibility="gone"/>
</merge>

View File

@@ -1,14 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/swipe_refresh_layout" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="match_parent">
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView <com.stardust.scriptdroid.ui.main.script_list.ScriptListView
android:id="@+id/script_file_list" android:id="@+id/script_file_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
</android.support.v4.widget.SwipeRefreshLayout> </FrameLayout>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<com.stardust.widget.EWebView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/eweb_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffffff"
android:orientation="vertical"
tools:showIn="@layout/activity_edit">
<com.jecelyin.editor.v2.view.EditorView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/editor"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<com.jecelyin.editor.v2.core.widget.JecEditText
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffffff"
android:enabled="true"
android:gravity="start|top"
android:inputType="textMultiLine"
android:padding="5dp"
android:scrollbarThumbVertical="@android:color/transparent"
android:scrollbarTrackVertical="@null"
android:scrollbars="vertical"/>
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:id="@+id/progress_view"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="90dp"
android:indeterminate="true"
android:visibility="gone"/>
<com.stardust.scriptdroid.ui.edit.completion.InputMethodEnhanceBar
android:id="@+id/input_method_enhance_bar"
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_alignParentBottom="true"
android:background="#e7ebec"/>
</com.jecelyin.editor.v2.view.EditorView>
</LinearLayout>

View File

@@ -5,10 +5,10 @@
android:id="@+id/item" android:id="@+id/item"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:clickable="true" android:clickable="true"
android:foreground="?selectableItemBackground" android:foreground="?selectableItemBackground"
android:paddingLeft="6dp"
android:paddingRight="6dp"
app:cardBackgroundColor="#ffffff" app:cardBackgroundColor="#ffffff"
app:cardElevation="1dp" app:cardElevation="1dp"
app:cardUseCompatPadding="true"> app:cardUseCompatPadding="true">
@@ -27,7 +27,7 @@
android:layout_marginLeft="16dp" android:layout_marginLeft="16dp"
android:layout_marginRight="16dp" android:layout_marginRight="16dp"
android:src="@drawable/ic_folder_yellow_100px" android:src="@drawable/ic_folder_yellow_100px"
android:tint="#ffde69"/> android:tint="#ffda93"/>
<TextView <TextView
android:id="@+id/name" android:id="@+id/name"
@@ -44,6 +44,7 @@
<ImageView <ImageView
android:id="@+id/more"
android:layout_width="52dp" android:layout_width="52dp"
android:layout_height="20dp" android:layout_height="20dp"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"

View File

@@ -11,6 +11,7 @@
android:background="#EDEEEF"/> android:background="#EDEEEF"/>
<LinearLayout <LinearLayout
android:id="@+id/item"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@android:color/white" android:background="@android:color/white"
@@ -59,10 +60,9 @@
android:ellipsize="end" android:ellipsize="end"
android:gravity="center_vertical" android:gravity="center_vertical"
android:maxLines="1" android:maxLines="1"
android:text="2017年2月3日11:56"
android:textColor="#9DA0A2" android:textColor="#9DA0A2"
android:textSize="11sp" android:textSize="11sp"
tools:text="正在运行的服务"/> tools:text="18 KB"/>
</LinearLayout> </LinearLayout>
@@ -85,6 +85,7 @@
android:tint="#A9AAAB"/> android:tint="#A9AAAB"/>
<ImageView <ImageView
android:id="@+id/edit"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="1"
@@ -96,6 +97,7 @@
android:tint="#A9AAAB"/> android:tint="#A9AAAB"/>
<ImageView <ImageView
android:id="@+id/more"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="1"

View File

@@ -229,6 +229,10 @@
<string name="text_enable_observe_key">启用按键监听</string> <string name="text_enable_observe_key">启用按键监听</string>
<string name="text_directory">文件夹</string> <string name="text_directory">文件夹</string>
<string name="text_file">文件</string> <string name="text_file">文件</string>
<string name="text_tutorial">教程</string>
<string name="text_script">脚本</string>
<string name="text_community">社区</string>
<string name="text_manage">管理</string>
<string-array name="record_control_keys"> <string-array name="record_control_keys">

View File

@@ -6,6 +6,7 @@ import android.widget.Toast;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/** /**
* Created by Stardust on 2017/2/3. * Created by Stardust on 2017/2/3.
@@ -14,9 +15,15 @@ public interface BackPressedHandler {
boolean onBackPressed(Activity activity); boolean onBackPressed(Activity activity);
interface HostActivity {
Observer getBackPressedObserver();
}
class Observer implements BackPressedHandler { class Observer implements BackPressedHandler {
private List<BackPressedHandler> mBackPressedHandlers = new ArrayList<>(); private CopyOnWriteArrayList<BackPressedHandler> mBackPressedHandlers = new CopyOnWriteArrayList<>();
@Override @Override
public boolean onBackPressed(Activity activity) { public boolean onBackPressed(Activity activity) {
@@ -31,6 +38,10 @@ public interface BackPressedHandler {
public void registerHandler(BackPressedHandler handler) { public void registerHandler(BackPressedHandler handler) {
mBackPressedHandlers.add(handler); mBackPressedHandlers.add(handler);
} }
public void unregisterHandler(BackPressedHandler handler) {
mBackPressedHandlers.remove(handler);
}
} }
@@ -42,7 +53,7 @@ public interface BackPressedHandler {
private String mNotice; private String mNotice;
public DoublePressExit(Activity activity, int noticeResId) { public DoublePressExit(Activity activity, int noticeResId) {
this(activity, activity.getString(noticeResId)); this(activity, activity.getString(noticeResId));
} }
public DoublePressExit(Activity activity, String notice) { public DoublePressExit(Activity activity, String notice) {